From 6a0898bba30ccd936e0ac1d6268970316efe92c4 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 18 Jul 2008 18:45:56 +0000 Subject: 2008-07-18 Joel Sherrill PR 1291/cpukit * itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, posix/include/mqueue.h, posix/include/rtems/posix/mqueue.h, posix/include/rtems/posix/semaphore.h, posix/include/rtems/posix/time.h, posix/src/condtimedwait.c, posix/src/mqueuereceive.c, posix/src/mqueuerecvsupp.c, posix/src/mqueuesend.c, posix/src/mqueuesendsupp.c, posix/src/mqueuetimedreceive.c, posix/src/mqueuetimedsend.c, posix/src/mutextimedlock.c, posix/src/mutextranslatereturncode.c, posix/src/posixtimespecabsolutetimeout.c, posix/src/prwlocktimedrdlock.c, posix/src/prwlocktimedwrlock.c, posix/src/semaphoretranslatereturncode.c, posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, posix/src/semtrywait.c, posix/src/semwait.c, posix/src/sigtimedwait.c, posix/src/timersettime.c, posix/src/ualarm.c, rtems/src/semobtain.c, rtems/src/semtranslatereturncode.c, score/include/rtems/score/coremutex.h, score/include/rtems/score/coresem.h, score/src/coresemseize.c: This patch addresses issues on implementation of the timeout on the following POSIX services. Some of these services incorrectly took a timeout as a relative time. Others would compute a 0 delta to timeout if the absolute time and the current time were equal and thus incorrectly block the caller forever. The root of the confusion is that POSIX specifies that if the timeout is incorrect (e.g. in the past, is now, or is numerically invalid), that it does not matter if the call would succeed without blocking. This is in contrast to RTEMS programming style where all errors are checked before any critical sections are entered. This fix implemented a more uniform way of handling POSIX absolute time timeouts. + pthread_cond_timedwait - could block forever + mq_timedreceive - used relative not absolute time + mq_timedsend - used relative not absolute time + pthread_mutex_timedlock - used relative not absolute time + pthread_rwlock_timedrdlock- used relative not absolute time + pthread_rwlock_timedwrlock- used relative not absolute time + sem_timedwait - could block forever --- cpukit/posix/src/mqueuetimedreceive.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'cpukit/posix/src/mqueuetimedreceive.c') diff --git a/cpukit/posix/src/mqueuetimedreceive.c b/cpukit/posix/src/mqueuetimedreceive.c index 493ac7aa66..4a16328c79 100644 --- a/cpukit/posix/src/mqueuetimedreceive.c +++ b/cpukit/posix/src/mqueuetimedreceive.c @@ -13,7 +13,7 @@ */ /* - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -53,14 +53,38 @@ ssize_t mq_timedreceive( char *msg_ptr, size_t msg_len, unsigned int *msg_prio, - const struct timespec *timeout + const struct timespec *abstime ) { + Watchdog_Interval ticks; + boolean do_wait; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + */ + switch ( _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ) ) { + case POSIX_ABSOLUTE_TIMEOUT_INVALID: + case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST: + case POSIX_ABSOLUTE_TIMEOUT_IS_NOW: + do_wait = FALSE; + break; + case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE: + do_wait = TRUE; + break; + } + return _POSIX_Message_queue_Receive_support( mqdes, msg_ptr, msg_len, msg_prio, - _Timespec_To_ticks( timeout ) + do_wait, + ticks ); } -- cgit v1.2.3