Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Signal Handler Tour

Sending Thread

Posting Signals

These are the actions that run on the thread that posts the signal
Signals are initiated in these ways:

  1. signal/sig_kill.c: nxsig_kill(). The standard function kill() is a simple wrapper around nxsig_kill(). nxsig_kill() can be used to send a signal to any task group. It simply sets up the call to nxsig_dispatch().
  2. signal/sig_queue.c: nxsig_queue(). The standard function sigqueue() is a simple wrapper around nxsig_queue(). nxsig_kill() can be used to send a signal to any task group, passing more information than is possible with kill(). It again simply sets up the call to nxsig_dispatch().
  3. signal/sig_notification.c: nxsig_notification(). This logic can also generate signals via a call to nxsig_dispatch(). But this is part of the internal, NuttX signal notification system. It sends signals to tasks via the work queue.

signal/sig_dispatch.c: nxsig_dispatch()

Code Block
  int nxsig_dispatch(pid_t pid, FAR siginfo_t *info)

...

  1. Get the TCB associated with the pid.
  2. Call nxsig_tcbdispatch() with the TCB

group/group_signal.c: group_signal()

Code Block
  int group_signal(FAR struct task_group_s *group, FAR siginfo_t *siginfo)

Send a signal to the appropriate member(s) of the group. This is typically called from nxsig_dispatch() as described above but may also be called from task/task_exithook.c to handle Death-of-Child (SIGCHLD) signals.

group/group_signal.c: group_signal_handler()

Code Block
  static int group_signal_handler(pid_t pid, FAR void *arg)

Callback from group_foreachchild() that handles one member of the group.

signal/sig_dispatch.c: nxsig_tcbdispatch():

Code Block
  int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)

...

For unmasked signals that have a signal handler attached, nxsig_tcbdispatch() will call the architecture-specific interface, up_schedule_sigaction().

arch/xxx/src/xxx/up_schedsigaction.c: up_schedule_sigaction()

Code Block
  void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)

...

There are other special cases when the signal is generated from interrupt handler or when the a task signals itself for some reason. Those variations are not addressed here.

Receiving Thread

signal/sig_deliver.c: nxsig_deliver()

Code Block
  void nxsig_deliver(FAR struct tcb_s *stcb)

...

Otherwise, the signal handler is called directly from nxsig_deliver(). When the signal handler returns, the action is over and there is only clean up to be done.

arch/xxx/src/xxx/up_sigdeliver.c: up_sigdeliver()

Code Block
  void up_sigdeliver(void)

...