/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using mozilla::CheckedInt; using mozilla::TimeDuration;
staticconstlong NanoSecPerSec = 1000000000;
// Android 4.4 or earlier & macOS 10.12 has the clock functions, but not // pthread_condattr_setclock. #ifdefined(HAVE_CLOCK_MONOTONIC) && \
!(defined(__ANDROID__) && __ANDROID_API__ < 21) && !defined(__APPLE__) # define CV_USE_CLOCK_API #endif
#ifdef CV_USE_CLOCK_API // The C++ specification defines std::condition_variable::wait_for in terms of // std::chrono::steady_clock, which is closest to CLOCK_MONOTONIC. staticconst clockid_t WhichClock = CLOCK_MONOTONIC;
// While timevaladd is widely available to work with timevals, the newer // timespec structure is largely lacking such conveniences. Thankfully, the // utilities available in MFBT make implementing our own quite easy. staticvoid moz_timespecadd(struct timespec* lhs, struct timespec* rhs, struct timespec* result) { // Add nanoseconds. This may wrap, but not above 2 billion.
MOZ_RELEASE_ASSERT(lhs->tv_nsec < NanoSecPerSec);
MOZ_RELEASE_ASSERT(rhs->tv_nsec < NanoSecPerSec);
result->tv_nsec = lhs->tv_nsec + rhs->tv_nsec;
// Add seconds, checking for overflow in the platform specific time_t type.
CheckedInt<time_t> sec = CheckedInt<time_t>(lhs->tv_sec) + rhs->tv_sec;
// If nanoseconds overflowed, carry the result over into seconds. if (result->tv_nsec >= NanoSecPerSec) {
MOZ_RELEASE_ASSERT(result->tv_nsec < 2 * NanoSecPerSec);
result->tv_nsec -= NanoSecPerSec;
sec += 1;
}
// Extracting the value asserts that there was no overflow.
MOZ_RELEASE_ASSERT(sec.isValid());
result->tv_sec = sec.value();
} #endif
#ifdef CV_USE_CLOCK_API
pthread_condattr_t attr; int r0 = pthread_condattr_init(&attr);
MOZ_RELEASE_ASSERT(!r0);
int r1 = pthread_condattr_setclock(&attr, WhichClock);
MOZ_RELEASE_ASSERT(!r1);
int r2 = pthread_cond_init(ptCond, &attr);
MOZ_RELEASE_ASSERT(!r2);
int r3 = pthread_condattr_destroy(&attr);
MOZ_RELEASE_ASSERT(!r3); #else int r = pthread_cond_init(ptCond, NULL);
MOZ_RELEASE_ASSERT(!r); #endif
}
mozilla::detail::ConditionVariableImpl::~ConditionVariableImpl() { int r = pthread_cond_destroy(&platformData()->ptCond);
MOZ_RELEASE_ASSERT(r == 0);
}
void mozilla::detail::ConditionVariableImpl::notify_one() { int r = pthread_cond_signal(&platformData()->ptCond);
MOZ_RELEASE_ASSERT(r == 0);
}
void mozilla::detail::ConditionVariableImpl::notify_all() { int r = pthread_cond_broadcast(&platformData()->ptCond);
MOZ_RELEASE_ASSERT(r == 0);
}
r = pthread_cond_timedwait(ptCond, ptMutex, &abs_ts); #else // Our non-clock-supporting platforms, OS X and Android, do support waiting // on a condition variable with a relative timeout.
r = pthread_cond_timedwait_relative_np(ptCond, ptMutex, &rel_ts); #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.