diff options
Diffstat (limited to 'cpukit/posix/src/sigtimedwait.c')
-rw-r--r-- | cpukit/posix/src/sigtimedwait.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c index b3b2de247d..276b9b61af 100644 --- a/cpukit/posix/src/sigtimedwait.c +++ b/cpukit/posix/src/sigtimedwait.c @@ -21,6 +21,7 @@ #include <rtems/posix/psignal.h> #include <rtems/posix/seterr.h> #include <rtems/posix/time.h> +#include <rtems/score/isr.h> int _POSIX_signals_Get_highest( sigset_t set @@ -55,7 +56,27 @@ int sigtimedwait( siginfo_t signal_information; siginfo_t *the_info; int signo; + ISR_Level level; + /* + * Error check parameters before disabling interrupts. + */ + + interval = 0; + if ( timeout ) { + + if ( timeout->tv_nsec < 0 || + timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND) { + set_errno_and_return_minus_one( EINVAL ); + } + + interval = _POSIX_Timespec_to_interval( timeout ); + } + + /* + * Initialize local variables. + */ + the_info = ( info ) ? info : &signal_information; the_thread = _Thread_Executing; @@ -68,11 +89,13 @@ int sigtimedwait( /* API signals pending? */ + _ISR_Disable( level ); if ( *set & api->signals_pending ) { /* XXX real info later */ the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending ); - _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, - FALSE, FALSE ); + _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, FALSE, FALSE ); + _ISR_Enable( level ); + the_info->si_code = SI_USER; the_info->si_value.sival_int = 0; return the_info->si_signo; @@ -83,6 +106,7 @@ int sigtimedwait( if ( *set & _POSIX_signals_Pending ) { signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending ); _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE ); + _ISR_Enable( level ); the_info->si_signo = signo; the_info->si_code = SI_USER; @@ -90,15 +114,6 @@ int sigtimedwait( return signo; } - interval = 0; - if ( timeout ) { - - if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND) - set_errno_and_return_minus_one( EINVAL ); - - interval = _POSIX_Timespec_to_interval( timeout ); - } - the_info->si_signo = -1; _Thread_Disable_dispatch(); @@ -107,6 +122,7 @@ int sigtimedwait( the_thread->Wait.option = *set; the_thread->Wait.return_argument = (void *) the_info; _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue ); + _ISR_Enable( level ); _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval ); _Thread_Enable_dispatch(); @@ -115,9 +131,7 @@ int sigtimedwait( * the signal. */ - _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, - FALSE, FALSE ); - + _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, FALSE, FALSE ); errno = _Thread_Executing->Wait.return_code; return the_info->si_signo; } |