From de47eb59bb829423b1d0f47ba13099073999b3cb Mon Sep 17 00:00:00 2001 From: Nicolas Planel Date: Wed, 29 Oct 2003 16:07:11 +0000 Subject: Corporate Server 2.1.1 release --- .../dietlibc/libpthread/pthread_cond_timedwait.c | 51 +++++++++++++++++----- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'mdk-stage1/dietlibc/libpthread/pthread_cond_timedwait.c') diff --git a/mdk-stage1/dietlibc/libpthread/pthread_cond_timedwait.c b/mdk-stage1/dietlibc/libpthread/pthread_cond_timedwait.c index 6613f2ca9..71d80bdb5 100644 --- a/mdk-stage1/dietlibc/libpthread/pthread_cond_timedwait.c +++ b/mdk-stage1/dietlibc/libpthread/pthread_cond_timedwait.c @@ -9,13 +9,14 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, { _pthread_descr tmp; _pthread_descr this; - int ret; + int ret=0; __THREAD_INIT(); this=__thread_self(); /* put in wait-chain */ + __NO_ASYNC_CANCEL_BEGIN; __pthread_lock(&(cond->lock)); this->waiting=1; if (cond->wait_chain) { @@ -23,21 +24,51 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, tmp->waitnext=this; } else cond->wait_chain=this; __pthread_unlock(&(cond->lock)); + __NO_ASYNC_CANCEL_STOP; - /* Aeh yeah / wait till signal */ + /* Aeh yeah / wait till cond-signal OR timeout */ pthread_mutex_unlock(mutex); - ret=nanosleep(abstime,0); + while (this->waiting) { + struct timeval tv; + gettimeofday(&tv,0); + if ((abstime->tv_sec <= tv.tv_sec) && (abstime->tv_nsec <= (tv.tv_usec*1000))) { + ret = 1; + break; + } + __thread_wait_some_time(); + if (this->canceled) break; /* a cancel */ + } pthread_mutex_lock(mutex); - __TEST_CANCEL(); - - if (ret) { - if ((*__errno_location())!=EINTR) return -1; - return 0; + __NO_ASYNC_CANCEL_BEGIN; + __pthread_lock(&(cond->lock)); + if (this->waiting) { /* still waiting -> TIMEOUT or SIGNAL */ + _pthread_descr prev; + /* remove from wait-chain */ + prev=cond->wait_chain; + if ((prev=cond->wait_chain)==this) { + cond->wait_chain=this->waitnext; + } else { + for (tmp=prev->waitnext;tmp;prev=tmp,tmp=prev->waitnext) { + if (tmp==this) { + prev->waitnext=this->waitnext; + break; + } + } + } + this->waiting=0; + this->waitnext=0; } + __pthread_unlock(&(cond->lock)); + __NO_ASYNC_CANCEL_END; + + if (ret) return ETIMEDOUT; - (*__errno_location())=ETIMEDOUT; - return -1; + { + register int err = (*__errno_location()); + if (err==EINTR) return err; + } + return 0; } -- cgit v1.2.1