Delete class EventTimerWrapper.
Only user, iSACTest, refactored to use a sleep instead. Bug: webrtc:3380 Change-Id: I683a5a05349f75a17e5d2a02d4a20a9cf059a28f Reviewed-on: https://webrtc-review.googlesource.com/96802 Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24541}
This commit is contained in:
@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "system_wrappers/source/event_timer_posix.h"
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
#include <android/api-level.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
|
||||
// Chromium build is always defining this macro if __ANDROID_API__ < 20.
|
||||
#undef HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||
#endif
|
||||
|
||||
#if defined(WEBRTC_ANDROID) && defined(__ANDROID_API__)
|
||||
#define HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC (__ANDROID_API__ < 21)
|
||||
#else
|
||||
#define HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC 0
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
EventTimerWrapper* EventTimerWrapper::Create() {
|
||||
return new EventTimerPosix();
|
||||
}
|
||||
|
||||
const int64_t kNanosecondsPerMillisecond = 1000000;
|
||||
const int64_t kNanosecondsPerSecond = 1000000000;
|
||||
|
||||
EventTimerPosix::EventTimerPosix()
|
||||
: event_set_(false),
|
||||
timer_thread_(nullptr),
|
||||
created_at_(),
|
||||
periodic_(false),
|
||||
time_ms_(0),
|
||||
count_(0),
|
||||
is_stopping_(false) {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mutex_, &attr);
|
||||
pthread_condattr_t cond_attr;
|
||||
pthread_condattr_init(&cond_attr);
|
||||
// TODO(sprang): Remove HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC special case once
|
||||
// all supported Android platforms support pthread_condattr_setclock.
|
||||
// TODO(sprang): Add support for monotonic clock on Apple platforms.
|
||||
#if !(defined(WEBRTC_MAC) || defined(WEBRTC_IOS)) && \
|
||||
!(defined(WEBRTC_ANDROID) && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
|
||||
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
|
||||
#endif
|
||||
pthread_cond_init(&cond_, &cond_attr);
|
||||
pthread_condattr_destroy(&cond_attr);
|
||||
}
|
||||
|
||||
EventTimerPosix::~EventTimerPosix() {
|
||||
StopTimer();
|
||||
pthread_cond_destroy(&cond_);
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
// TODO(pbos): Make this void.
|
||||
bool EventTimerPosix::Set() {
|
||||
RTC_CHECK_EQ(0, pthread_mutex_lock(&mutex_));
|
||||
event_set_ = true;
|
||||
pthread_cond_signal(&cond_);
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return true;
|
||||
}
|
||||
|
||||
EventTypeWrapper EventTimerPosix::Wait(unsigned long timeout_ms) {
|
||||
int ret_val = 0;
|
||||
RTC_CHECK_EQ(0, pthread_mutex_lock(&mutex_));
|
||||
|
||||
if (!event_set_) {
|
||||
if (WEBRTC_EVENT_INFINITE != timeout_ms) {
|
||||
timespec end_at;
|
||||
#ifndef WEBRTC_MAC
|
||||
clock_gettime(CLOCK_MONOTONIC, &end_at);
|
||||
#else
|
||||
timeval value;
|
||||
struct timezone time_zone;
|
||||
time_zone.tz_minuteswest = 0;
|
||||
time_zone.tz_dsttime = 0;
|
||||
gettimeofday(&value, &time_zone);
|
||||
TIMEVAL_TO_TIMESPEC(&value, &end_at);
|
||||
#endif
|
||||
end_at.tv_sec += timeout_ms / 1000;
|
||||
end_at.tv_nsec += (timeout_ms % 1000) * kNanosecondsPerMillisecond;
|
||||
|
||||
if (end_at.tv_nsec >= kNanosecondsPerSecond) {
|
||||
end_at.tv_sec++;
|
||||
end_at.tv_nsec -= kNanosecondsPerSecond;
|
||||
}
|
||||
while (ret_val == 0 && !event_set_) {
|
||||
#if defined(WEBRTC_ANDROID) && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||
ret_val = pthread_cond_timedwait_monotonic_np(&cond_, &mutex_, &end_at);
|
||||
#else
|
||||
ret_val = pthread_cond_timedwait(&cond_, &mutex_, &end_at);
|
||||
#endif // WEBRTC_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||
}
|
||||
} else {
|
||||
while (ret_val == 0 && !event_set_)
|
||||
ret_val = pthread_cond_wait(&cond_, &mutex_);
|
||||
}
|
||||
}
|
||||
|
||||
RTC_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_);
|
||||
|
||||
return ret_val == 0 ? kEventSignaled : kEventTimeout;
|
||||
}
|
||||
|
||||
EventTypeWrapper EventTimerPosix::Wait(timespec* end_at, bool reset_event) {
|
||||
int ret_val = 0;
|
||||
RTC_CHECK_EQ(0, pthread_mutex_lock(&mutex_));
|
||||
if (reset_event) {
|
||||
// Only wake for new events or timeouts.
|
||||
event_set_ = false;
|
||||
}
|
||||
|
||||
while (ret_val == 0 && !event_set_) {
|
||||
#if defined(WEBRTC_ANDROID) && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||
ret_val = pthread_cond_timedwait_monotonic_np(&cond_, &mutex_, end_at);
|
||||
#else
|
||||
ret_val = pthread_cond_timedwait(&cond_, &mutex_, end_at);
|
||||
#endif // WEBRTC_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||
}
|
||||
|
||||
RTC_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_);
|
||||
|
||||
return ret_val == 0 ? kEventSignaled : kEventTimeout;
|
||||
}
|
||||
|
||||
rtc::PlatformThread* EventTimerPosix::CreateThread() {
|
||||
const char* kThreadName = "WebRtc_event_timer_thread";
|
||||
return new rtc::PlatformThread(Run, this, kThreadName);
|
||||
}
|
||||
|
||||
bool EventTimerPosix::StartTimer(bool periodic, unsigned long time_ms) {
|
||||
pthread_mutex_lock(&mutex_);
|
||||
if (timer_thread_) {
|
||||
if (periodic_) {
|
||||
// Timer already started.
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return false;
|
||||
} else {
|
||||
// New one shot timer.
|
||||
time_ms_ = time_ms;
|
||||
created_at_.tv_sec = 0;
|
||||
timer_event_->Set();
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Start the timer thread.
|
||||
timer_event_.reset(new EventTimerPosix());
|
||||
timer_thread_.reset(CreateThread());
|
||||
periodic_ = periodic;
|
||||
time_ms_ = time_ms;
|
||||
timer_thread_->Start();
|
||||
timer_thread_->SetPriority(rtc::kRealtimePriority);
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventTimerPosix::Run(void* obj) {
|
||||
return static_cast<EventTimerPosix*>(obj)->Process();
|
||||
}
|
||||
|
||||
bool EventTimerPosix::Process() {
|
||||
pthread_mutex_lock(&mutex_);
|
||||
if (is_stopping_) {
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
return false;
|
||||
}
|
||||
if (created_at_.tv_sec == 0) {
|
||||
#ifndef WEBRTC_MAC
|
||||
RTC_CHECK_EQ(0, clock_gettime(CLOCK_MONOTONIC, &created_at_));
|
||||
#else
|
||||
timeval value;
|
||||
struct timezone time_zone;
|
||||
time_zone.tz_minuteswest = 0;
|
||||
time_zone.tz_dsttime = 0;
|
||||
gettimeofday(&value, &time_zone);
|
||||
TIMEVAL_TO_TIMESPEC(&value, &created_at_);
|
||||
#endif
|
||||
count_ = 0;
|
||||
}
|
||||
|
||||
timespec end_at;
|
||||
unsigned long long total_delta_ms = time_ms_ * ++count_;
|
||||
if (!periodic_ && count_ >= 1) {
|
||||
// No need to wake up often if we're not going to signal waiting threads.
|
||||
total_delta_ms =
|
||||
std::min<uint64_t>(total_delta_ms, 60 * kNanosecondsPerSecond);
|
||||
}
|
||||
|
||||
end_at.tv_sec = created_at_.tv_sec + total_delta_ms / 1000;
|
||||
end_at.tv_nsec = created_at_.tv_nsec +
|
||||
(total_delta_ms % 1000) * kNanosecondsPerMillisecond;
|
||||
|
||||
if (end_at.tv_nsec >= kNanosecondsPerSecond) {
|
||||
end_at.tv_sec++;
|
||||
end_at.tv_nsec -= kNanosecondsPerSecond;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
// Reset event on first call so that we don't immediately return here if this
|
||||
// thread was not blocked on timer_event_->Wait when the StartTimer() call
|
||||
// was made.
|
||||
if (timer_event_->Wait(&end_at, count_ == 1) == kEventSignaled)
|
||||
return true;
|
||||
|
||||
pthread_mutex_lock(&mutex_);
|
||||
if (periodic_ || count_ == 1)
|
||||
Set();
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventTimerPosix::StopTimer() {
|
||||
pthread_mutex_lock(&mutex_);
|
||||
is_stopping_ = true;
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
|
||||
if (timer_event_)
|
||||
timer_event_->Set();
|
||||
|
||||
if (timer_thread_) {
|
||||
timer_thread_->Stop();
|
||||
timer_thread_.reset();
|
||||
}
|
||||
timer_event_.reset();
|
||||
|
||||
// Set time to zero to force new reference time for the timer.
|
||||
memset(&created_at_, 0, sizeof(created_at_));
|
||||
count_ = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
Reference in New Issue
Block a user