source: rtems/cpukit/posix/src/sigtimedwait.c @ 188c82b

4.104.114.84.95
Last change on this file since 188c82b was 188c82b, checked in by Joel Sherrill <joel.sherrill@…>, on 08/30/00 at 17:12:55

2000-08-30 Joel Sherrill <joel@…>

  • Many files: Moved posix/include/rtems/posix/seterr.h to score/include/rtems/seterr.h so it would be available within all APIs.
  • Property mode set to 100644
File size: 3.3 KB
Line 
1/*
2 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.OARcorp.com/rtems/license.html.
10 *
11 *  $Id$
12 */
13
14
15#include <pthread.h>
16#include <signal.h>
17#include <errno.h>
18
19#include <rtems/system.h>
20#include <rtems/posix/pthread.h>
21#include <rtems/posix/psignal.h>
22#include <rtems/seterr.h>
23#include <rtems/posix/time.h>
24#include <rtems/score/isr.h>
25
26int _POSIX_signals_Get_highest(
27  sigset_t   set
28)
29{
30  int signo;
31
32  for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
33    if ( set & signo_to_mask( signo ) )
34      return signo;
35  }
36
37/* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */
38
39  for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
40    if ( set & signo_to_mask( signo ) )
41      return signo;
42  }
43
44  return 0;
45}
46
47int sigtimedwait(
48  const sigset_t         *set,
49  siginfo_t              *info,
50  const struct timespec  *timeout
51)
52{
53  Thread_Control    *the_thread;
54  POSIX_API_Control *api;
55  Watchdog_Interval  interval;
56  siginfo_t          signal_information;
57  siginfo_t         *the_info;
58  int                signo;
59  ISR_Level          level;
60 
61  /*
62   *  Error check parameters before disabling interrupts.
63   */
64
65  interval = 0;
66  if ( timeout ) {
67
68    if ( timeout->tv_nsec < 0 ||
69         timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND) {
70      set_errno_and_return_minus_one( EINVAL );
71    }
72
73    interval = _POSIX_Timespec_to_interval( timeout );
74  }
75
76  /*
77   *  Initialize local variables.
78   */
79
80  the_info = ( info ) ? info : &signal_information;
81
82  the_thread = _Thread_Executing;
83
84  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
85
86  /*
87   *  What if they are already pending?
88   */
89
90  /* API signals pending? */
91
92  _ISR_Disable( level );
93  if ( *set & api->signals_pending ) {
94    /* XXX real info later */
95    the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
96    _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, FALSE, FALSE );
97    _ISR_Enable( level );
98
99    the_info->si_code = SI_USER;
100    the_info->si_value.sival_int = 0;
101    return the_info->si_signo;
102  }
103
104  /* Process pending signals? */
105
106  if ( *set & _POSIX_signals_Pending ) {
107    signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
108    _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE );
109    _ISR_Enable( level );
110
111    the_info->si_signo = signo;
112    the_info->si_code = SI_USER;
113    the_info->si_value.sival_int = 0;
114    return signo;
115  }
116
117  the_info->si_signo = -1;
118
119  _Thread_Disable_dispatch();
120    the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
121    the_thread->Wait.return_code     = EINTR;
122    the_thread->Wait.option          = *set;
123    the_thread->Wait.return_argument = (void *) the_info;
124    _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
125    _ISR_Enable( level );
126    _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
127  _Thread_Enable_dispatch();
128
129  /*
130   * When the thread is set free by a signal, it is need to eliminate
131   * the signal.
132   */
133
134  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, FALSE, FALSE );
135  errno = _Thread_Executing->Wait.return_code;
136  return the_info->si_signo;
137}
Note: See TracBrowser for help on using the repository browser.