diff --git a/webrtc/system_wrappers/source/event_posix.cc b/webrtc/system_wrappers/source/event_posix.cc index c873e3a9da..d1331500b9 100644 --- a/webrtc/system_wrappers/source/event_posix.cc +++ b/webrtc/system_wrappers/source/event_posix.cc @@ -26,64 +26,30 @@ const long int E6 = 1000000; const long int E9 = 1000 * E6; EventWrapper* EventPosix::Create() { - EventPosix* ptr = new EventPosix; - if (!ptr) { - return NULL; - } - - const int error = ptr->Construct(); - if (error) { - delete ptr; - return NULL; - } - return ptr; + return new EventPosix(); } EventPosix::EventPosix() - : timer_thread_(0), + : event_set_(false), + timer_thread_(nullptr), timer_event_(0), + created_at_(), periodic_(false), time_(0), - count_(0), - state_(kDown) { -} - -int EventPosix::Construct() { - // Set start time to zero - memset(&created_at_, 0, sizeof(created_at_)); - + count_(0) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - int result = pthread_mutex_init(&mutex_, &attr); - if (result != 0) { - return -1; - } + pthread_mutex_init(&mutex_, &attr); #ifdef WEBRTC_CLOCK_TYPE_REALTIME - result = pthread_cond_init(&cond_, 0); - if (result != 0) { - return -1; - } + pthread_cond_init(&cond_, 0); #else pthread_condattr_t cond_attr; - result = pthread_condattr_init(&cond_attr); - if (result != 0) { - return -1; - } - result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC); - if (result != 0) { - return -1; - } - result = pthread_cond_init(&cond_, &cond_attr); - if (result != 0) { - return -1; - } - result = pthread_condattr_destroy(&cond_attr); - if (result != 0) { - return -1; - } + pthread_condattr_init(&cond_attr); + pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC); + pthread_cond_init(&cond_, &cond_attr); + pthread_condattr_destroy(&cond_attr); #endif - return 0; } EventPosix::~EventPosix() { @@ -92,24 +58,20 @@ EventPosix::~EventPosix() { pthread_mutex_destroy(&mutex_); } +// TODO(pbos): Make this void. bool EventPosix::Set() { - if (0 != pthread_mutex_lock(&mutex_)) { - return false; - } - state_ = kUp; - // Release all waiting threads - pthread_cond_broadcast(&cond_); + CHECK_EQ(0, pthread_mutex_lock(&mutex_)); + event_set_ = true; + pthread_cond_signal(&cond_); pthread_mutex_unlock(&mutex_); return true; } EventTypeWrapper EventPosix::Wait(unsigned long timeout) { int ret_val = 0; - if (0 != pthread_mutex_lock(&mutex_)) { - return kEventError; - } + CHECK_EQ(0, pthread_mutex_lock(&mutex_)); - if (kDown == state_) { + if (!event_set_) { if (WEBRTC_EVENT_INFINITE != timeout) { timespec end_at; #ifndef WEBRTC_MAC @@ -133,52 +95,43 @@ EventTypeWrapper EventPosix::Wait(unsigned long timeout) { end_at.tv_sec++; end_at.tv_nsec -= E9; } - ret_val = pthread_cond_timedwait(&cond_, &mutex_, &end_at); + while (ret_val == 0 && !event_set_) + ret_val = pthread_cond_timedwait(&cond_, &mutex_, &end_at); } else { - ret_val = pthread_cond_wait(&cond_, &mutex_); + while (ret_val == 0 && !event_set_) + ret_val = pthread_cond_wait(&cond_, &mutex_); } } - // Be careful to only change the state if we're about to report that the - // event was signaled. - if (ret_val == 0) { - // state_ might already be kDown, in case of multiple waiters. That's OK. - state_ = kDown; - } + DCHECK(ret_val == 0 || ret_val == ETIMEDOUT); + // Reset and signal if set, regardless of why the thread woke up. + if (event_set_) { + ret_val = 0; + event_set_ = false; + } pthread_mutex_unlock(&mutex_); - switch (ret_val) { - case 0: - return kEventSignaled; - case ETIMEDOUT: - return kEventTimeout; - default: - return kEventError; - } + return ret_val == 0 ? kEventSignaled : kEventTimeout; } -EventTypeWrapper EventPosix::Wait(timespec& wake_at) { +EventTypeWrapper EventPosix::Wait(timespec* end_at) { int ret_val = 0; - if (0 != pthread_mutex_lock(&mutex_)) { - return kEventError; - } + CHECK_EQ(0, pthread_mutex_lock(&mutex_)); - if (kUp != state_) { - ret_val = pthread_cond_timedwait(&cond_, &mutex_, &wake_at); - } - state_ = kDown; + while (ret_val == 0 && !event_set_) + ret_val = pthread_cond_timedwait(&cond_, &mutex_, end_at); + DCHECK(ret_val == 0 || ret_val == ETIMEDOUT); + + // Reset and signal if set, regardless of why the thread woke up. + if (event_set_) { + ret_val = 0; + event_set_ = false; + } pthread_mutex_unlock(&mutex_); - switch (ret_val) { - case 0: - return kEventSignaled; - case ETIMEDOUT: - return kEventTimeout; - default: - return kEventError; - } + return ret_val == 0 ? kEventSignaled : kEventTimeout; } bool EventPosix::StartTimer(bool periodic, unsigned long time) { @@ -246,14 +199,8 @@ bool EventPosix::Process() { } pthread_mutex_unlock(&mutex_); - switch (timer_event_->Wait(end_at)) { - case kEventSignaled: - return true; - case kEventError: - return false; - case kEventTimeout: - break; - } + if (timer_event_->Wait(&end_at) == kEventSignaled) + return true; pthread_mutex_lock(&mutex_); if (periodic_ || count_ == 1) diff --git a/webrtc/system_wrappers/source/event_posix.h b/webrtc/system_wrappers/source/event_posix.h index 7512c88a14..0a3fc7ba7e 100644 --- a/webrtc/system_wrappers/source/event_posix.h +++ b/webrtc/system_wrappers/source/event_posix.h @@ -39,15 +39,15 @@ class EventPosix : public EventWrapper { private: EventPosix(); - int Construct(); static bool Run(ThreadObj obj); bool Process(); - EventTypeWrapper Wait(timespec& wake_at); + EventTypeWrapper Wait(timespec* end_at); private: pthread_cond_t cond_; pthread_mutex_t mutex_; + bool event_set_; ThreadWrapper* timer_thread_; EventPosix* timer_event_; @@ -56,7 +56,6 @@ class EventPosix : public EventWrapper { bool periodic_; unsigned long time_; // In ms unsigned long count_; - State state_; }; } // namespace webrtc