source: rtems/cpukit/posix/src/psignalunblockthread.c @ c838e2f4

4.11
Last change on this file since c838e2f4 was c838e2f4, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 28, 2010 at 8:39:48 PM

2010-07-28 Vinu Rajashekhar <vinutheraj@…>

  • posix/src/condinit.c, posix/src/condwaitsupp.c, posix/src/psignalunblockthread.c: Clean up some signal interruption code.
  • Property mode set to 100644
File size: 3.1 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2007.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 *  $Id$
10 */
11
12#if HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include <errno.h>
17#include <pthread.h>
18#include <signal.h>
19
20#include <rtems/system.h>
21#include <rtems/score/isr.h>
22#include <rtems/score/thread.h>
23#include <rtems/score/tqdata.h>
24#include <rtems/score/wkspace.h>
25#include <rtems/seterr.h>
26#include <rtems/posix/threadsup.h>
27#include <rtems/posix/psignal.h>
28#include <rtems/posix/pthread.h>
29#include <rtems/posix/time.h>
30#include <stdio.h>
31
32
33/*PAGE
34 *
35 *  _POSIX_signals_Unblock_thread
36 */
37
38/* XXX this routine could probably be cleaned up */
39bool _POSIX_signals_Unblock_thread(
40  Thread_Control  *the_thread,
41  int              signo,
42  siginfo_t       *info
43)
44{
45  POSIX_API_Control  *api;
46  sigset_t            mask;
47  siginfo_t          *the_info = NULL;
48
49  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
50
51  mask = signo_to_mask( signo );
52
53  /*
54   *  Is the thread is specifically waiting for a signal?
55   */
56
57  if ( _States_Is_interruptible_signal( the_thread->current_state ) ) {
58
59    if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) {
60      the_thread->Wait.return_code = EINTR;
61
62      the_info = (siginfo_t *) the_thread->Wait.return_argument;
63
64      if ( !info ) {
65        the_info->si_signo = signo;
66        the_info->si_code = SI_USER;
67        the_info->si_value.sival_int = 0;
68      } else {
69        *the_info = *info;
70      }
71
72      _Thread_queue_Extract_with_proxy( the_thread );
73      return true;
74    }
75
76    /*
77     *  This should only be reached via pthread_kill().
78     */
79
80    return false;
81  }
82
83  /*
84   *  Thread is not waiting due to a sigwait.
85   */
86  if ( ~api->signals_blocked & mask ) {
87
88    /*
89     *  The thread is interested in this signal.  We are going
90     *  to post it.  We have a few broad cases:
91     *    + If it is blocked on an interruptible signal, THEN
92     *        we unblock the thread.
93     *    + If it is in the ready state AND
94     *      we are sending from an ISR AND
95     *      it is the interrupted thread AND
96     *      it is not blocked, THEN
97     *        we need to dispatch at the end of this ISR.
98     *    + Any other combination, do nothing.
99     */
100
101    if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
102      the_thread->Wait.return_code = EINTR;
103      /*
104       *  In pthread_cond_wait, a thread will be blocking on a thread
105       *  queue, but is also interruptible by a POSIX signal.
106       */
107        if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) )
108          _Thread_queue_Extract_with_proxy( the_thread );
109        else if ( _States_Is_delaying(the_thread->current_state) ){
110            if ( _Watchdog_Is_active( &the_thread->Timer ) )
111              (void) _Watchdog_Remove( &the_thread->Timer );
112            _Thread_Unblock( the_thread );
113          }
114
115    } else if ( the_thread->current_state == STATES_READY ) {
116      if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
117        _Context_Switch_necessary = true;
118    }
119  }
120  return false;
121}
Note: See TracBrowser for help on using the repository browser.