Пример #1
0
int sig_dispatch(pid_t pid, FAR siginfo_t *info)
{
#ifdef HAVE_GROUP_MEMBERS

  FAR struct tcb_s *stcb;
  FAR struct task_group_s *group;

  /* Get the TCB associated with the pid */

  stcb = sched_gettcb(pid);
  if (stcb)
    {
      /* The task/thread associated with this PID is still active.  Get its
       * task group.
       */

      group = stcb->group;
    }
  else
    {
      /* The task/thread associated with this PID has exited.  In the normal
       * usage model, the PID should correspond to the PID of the task that
       * created the task group.  Try looking it up.
       */

      group = group_findbypid(pid);
    }

  /* Did we locate the group? */

  if (group)
    {
      /* Yes.. call group_signal() to send the signal to the correct group
       * member.
       */

      return group_signal(group, info);
    }
  else
    {
      return -ESRCH;
    }

#else

  FAR struct tcb_s *stcb;

  /* Get the TCB associated with the pid */

  stcb = sched_gettcb(pid);
  if (!stcb)
    {
      return -ESRCH;
    }

  return sig_tcbdispatch(stcb, info);

#endif
}
Пример #2
0
static inline void task_sigchild(gid_t pgid, FAR struct tcb_s *ctcb, int status)
{
  FAR struct task_group_s *chgrp = ctcb->group;
  FAR struct task_group_s *pgrp;
  siginfo_t info;

  DEBUGASSERT(chgrp);

  /* Get the parent task group.  It is possible that all of the members of
   * the parent task group have exited.  This would not be an error.  In
   * this case, the child task group has been orphaned.
   */

  pgrp = group_findbygid(pgid);
  if (!pgrp)
    {
      /* Set the task group ID to an invalid group ID.  The dead parent
       * task group ID could get reused some time in the future.
       */

      chgrp->tg_pgid = INVALID_GROUP_ID;
      return;
    }

  /* Save the exit status now if this is the main thread of the task group
   * that is exiting. Only the exiting main task of a task group carries
   * interpretable exit  Check if this is the main task that is exiting.
   */

#ifndef CONFIG_DISABLE_PTHREAD
  if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
#endif
    {
      task_exitstatus(pgrp, status);
    }

  /* But only the final exiting thread in a task group, whatever it is,
   * should generate SIGCHLD.
   */

  if (chgrp->tg_nmembers == 1)
    {
      /* Mark that all of the threads in the task group have exited */

      task_groupexit(pgrp);

      /* Create the siginfo structure.  We don't actually know the cause.
       * That is a bug. Let's just say that the child task just exited
       * for now.
       */

      info.si_signo           = SIGCHLD;
      info.si_code            = CLD_EXITED;
      info.si_errno           = OK;
      info.si_value.sival_ptr = NULL;
#ifndef CONFIG_DISABLE_PTHREAD
      info.si_pid             = chgrp->tg_task;
#else
      info.si_pid             = ctcb->pid;
#endif
      info.si_status          = status;

      /* Send the signal to one thread in the group */

      (void)group_signal(pgrp, &info);
    }
}