00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #if defined(QT_THREAD_SUPPORT)
00039
00040 #include "qplatformdefs.h"
00041
00042 typedef pthread_mutex_t Q_MUTEX_T;
00043
00044 #include "qwaitcondition.h"
00045 #include "qmutex.h"
00046 #include "qmutex_p.h"
00047
00048 #include <errno.h>
00049 #include <string.h>
00050
00051
00052 struct QWaitConditionPrivate {
00053 pthread_cond_t cond;
00054 };
00055
00056
00145 QWaitCondition::QWaitCondition()
00146 {
00147 d = new QWaitConditionPrivate;
00148
00149 int ret = pthread_cond_init(&d->cond, NULL);
00150
00151 #ifdef QT_CHECK_RANGE
00152 if (ret)
00153 qWarning( "Wait condition init failure: %s", strerror( ret ) );
00154 #endif
00155 }
00156
00157
00161 QWaitCondition::~QWaitCondition()
00162 {
00163 int ret = pthread_cond_destroy(&d->cond);
00164
00165 if (ret) {
00166 #ifdef QT_CHECK_RANGE
00167 qWarning( "Wait condition destroy failure: %s", strerror( ret ) );
00168 #endif
00169
00170
00171 pthread_cond_broadcast(&d->cond);
00172 }
00173
00174 delete d;
00175 }
00176
00184 void QWaitCondition::wakeOne()
00185 {
00186 int ret = pthread_cond_signal(&d->cond);
00187
00188 #ifdef QT_CHECK_RANGE
00189 if (ret)
00190 qWarning("Wait condition wakeOne failure: %s", strerror(ret));
00191 #endif
00192 }
00193
00201 void QWaitCondition::wakeAll()
00202 {
00203 int ret = pthread_cond_broadcast(&d->cond);
00204
00205 #ifdef QT_CHECK_RANGE
00206 if (ret)
00207 qWarning("Wait condition wakeAll failure: %s", strerror(ret));
00208 #endif
00209 }
00210
00225 bool QWaitCondition::wait(unsigned long time)
00226 {
00227 pthread_mutex_t mutex;
00228 pthread_mutex_init( &mutex, 0 );
00229 pthread_mutex_lock( &mutex );
00230
00231 int ret;
00232 if (time != ULONG_MAX) {
00233 struct timeval tv;
00234 gettimeofday(&tv, 0);
00235
00236 timespec ti;
00237 ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000;
00238 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
00239 ti.tv_nsec %= 1000000000;
00240
00241 ret = pthread_cond_timedwait(&d->cond, &mutex, &ti);
00242 } else
00243 ret = pthread_cond_wait(&d->cond, &mutex);
00244
00245 #ifdef QT_CHECK_RANGE
00246 if (ret && ret != ETIMEDOUT)
00247 qWarning("Wait condition wait failure: %s",strerror(ret));
00248 #endif
00249
00250 pthread_mutex_unlock( &mutex );
00251 pthread_mutex_destroy( &mutex );
00252
00253 return (ret == 0);
00254 }
00255
00280 bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
00281 {
00282 if (! mutex)
00283 return FALSE;
00284
00285 if (mutex->d->type() == Q_MUTEX_RECURSIVE) {
00286 #ifdef QT_CHECK_RANGE
00287 qWarning("Wait condition warning: using recursive mutexes with\n"
00288 " wait conditions is undefined!");
00289 #endif
00290 return FALSE;
00291 }
00292
00293 int ret;
00294 if (time != ULONG_MAX) {
00295 struct timeval tv;
00296 gettimeofday(&tv, 0);
00297
00298 timespec ti;
00299 ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000;
00300 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
00301 ti.tv_nsec %= 1000000000;
00302
00303 ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti);
00304 } else
00305 ret = pthread_cond_wait(&d->cond, &mutex->d->handle);
00306
00307 #ifdef QT_CHECK_RANGE
00308 if (ret && ret != ETIMEDOUT)
00309 qWarning("Wait condition wait failure: %s",strerror(ret));
00310 #endif
00311
00312 return (ret == 0);
00313 }
00314
00315 #endif // QT_THREAD_SUPPORT