Ejemplo n.º 1
0
void sig_unmaskpendingsignal(void)
{
   FAR _TCB       *rtcb = (FAR _TCB*)g_readytorun.head;
   sigset_t        unmaskedset;
   FAR sigpendq_t *pendingsig;
   int             signo;

   /* Prohibit any context switches until we are done with this.
    * We may still be performing signal operations from interrupt
    * handlers, however, none of the pending signals that we
    * are concerned with here should be effected.
    */

   sched_lock();

   /* Get the set of pending signals that were just unmasked.  The
    * following operation should be safe because the sigprocmask
    * can only be changed on this thread of execution.
    */

   unmaskedset = ~(rtcb->sigprocmask) & sig_pendingset(rtcb);

   /* Loop while there are unmasked pending signals to be processed. */

   while (unmaskedset != NULL_SIGNAL_SET)
    {
      /* Pending signals will be processed from lowest numbered signal
       * to highest
       */

      signo = sig_lowest(&unmaskedset);
      if (signo != ERROR)
        {
          /* Remove the signal from the set of unmasked signals.  NOTE:
           * this implicitly assumes that only one instance for a given
           * signal number is pending.
           */

          sigdelset(&unmaskedset, signo);

          /* Remove the pending signal from the list of pending signals */

          if ((pendingsig = sig_removependingsignal(rtcb, signo)) != NULL)
            {
              /* If there is one, then process it like a normal signal */

              sig_received(rtcb, &pendingsig->info);

              /* Then remove it from the pending signal list */

              sig_releasependingsignal(pendingsig);
            }
        }
    }

  sched_unlock();
}
Ejemplo n.º 2
0
static inline void task_sigchild(FAR _TCB *ptcb, FAR _TCB *ctcb, int status)
{
  siginfo_t info;

  /* If task groups are not supported then we will report SIGCHLD when the
   * task exits.  Unfortunately, there could still be threads in the group
   * that are still running.
   */

  if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK)
    {
#ifdef CONFIG_SCHED_CHILD_STATUS
      /* Save the exit status now of the main thread */

      task_exitstatus(ptcb->group, status);

#else /* CONFIG_SCHED_CHILD_STATUS */

      /* Decrement the number of children from this parent */

      DEBUGASSERT(ptcb->nchildren > 0);
      ptcb->nchildren--;

#endif /* CONFIG_SCHED_CHILD_STATUS */

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

      info.si_signo           = SIGCHLD;
      info.si_code            = CLD_EXITED;
      info.si_value.sival_ptr = NULL;
      info.si_pid             = ctcb->pid;
      info.si_status          = status;

      /* Send the signal.  We need to use this internal interface so that we
       * can provide the correct si_code value with the signal.
       */

      (void)sig_received(ptcb, &info);
    }
}
Ejemplo n.º 3
0
int sig_mqnotempty (int pid, int signo, void *sival_ptr)
#endif
{
  FAR _TCB *stcb;
  siginfo_t info;
  int       ret = ERROR;

  sched_lock();

  /* Get the TCB of the receiving task */

  stcb = sched_gettcb(pid);

#ifdef CONFIG_CAN_PASS_STRUCTS
  sdbg("TCB=%p signo=%d value=%d\n", stcb, signo, value.sival_int);
#else
  sdbg("TCB=%p signo=%d sival_ptr=%p\n", stcb, signo, sival_ptr);
#endif

  /* Create the siginfo structure */

  info.si_signo           = signo;
  info.si_code            = SI_MESGQ;
#ifdef CONFIG_CAN_PASS_STRUCTS
  info.si_value           = value;
#else
  info.si_value.sival_ptr = sival_ptr;
#endif

  /* Verify that we can perform the signalling operation */

  if ((stcb) && (GOOD_SIGNO(signo)))
   {
     /* Process the receipt of the signal */
     ret = sig_received(stcb, &info);
   }

  sched_unlock();
  return ret;
}
Ejemplo n.º 4
0
static inline void task_sigchild(FAR _TCB *tcb, int status)
{
  FAR _TCB *ptcb;
  siginfo_t info;

  /* Only exiting tasks should generate SIGCHLD. pthreads use other
   * mechansims.
   */

  if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK)
    {
      /* Keep things stationary through the following */

      sched_lock();

      /* Get the TCB of the receiving task */

      ptcb = sched_gettcb(tcb->parent);
      if (!ptcb)
        {
          /* The parent no longer exists... bail */

          sched_unlock();
          return;
        }

#ifdef CONFIG_SCHED_CHILD_STATUS
      /* Check if the parent task has suppressed retention of child exit
       * status information.  Only 'tasks' report exit status, not pthreads.
       * pthreads have a different mechanism.
       */

      if ((ptcb->flags & TCB_FLAG_NOCLDWAIT) == 0)
        {
          FAR struct child_status_s *child;

          /* No.. Find the exit status entry for this task in the parent TCB */

          child = task_findchild(ptcb, getpid());
          DEBUGASSERT(child);
          if (child)
            {
              /* Mark that the child has exit'ed */

              child->ch_flags |= CHILD_FLAG_EXITED;

              /* Save the exit status */

              child->ch_status = status;
            }
        }
#else
      /* Decrement the number of children from this parent */

      DEBUGASSERT(ptcb->nchildren > 0);
      ptcb->nchildren--;
#endif

      /* Set the parent to an impossible PID.  We do this because under
       * certain conditions, task_exithook() can be called multiple times.
       * If this function is called again, sched_gettcb() will fail on the
       * invalid parent PID above, nchildren will be decremented once and
       * all will be well.
       */

      tcb->parent = INVALID_PROCESS_ID;

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

      info.si_signo           = SIGCHLD;
      info.si_code            = CLD_EXITED;
      info.si_value.sival_ptr = NULL;
      info.si_pid             = tcb->pid;
      info.si_status          = status;

      /* Send the signal.  We need to use this internal interface so that we
       * can provide the correct si_code value with the signal.
       */

      (void)sig_received(ptcb, &info);
      sched_unlock();
    }
}