source: rtems/cpukit/posix/src/sigtimedwait.c @ 0a752f4e

4.115
Last change on this file since 0a752f4e was 0a752f4e, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/10/11 at 03:56:16

2011-12-10 Ralf Corsépius <ralf.corsepius@…>

  • posix/src/sigtimedwait.c: Make _POSIX_signals_Get_lowest static.
  • Property mode set to 100644
File size: 4.1 KB
RevLine 
[07d880f4]1/*
2 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
3 *
[6a0898b]4 *  COPYRIGHT (c) 1989-2008.
[07d880f4]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
[8e36f29]9 *  http://www.rtems.com/license/LICENSE.
[07d880f4]10 *
11 *  $Id$
12 */
13
[f42b726]14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
[07d880f4]17
18#include <pthread.h>
19#include <signal.h>
20#include <errno.h>
21
22#include <rtems/system.h>
23#include <rtems/posix/pthread.h>
24#include <rtems/posix/psignal.h>
[188c82b]25#include <rtems/seterr.h>
[07d880f4]26#include <rtems/posix/time.h>
[df49c60]27#include <rtems/score/isr.h>
[07d880f4]28
[0a752f4e]29static int _POSIX_signals_Get_lowest(
[07d880f4]30  sigset_t   set
31)
32{
33  int signo;
34
35  for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
[ecdbb42]36    if ( set & signo_to_mask( signo ) ) {
37      goto found_it;
38    }
[07d880f4]39  }
40
[ecdbb42]41  /*
42   *  We assume SIGHUP == 1 and is the first non-real-time signal.
43   */
[07d880f4]44
[ecdbb42]45  #if (SIGHUP != 1)
46    #error "Assumption that SIGHUP==1 violated!!"
47  #endif
[07d880f4]48  for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
[ecdbb42]49    if ( set & signo_to_mask( signo ) ) {
50      goto found_it;
51    }
[07d880f4]52  }
53
[ecdbb42]54  /*
55   *  This is structured this way to eliminate the need to have
56   *  a return 0.  This routine will NOT be called unless a signal
57   *  is pending in the set passed in.
58   */
59found_it:
60  return signo;
[07d880f4]61}
62
63int sigtimedwait(
64  const sigset_t         *set,
65  siginfo_t              *info,
66  const struct timespec  *timeout
67)
68{
69  Thread_Control    *the_thread;
70  POSIX_API_Control *api;
71  Watchdog_Interval  interval;
72  siginfo_t          signal_information;
73  siginfo_t         *the_info;
74  int                signo;
[df49c60]75  ISR_Level          level;
[874297f3]76
[df49c60]77  /*
78   *  Error check parameters before disabling interrupts.
[ecdbb42]79   */
80  if ( !set )
81    rtems_set_errno_and_return_minus_one( EINVAL );
[1de949a8]82
[ecdbb42]83  /*  NOTE: This is very specifically a RELATIVE not ABSOLUTE time
[6a0898b]84   *        in the Open Group specification.
[df49c60]85   */
86
87  interval = 0;
88  if ( timeout ) {
89
[6a0898b]90    if ( !_Timespec_Is_valid( timeout ) )
[e180a77e]91      rtems_set_errno_and_return_minus_one( EINVAL );
[df49c60]92
[412dbff6]93    interval = _Timespec_To_ticks( timeout );
[6a0898b]94
95    if ( !interval )
96      rtems_set_errno_and_return_minus_one( EINVAL );
[df49c60]97  }
98
99  /*
100   *  Initialize local variables.
101   */
102
[07d880f4]103  the_info = ( info ) ? info : &signal_information;
104
105  the_thread = _Thread_Executing;
106
107  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
108
109  /*
110   *  What if they are already pending?
111   */
112
113  /* API signals pending? */
114
[df49c60]115  _ISR_Disable( level );
[07d880f4]116  if ( *set & api->signals_pending ) {
117    /* XXX real info later */
[1102485c]118    the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending );
[412dbff6]119    _POSIX_signals_Clear_signals(
120      api,
121      the_info->si_signo,
122      the_info,
[f8437c8]123      false,
124      false
[412dbff6]125    );
[df49c60]126    _ISR_Enable( level );
127
[07d880f4]128    the_info->si_code = SI_USER;
129    the_info->si_value.sival_int = 0;
130    return the_info->si_signo;
131  }
132
133  /* Process pending signals? */
134
[4fa5eae]135  if ( *set & _POSIX_signals_Pending ) {
[1102485c]136    signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending );
[f8437c8]137    _POSIX_signals_Clear_signals( api, signo, the_info, true, false );
[df49c60]138    _ISR_Enable( level );
[07d880f4]139
[4fa5eae]140    the_info->si_signo = signo;
141    the_info->si_code = SI_USER;
142    the_info->si_value.sival_int = 0;
143    return signo;
[07d880f4]144  }
145
146  the_info->si_signo = -1;
147
148  _Thread_Disable_dispatch();
149    the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
150    the_thread->Wait.return_code     = EINTR;
151    the_thread->Wait.option          = *set;
[e7bd66a7]152    the_thread->Wait.return_argument = the_info;
[874297f3]153    _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
[df49c60]154    _ISR_Enable( level );
[874297f3]155    _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
[07d880f4]156  _Thread_Enable_dispatch();
157
[aee3d68]158  /*
159   * When the thread is set free by a signal, it is need to eliminate
160   * the signal.
161   */
162
[f8437c8]163  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false );
[1102485c]164
165  /* Set errno only if return code is not EINTR or
166   * if EINTR was caused by a signal being caught, which
167   * was not in our set.
168   */
169
170  if ( (_Thread_Executing->Wait.return_code != EINTR)
171       || !(*set & signo_to_mask( the_info->si_signo )) ) {
172    errno = _Thread_Executing->Wait.return_code;
173    return -1;
174  }
175
[07d880f4]176  return the_info->si_signo;
177}
Note: See TracBrowser for help on using the repository browser.