summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/prwlocktimedwrlock.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-07-18 18:45:56 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-07-18 18:45:56 +0000
commit6a0898bba30ccd936e0ac1d6268970316efe92c4 (patch)
tree364d967bdfcdb75695666e37263cb2f0bed3a077 /cpukit/posix/src/prwlocktimedwrlock.c
parentChanged special purpose register inline functions to macros. (diff)
downloadrtems-6a0898bba30ccd936e0ac1d6268970316efe92c4.tar.bz2
2008-07-18 Joel Sherrill <joel.sherrill@oarcorp.com>
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
Diffstat (limited to 'cpukit/posix/src/prwlocktimedwrlock.c')
-rw-r--r--cpukit/posix/src/prwlocktimedwrlock.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/cpukit/posix/src/prwlocktimedwrlock.c b/cpukit/posix/src/prwlocktimedwrlock.c
index adf45b77fc..a826df8371 100644
--- a/cpukit/posix/src/prwlocktimedwrlock.c
+++ b/cpukit/posix/src/prwlocktimedwrlock.c
@@ -1,7 +1,7 @@
/*
* POSIX RWLock Manager -- Attempt to Obtain a Write Lock on a RWLock Instance
*
- * COPYRIGHT (c) 1989-2007.
+ * COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -40,17 +40,35 @@ int pthread_rwlock_timedwrlock(
const struct timespec *abstime
)
{
- POSIX_RWLock_Control *the_rwlock;
- Objects_Locations location;
- int status;
- Watchdog_Interval ticks;
-
+ POSIX_RWLock_Control *the_rwlock;
+ Objects_Locations location;
+ Watchdog_Interval ticks;
+ boolean do_wait;
+ POSIX_Absolute_timeout_conversion_results_t status;
+
if ( !rwlock )
return EINVAL;
+ /*
+ * 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.
+ */
status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks );
- if ( status )
- return status;
+ switch (status) {
+ 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;
+ }
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
@@ -60,12 +78,25 @@ int pthread_rwlock_timedwrlock(
_CORE_RWLock_Obtain_for_writing(
&the_rwlock->RWLock,
*rwlock,
- TRUE, // we are willing to wait up to ticks
+ do_wait,
ticks,
NULL
);
_Thread_Enable_dispatch();
+ if ( !do_wait &&
+ (_Thread_Executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE) ) {
+ switch (status) {
+ case POSIX_ABSOLUTE_TIMEOUT_INVALID:
+ return EINVAL;
+ case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
+ case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
+ return ETIMEDOUT;
+ case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
+ break;
+ }
+ }
+
return _POSIX_RWLock_Translate_core_RWLock_return_code(
(CORE_RWLock_Status) _Thread_Executing->Wait.return_code
);