Replace the stop_event_ in PlatformThread with an atomic flag
BUG=webrtc:7187 Review-Url: https://codereview.webrtc.org/2708433002 Cr-Commit-Position: refs/heads/master@{#16705}
This commit is contained in:
parent
d95c48a810
commit
82ead60076
@ -10,6 +10,7 @@
|
||||
|
||||
#include "webrtc/base/platform_thread.h"
|
||||
|
||||
#include "webrtc/base/atomicops.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
#if defined(WEBRTC_LINUX)
|
||||
@ -96,15 +97,7 @@ PlatformThread::PlatformThread(ThreadRunFunction func,
|
||||
const char* thread_name)
|
||||
: run_function_(func),
|
||||
obj_(obj),
|
||||
name_(thread_name ? thread_name : "webrtc"),
|
||||
#if defined(WEBRTC_WIN)
|
||||
stop_(false),
|
||||
thread_(NULL),
|
||||
thread_id_(0) {
|
||||
#else
|
||||
stop_event_(false, false),
|
||||
thread_(0) {
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
name_(thread_name ? thread_name : "webrtc") {
|
||||
RTC_DCHECK(func);
|
||||
RTC_DCHECK(name_.length() < 64);
|
||||
}
|
||||
@ -187,15 +180,26 @@ void PlatformThread::Stop() {
|
||||
thread_ = nullptr;
|
||||
thread_id_ = 0;
|
||||
#else
|
||||
stop_event_.Set();
|
||||
RTC_CHECK_EQ(1, AtomicOps::Increment(&stop_flag_));
|
||||
RTC_CHECK_EQ(0, pthread_join(thread_, nullptr));
|
||||
AtomicOps::ReleaseStore(&stop_flag_, 0);
|
||||
thread_ = 0;
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
}
|
||||
|
||||
// TODO(tommi): Deprecate the loop behavior in PlatformThread.
|
||||
// * Introduce a new callback type that returns void.
|
||||
// * Remove potential for a busy loop in PlatformThread.
|
||||
// * Delegate the responsibility for how to stop the thread, to the
|
||||
// implementation that actually uses the thread.
|
||||
// All implementations will need to be aware of how the thread should be stopped
|
||||
// and encouraging a busy polling loop, can be costly in terms of power and cpu.
|
||||
void PlatformThread::Run() {
|
||||
if (!name_.empty())
|
||||
rtc::SetCurrentThreadName(name_.c_str());
|
||||
#if !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN)
|
||||
const struct timespec ts_null = {0};
|
||||
#endif
|
||||
do {
|
||||
// The interface contract of Start/Stop is that for a successful call to
|
||||
// Start, there should be at least one call to the run function. So we
|
||||
@ -207,7 +211,12 @@ void PlatformThread::Run() {
|
||||
SleepEx(0, true);
|
||||
} while (!stop_);
|
||||
#else
|
||||
} while (!stop_event_.Wait(0));
|
||||
#if defined(WEBRTC_MAC)
|
||||
sched_yield();
|
||||
#else
|
||||
nanosleep(&ts_null, nullptr);
|
||||
#endif
|
||||
} while (!AtomicOps::AcquireLoad(&stop_flag_));
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
}
|
||||
|
||||
|
||||
@ -94,15 +94,16 @@ class PlatformThread {
|
||||
#if defined(WEBRTC_WIN)
|
||||
static DWORD WINAPI StartThread(void* param);
|
||||
|
||||
bool stop_;
|
||||
HANDLE thread_;
|
||||
DWORD thread_id_;
|
||||
bool stop_ = false;
|
||||
HANDLE thread_ = nullptr;
|
||||
DWORD thread_id_ = 0;
|
||||
#else
|
||||
static void* StartThread(void* param);
|
||||
|
||||
rtc::Event stop_event_;
|
||||
|
||||
pthread_t thread_;
|
||||
// An atomic flag that we use to stop the thread. Only modified on the
|
||||
// controlling thread and checked on the worker thread.
|
||||
volatile int stop_flag_ = 0;
|
||||
pthread_t thread_ = 0;
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(PlatformThread);
|
||||
};
|
||||
|
||||
@ -85,7 +85,9 @@ TEST(ProcessThreadImpl, ProcessCall) {
|
||||
std::unique_ptr<EventWrapper> event(EventWrapper::Create());
|
||||
|
||||
MockModule module;
|
||||
EXPECT_CALL(module, TimeUntilNextProcess()).WillRepeatedly(Return(0));
|
||||
EXPECT_CALL(module, TimeUntilNextProcess())
|
||||
.WillOnce(Return(0))
|
||||
.WillRepeatedly(Return(1));
|
||||
EXPECT_CALL(module, Process())
|
||||
.WillOnce(DoAll(SetEvent(event.get()), Return()))
|
||||
.WillRepeatedly(Return());
|
||||
@ -105,7 +107,9 @@ TEST(ProcessThreadImpl, ProcessCall2) {
|
||||
std::unique_ptr<EventWrapper> event(EventWrapper::Create());
|
||||
|
||||
MockModule module;
|
||||
EXPECT_CALL(module, TimeUntilNextProcess()).WillRepeatedly(Return(0));
|
||||
EXPECT_CALL(module, TimeUntilNextProcess())
|
||||
.WillOnce(Return(0))
|
||||
.WillRepeatedly(Return(1));
|
||||
EXPECT_CALL(module, Process())
|
||||
.WillOnce(DoAll(SetEvent(event.get()), Return()))
|
||||
.WillRepeatedly(Return());
|
||||
@ -128,7 +132,9 @@ TEST(ProcessThreadImpl, Deregister) {
|
||||
|
||||
int process_count = 0;
|
||||
MockModule module;
|
||||
EXPECT_CALL(module, TimeUntilNextProcess()).WillRepeatedly(Return(0));
|
||||
EXPECT_CALL(module, TimeUntilNextProcess())
|
||||
.WillOnce(Return(0))
|
||||
.WillRepeatedly(Return(1));
|
||||
EXPECT_CALL(module, Process())
|
||||
.WillOnce(DoAll(SetEvent(event.get()),
|
||||
Increment(&process_count),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user