THRIFT-1280. cpp: Improve Monitor exception-free interfaces
Patch: Mark Rabkin
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1160944 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/concurrency/Monitor.cpp b/lib/cpp/src/concurrency/Monitor.cpp
index 2943ef7..3d6440c 100644
--- a/lib/cpp/src/concurrency/Monitor.cpp
+++ b/lib/cpp/src/concurrency/Monitor.cpp
@@ -68,33 +68,71 @@
void lock() { mutex().lock(); }
void unlock() { mutex().unlock(); }
- void wait(int64_t timeout) const {
+ /**
+ * Exception-throwing version of waitForTimeRelative(), called simply
+ * wait(int64) for historical reasons. Timeout is in milliseconds.
+ *
+ * If the condition occurs, this function returns cleanly; on timeout or
+ * error an exception is thrown.
+ */
+ void wait(int64_t timeout_ms) const {
+ int result = waitForTimeRelative(timeout_ms);
+ if (result == ETIMEDOUT) {
+ // pthread_cond_timedwait has been observed to return early on
+ // various platforms, so comment out this assert.
+ //assert(Util::currentTime() >= (now + timeout));
+ throw TimedOutException();
+ } else if (result != 0) {
+ throw TException(
+ "pthread_cond_wait() or pthread_cond_timedwait() failed");
+ }
+ }
+
+ /**
+ * Waits until the specified timeout in milliseconds for the condition to
+ * occur, or waits forever if timeout_ms == 0.
+ *
+ * Returns 0 if condition occurs, ETIMEDOUT on timeout, or an error code.
+ */
+ int waitForTimeRelative(int64_t timeout_ms) const {
+ if (timeout_ms == 0LL) {
+ return waitForever();
+ }
+
+ struct timespec abstime;
+ Util::toTimespec(abstime, Util::currentTime() + timeout_ms);
+ return waitForTime(&abstime);
+ }
+
+ /**
+ * Waits until the absolute time specified using struct timespec.
+ * Returns 0 if condition occurs, ETIMEDOUT on timeout, or an error code.
+ */
+ int waitForTime(const timespec* abstime) const {
assert(mutex_);
pthread_mutex_t* mutexImpl =
reinterpret_cast<pthread_mutex_t*>(mutex_->getUnderlyingImpl());
assert(mutexImpl);
// XXX Need to assert that caller owns mutex
- assert(timeout >= 0LL);
- if (timeout == 0LL) {
- int iret = pthread_cond_wait(&pthread_cond_, mutexImpl);
- assert(iret == 0);
- } else {
- struct timespec abstime;
- int64_t now = Util::currentTime();
- Util::toTimespec(abstime, now + timeout);
- int result = pthread_cond_timedwait(&pthread_cond_,
- mutexImpl,
- &abstime);
- if (result == ETIMEDOUT) {
- // pthread_cond_timedwait has been observed to return early on
- // various platforms, so comment out this assert.
- //assert(Util::currentTime() >= (now + timeout));
- throw TimedOutException();
- }
- }
+ return pthread_cond_timedwait(&pthread_cond_,
+ mutexImpl,
+ abstime);
}
+ /**
+ * Waits forever until the condition occurs.
+ * Returns 0 if condition occurs, or an error code otherwise.
+ */
+ int waitForever() const {
+ assert(mutex_);
+ pthread_mutex_t* mutexImpl =
+ reinterpret_cast<pthread_mutex_t*>(mutex_->getUnderlyingImpl());
+ assert(mutexImpl);
+ return pthread_cond_wait(&pthread_cond_, mutexImpl);
+ }
+
+
void notify() {
// XXX Need to assert that caller owns mutex
int iret = pthread_cond_signal(&pthread_cond_);
@@ -151,6 +189,18 @@
void Monitor::wait(int64_t timeout) const { impl_->wait(timeout); }
+int Monitor::waitForTime(const timespec* abstime) const {
+ return impl_->waitForTime(abstime);
+}
+
+int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
+ return impl_->waitForTimeRelative(timeout_ms);
+}
+
+int Monitor::waitForever() const {
+ return impl_->waitForever();
+}
+
void Monitor::notify() const { impl_->notify(); }
void Monitor::notifyAll() const { impl_->notifyAll(); }