bool wait(unsigned long time) { TInt err = KErrNone; if (time == ULONG_MAX) { // untimed wait, loop because RCondVar::Wait may return before the condition is triggered do { err = cond.Wait(mutex); } while (err == KErrNone && wakeups == 0); } else { unsigned long maxWait = KMaxTInt / 1000; QElapsedTimer waitTimer; do { waitTimer.start(); unsigned long waitTime = qMin(maxWait, time); // wait at least 1ms, as 0 means no wait err = cond.TimedWait(mutex, qMax(1ul, waitTime) * 1000); // RCondVar::TimedWait may return before the condition is triggered, update the timeout with actual wait time time -= qMin((unsigned long)waitTimer.elapsed(), waitTime); } while ((err == KErrNone && wakeups == 0) || (err == KErrTimedOut && time > 0)); } Q_ASSERT_X(waiters > 0, "QWaitCondition::wait", "internal error (waiters)"); --waiters; if (err == KErrNone) { Q_ASSERT_X(wakeups > 0, "QWaitCondition::wait", "internal error (wakeups)"); --wakeups; } mutex.Signal(); if (err && err != KErrTimedOut) report_error(err, "QWaitCondition::wait()", "cv wait"); return err == KErrNone; }
bool_t ConditionWait(void* Handle,int Tick,void* Lock) { RCondVar p; RMutex m; p.SetHandle((int)Handle); m.SetHandle((int)Lock); // Increase the tick by one to mimic other platforms // which is -1 = Wait forever, 0 = Return // For Symbian, 0 = Wait forever Tick++; return p.TimedWait(m, Tick*1000) == KErrNone; }
QWaitConditionPrivate() : waiters(0), wakeups(0) { qt_symbian_throwIfError(mutex.CreateLocal()); int err = cond.CreateLocal(); if (err != KErrNone) { mutex.Close(); qt_symbian_throwIfError(err); } }
TInt Thread3(TAny* a) { SThreadData2& d = *(SThreadData2*)a; RMutex m; RCondVar cv; TInt r = m.OpenGlobal(TPtrC(d.iMutexName), EOwnerThread); if (r!=KErrNone) return r; r = cv.OpenGlobal(TPtrC(d.iCondVarName), EOwnerThread); if (r!=KErrNone) return r; m.Wait(); while (r==KErrNone) { r = cv.Wait(m); ++d.iInnerLoops; } return r; }
TInt Thread4(TAny* a) { volatile TInt& count = *(volatile TInt*)a; TInt r = KErrNone; M2.Wait(); while (r==KErrNone) { r = CV2.Wait(M2); ++count; } return r; }
~QWaitConditionPrivate() { cond.Close(); mutex.Close(); }
void ConditionSignal(void* Handle) { RCondVar p; p.SetHandle((int)Handle); p.Signal(); }
void ConditionBroadcast(void* Handle) { RCondVar p; p.SetHandle((int)Handle); p.Broadcast(); }
void ConditionClose(void* Handle) { RCondVar p; p.SetHandle((int)Handle); p.Close(); }
void* ConditionCreate() { RCondVar p; p.CreateLocal(); return (void *)p.Handle(); }
TInt Thread0(TAny*) { return CV1.Wait(M1); }