summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/condtimedwait.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2008-07-24 20:43:24 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2008-07-24 20:43:24 +0000
commitd17c1140a84559e1fbfb082def45fbdcb487e85f (patch)
treefd05fdac29f39ae2041acd6bdc49e93a54d531d9 /cpukit/posix/src/condtimedwait.c
parent2008-07-15 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-d17c1140a84559e1fbfb082def45fbdcb487e85f.tar.bz2
2008-07-24 Joel Sherrill <joel.sherrill@OARcorp.com>
PR 1291/cpukit * posix/src/posixtimespecabsolutetimeout.c: New file. * itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, posix/Makefile.am, 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/mutexfromcorestatus.c, posix/src/mutextimedlock.c, posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, posix/src/semtrywait.c, posix/src/semwait.c, rtems/src/semobtain.c, rtems/src/semtranslatereturncode.c, score/include/rtems/score/coresem.h, score/src/coremsgseize.c, 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/condtimedwait.c')
-rw-r--r--cpukit/posix/src/condtimedwait.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/cpukit/posix/src/condtimedwait.c b/cpukit/posix/src/condtimedwait.c
index 32ce1d4a05..204dae858c 100644
--- a/cpukit/posix/src/condtimedwait.c
+++ b/cpukit/posix/src/condtimedwait.c
@@ -28,34 +28,34 @@ int pthread_cond_timedwait(
const struct timespec *abstime
)
{
- Watchdog_Interval timeout;
- struct timespec current_time;
- struct timespec difference;
- boolean already_timedout = FALSE;
-
- if ( !abstime )
- return EINVAL;
+ Watchdog_Interval ticks;
+ boolean already_timedout;
/*
- * The abstime is a walltime. We turn it into an interval.
+ * 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.
*/
-
- (void) clock_gettime( CLOCK_REALTIME, &current_time );
-
- /* XXX probably some error checking should go here */
-
- _POSIX_Timespec_subtract( &current_time, abstime, &difference );
-
- if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&
- ( difference.tv_nsec < 0 ) ) )
- already_timedout = TRUE;
-
- timeout = _POSIX_Timespec_to_interval( &difference );
+ switch ( _POSIX_Absolute_timeout_to_ticks(abstime, &ticks) ) {
+ case POSIX_ABSOLUTE_TIMEOUT_INVALID:
+ return EINVAL;
+ case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
+ case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
+ already_timedout = TRUE;
+ break;
+ case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
+ already_timedout = FALSE;
+ break;
+ }
return _POSIX_Condition_variables_Wait_support(
cond,
mutex,
- timeout,
+ ticks,
already_timedout
);
}