Reformatted thread and static_instance.
BUG= TEST=Trybots. Review URL: https://webrtc-codereview.appspot.com/1006005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3324 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
a19d04e707
commit
ec9c942e45
@ -8,14 +8,14 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATICINSTANCETEMPLATE_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATICINSTANCETEMPLATE_H_
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "critical_section_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
#ifdef _WIN32
|
||||
#include "fix_interlocked_exchange_pointer_win.h"
|
||||
#include "webrtc/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
@ -116,8 +116,8 @@ static T* GetStaticInstance(CountOperation count_operation) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int newValue = InterlockedDecrement(&instance_count);
|
||||
if (newValue == 0) {
|
||||
int new_value = InterlockedDecrement(&instance_count);
|
||||
if (new_value == 0) {
|
||||
state = kDestroy;
|
||||
}
|
||||
}
|
||||
@ -150,4 +150,4 @@ static T* GetStaticInstance(CountOperation count_operation) {
|
||||
|
||||
} // namspace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATICINSTANCETEMPLATE_H_
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
|
||||
|
@ -16,10 +16,11 @@
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
|
||||
|
||||
#include "common_types.h"
|
||||
#include "typedefs.h"
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Object that will be passed by the spawned thread when it enters the callback
|
||||
// function.
|
||||
#define ThreadObj void*
|
||||
@ -29,8 +30,7 @@ namespace webrtc {
|
||||
// more work to do and that the thread can be released.
|
||||
typedef bool(*ThreadRunFunction)(ThreadObj);
|
||||
|
||||
enum ThreadPriority
|
||||
{
|
||||
enum ThreadPriority {
|
||||
kLowPriority = 1,
|
||||
kNormalPriority = 2,
|
||||
kHighPriority = 3,
|
||||
@ -38,8 +38,7 @@ enum ThreadPriority
|
||||
kRealtimePriority = 5
|
||||
};
|
||||
|
||||
class ThreadWrapper
|
||||
{
|
||||
class ThreadWrapper {
|
||||
public:
|
||||
enum {kThreadMaxNameLength = 64};
|
||||
|
||||
@ -51,12 +50,12 @@ public:
|
||||
// obj Object associated with the thread. Passed in the callback
|
||||
// function.
|
||||
// prio Thread priority. May require root/admin rights.
|
||||
// threadName NULL terminated thread name, will be visable in the Windows
|
||||
// thread_name NULL terminated thread name, will be visable in the Windows
|
||||
// debugger.
|
||||
static ThreadWrapper* CreateThread(ThreadRunFunction func = 0,
|
||||
ThreadObj obj = 0,
|
||||
ThreadPriority prio = kNormalPriority,
|
||||
const char* threadName = 0);
|
||||
const char* thread_name = 0);
|
||||
|
||||
// Get the current thread's kernel thread ID.
|
||||
static uint32_t GetThreadId();
|
||||
@ -74,12 +73,12 @@ public:
|
||||
virtual bool Start(unsigned int& id) = 0;
|
||||
|
||||
// Sets the threads CPU affinity. CPUs are listed 0 - (number of CPUs - 1).
|
||||
// The numbers in processorNumbers specify which CPUs are allowed to run the
|
||||
// thread. processorNumbers should not contain any duplicates and elements
|
||||
// should be lower than (number of CPUs - 1). amountOfProcessors should be
|
||||
// equal to the number of processors listed in processorNumbers
|
||||
virtual bool SetAffinity(const int* /*processorNumbers*/,
|
||||
const unsigned int /*amountOfProcessors*/) {
|
||||
// The numbers in processor_numbers specify which CPUs are allowed to run the
|
||||
// thread. processor_numbers should not contain any duplicates and elements
|
||||
// should be lower than (number of CPUs - 1). amount_of_processors should be
|
||||
// equal to the number of processors listed in processor_numbers.
|
||||
virtual bool SetAffinity(const int* processor_numbers,
|
||||
const unsigned int amount_of_processors) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -89,6 +88,7 @@ public:
|
||||
// It's ok to call Stop() even if the spawned thread has been reclaimed.
|
||||
virtual bool Stop() = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
|
||||
|
@ -8,23 +8,24 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "thread_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "thread_win.h"
|
||||
#include "webrtc/system_wrappers/source/thread_win.h"
|
||||
#else
|
||||
#include "thread_posix.h"
|
||||
#include "webrtc/system_wrappers/source/thread_posix.h"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ThreadWrapper* ThreadWrapper::CreateThread(ThreadRunFunction func,
|
||||
ThreadObj obj, ThreadPriority prio,
|
||||
const char* threadName)
|
||||
{
|
||||
const char* thread_name) {
|
||||
#if defined(_WIN32)
|
||||
return new ThreadWindows(func, obj, prio, threadName);
|
||||
return new ThreadWindows(func, obj, prio, thread_name);
|
||||
#else
|
||||
return ThreadPosix::Create(func, obj, prio, threadName);
|
||||
return ThreadPosix::Create(func, obj, prio, thread_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -9,40 +9,40 @@
|
||||
*/
|
||||
|
||||
// The state of a thread is controlled by the two member variables
|
||||
// _alive and _dead.
|
||||
// _alive represents the state the thread has been ordered to achieve.
|
||||
// alive_ and dead_.
|
||||
// alive_ represents the state the thread has been ordered to achieve.
|
||||
// It is set to true by the thread at startup, and is set to false by
|
||||
// other threads, using SetNotAlive() and Stop().
|
||||
// _dead represents the state the thread has achieved.
|
||||
// dead_ represents the state the thread has achieved.
|
||||
// It is written by the thread encapsulated by this class only
|
||||
// (except at init). It is read only by the Stop() method.
|
||||
// The Run() method fires _event when it's started; this ensures that the
|
||||
// Start() method does not continue until after _dead is false.
|
||||
// The Run() method fires event_ when it's started; this ensures that the
|
||||
// Start() method does not continue until after dead_ is false.
|
||||
// This protects against premature Stop() calls from the creator thread, but
|
||||
// not from other threads.
|
||||
|
||||
// Their transitions and states:
|
||||
// _alive _dead Set by
|
||||
// alive_ dead_ Set by
|
||||
// false true Constructor
|
||||
// true false Run() method entry
|
||||
// false any Run() method runFunction failure
|
||||
// any false Run() method exit (happens only with _alive false)
|
||||
// false any Run() method run_function failure
|
||||
// any false Run() method exit (happens only with alive_ false)
|
||||
// false any SetNotAlive
|
||||
// false any Stop Stop waits for _dead to become true.
|
||||
// false any Stop Stop waits for dead_ to become true.
|
||||
//
|
||||
// Summarized a different way:
|
||||
// Variable Writer Reader
|
||||
// _alive Constructor(false) Run.loop
|
||||
// alive_ Constructor(false) Run.loop
|
||||
// Run.start(true)
|
||||
// Run.fail(false)
|
||||
// SetNotAlive(false)
|
||||
// Stop(false)
|
||||
//
|
||||
// _dead Constructor(true) Stop.loop
|
||||
// dead_ Constructor(true) Stop.loop
|
||||
// Run.start(false)
|
||||
// Run.exit(true)
|
||||
|
||||
#include "thread_posix.h"
|
||||
#include "webrtc/system_wrappers/source/thread_posix.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -59,57 +59,54 @@
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#include "system_wrappers/interface/critical_section_wrapper.h"
|
||||
#include "system_wrappers/interface/event_wrapper.h"
|
||||
#include "system_wrappers/interface/trace.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/trace.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
int ConvertToSystemPriority(ThreadPriority priority, int minPrio, int maxPrio)
|
||||
{
|
||||
assert(maxPrio - minPrio > 2);
|
||||
const int topPrio = maxPrio - 1;
|
||||
const int lowPrio = minPrio + 1;
|
||||
int ConvertToSystemPriority(ThreadPriority priority, int min_prio,
|
||||
int max_prio) {
|
||||
assert(max_prio - min_prio > 2);
|
||||
const int top_prio = max_prio - 1;
|
||||
const int low_prio = min_prio + 1;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
switch (priority) {
|
||||
case kLowPriority:
|
||||
return lowPrio;
|
||||
return low_prio;
|
||||
case kNormalPriority:
|
||||
// The -1 ensures that the kHighPriority is always greater or equal to
|
||||
// kNormalPriority.
|
||||
return (lowPrio + topPrio - 1) / 2;
|
||||
return (low_prio + top_prio - 1) / 2;
|
||||
case kHighPriority:
|
||||
return std::max(topPrio - 2, lowPrio);
|
||||
return std::max(top_prio - 2, low_prio);
|
||||
case kHighestPriority:
|
||||
return std::max(topPrio - 1, lowPrio);
|
||||
return std::max(top_prio - 1, low_prio);
|
||||
case kRealtimePriority:
|
||||
return topPrio;
|
||||
return top_prio;
|
||||
}
|
||||
assert(false);
|
||||
return lowPrio;
|
||||
return low_prio;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static void* StartThread(void* lpParameter)
|
||||
{
|
||||
static_cast<ThreadPosix*>(lpParameter)->Run();
|
||||
static void* StartThread(void* lp_parameter) {
|
||||
static_cast<ThreadPosix*>(lp_parameter)->Run();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadWrapper* ThreadPosix::Create(ThreadRunFunction func, ThreadObj obj,
|
||||
ThreadPriority prio, const char* threadName)
|
||||
{
|
||||
ThreadPosix* ptr = new ThreadPosix(func, obj, prio, threadName);
|
||||
if (!ptr)
|
||||
{
|
||||
ThreadWrapper* ThreadPosix::Create(ThreadRunFunction func,
|
||||
ThreadObj obj,
|
||||
ThreadPriority prio,
|
||||
const char* thread_name) {
|
||||
ThreadPosix* ptr = new ThreadPosix(func, obj, prio, thread_name);
|
||||
if (!ptr) {
|
||||
return NULL;
|
||||
}
|
||||
const int error = ptr->Construct();
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
delete ptr;
|
||||
return NULL;
|
||||
}
|
||||
@ -117,27 +114,25 @@ ThreadWrapper* ThreadPosix::Create(ThreadRunFunction func, ThreadObj obj,
|
||||
}
|
||||
|
||||
ThreadPosix::ThreadPosix(ThreadRunFunction func, ThreadObj obj,
|
||||
ThreadPriority prio, const char* threadName)
|
||||
: _runFunction(func),
|
||||
_obj(obj),
|
||||
_crit_state(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
_alive(false),
|
||||
_dead(true),
|
||||
_prio(prio),
|
||||
_event(EventWrapper::Create()),
|
||||
_name(),
|
||||
_setThreadName(false),
|
||||
ThreadPriority prio, const char* thread_name)
|
||||
: run_function_(func),
|
||||
obj_(obj),
|
||||
crit_state_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
alive_(false),
|
||||
dead_(true),
|
||||
prio_(prio),
|
||||
event_(EventWrapper::Create()),
|
||||
name_(),
|
||||
set_thread_name_(false),
|
||||
#if (defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID))
|
||||
_pid(-1),
|
||||
pid_(-1),
|
||||
#endif
|
||||
_attr(),
|
||||
_thread(0)
|
||||
{
|
||||
if (threadName != NULL)
|
||||
{
|
||||
_setThreadName = true;
|
||||
strncpy(_name, threadName, kThreadMaxNameLength);
|
||||
_name[kThreadMaxNameLength - 1] = '\0';
|
||||
attr_(),
|
||||
thread_(0) {
|
||||
if (thread_name != NULL) {
|
||||
set_thread_name_ = true;
|
||||
strncpy(name_, thread_name, kThreadMaxNameLength);
|
||||
name_[kThreadMaxNameLength - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,101 +144,89 @@ uint32_t ThreadWrapper::GetThreadId() {
|
||||
#endif
|
||||
}
|
||||
|
||||
int ThreadPosix::Construct()
|
||||
{
|
||||
int ThreadPosix::Construct() {
|
||||
int result = 0;
|
||||
#if !defined(WEBRTC_ANDROID)
|
||||
// Enable immediate cancellation if requested, see Shutdown()
|
||||
// Enable immediate cancellation if requested, see Shutdown().
|
||||
result = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
if (result != 0)
|
||||
{
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
result = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
if (result != 0)
|
||||
{
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
result = pthread_attr_init(&_attr);
|
||||
if (result != 0)
|
||||
{
|
||||
result = pthread_attr_init(&attr_);
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ThreadPosix::~ThreadPosix()
|
||||
{
|
||||
pthread_attr_destroy(&_attr);
|
||||
delete _event;
|
||||
delete _crit_state;
|
||||
ThreadPosix::~ThreadPosix() {
|
||||
pthread_attr_destroy(&attr_);
|
||||
delete event_;
|
||||
delete crit_state_;
|
||||
}
|
||||
|
||||
#define HAS_THREAD_ID !defined(WEBRTC_IOS) && !defined(WEBRTC_MAC)
|
||||
#if HAS_THREAD_ID
|
||||
bool ThreadPosix::Start(unsigned int& threadID)
|
||||
#else
|
||||
bool ThreadPosix::Start(unsigned int& /*threadID*/)
|
||||
#endif
|
||||
{
|
||||
if (!_runFunction)
|
||||
|
||||
bool ThreadPosix::Start(unsigned int& thread_id)
|
||||
{
|
||||
if (!run_function_) {
|
||||
return false;
|
||||
}
|
||||
int result = pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED);
|
||||
int result = pthread_attr_setdetachstate(&attr_, PTHREAD_CREATE_DETACHED);
|
||||
// Set the stack stack size to 1M.
|
||||
result |= pthread_attr_setstacksize(&_attr, 1024*1024);
|
||||
result |= pthread_attr_setstacksize(&attr_, 1024 * 1024);
|
||||
#ifdef WEBRTC_THREAD_RR
|
||||
const int policy = SCHED_RR;
|
||||
#else
|
||||
const int policy = SCHED_FIFO;
|
||||
#endif
|
||||
_event->Reset();
|
||||
event_->Reset();
|
||||
// If pthread_create was successful, a thread was created and is running.
|
||||
// Don't return false if it was successful since if there are any other
|
||||
// failures the state will be: thread was started but not configured as
|
||||
// asked for. However, the caller of this API will assume that a false
|
||||
// return value means that the thread never started.
|
||||
result |= pthread_create(&_thread, &_attr, &StartThread, this);
|
||||
if (result != 0)
|
||||
{
|
||||
result |= pthread_create(&thread_, &attr_, &StartThread, this);
|
||||
if (result != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait up to 10 seconds for the OS to call the callback function. Prevents
|
||||
// race condition if Stop() is called too quickly after start.
|
||||
if (kEventSignaled != _event->Wait(WEBRTC_EVENT_10_SEC))
|
||||
{
|
||||
if (kEventSignaled != event_->Wait(WEBRTC_EVENT_10_SEC)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
|
||||
"posix thread event never triggered");
|
||||
|
||||
// Timed out. Something went wrong.
|
||||
_runFunction = NULL;
|
||||
run_function_ = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if HAS_THREAD_ID
|
||||
threadID = static_cast<unsigned int>(_thread);
|
||||
thread_id = static_cast<unsigned int>(thread_);
|
||||
#endif
|
||||
sched_param param;
|
||||
|
||||
const int minPrio = sched_get_priority_min(policy);
|
||||
const int maxPrio = sched_get_priority_max(policy);
|
||||
if ((minPrio == EINVAL) || (maxPrio == EINVAL))
|
||||
{
|
||||
const int min_prio = sched_get_priority_min(policy);
|
||||
const int max_prio = sched_get_priority_max(policy);
|
||||
|
||||
if ((min_prio == EINVAL) || (max_prio == EINVAL)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
|
||||
"unable to retreive min or max priority for threads");
|
||||
return true;
|
||||
}
|
||||
if (maxPrio - minPrio <= 2)
|
||||
{
|
||||
if (max_prio - min_prio <= 2) {
|
||||
// There is no room for setting priorities with any granularity.
|
||||
return true;
|
||||
}
|
||||
param.sched_priority = ConvertToSystemPriority(_prio, minPrio, maxPrio);
|
||||
result = pthread_setschedparam(_thread, policy, ¶m);
|
||||
if (result == EINVAL)
|
||||
{
|
||||
param.sched_priority = ConvertToSystemPriority(prio_, min_prio, max_prio);
|
||||
result = pthread_setschedparam(thread_, policy, ¶m);
|
||||
if (result == EINVAL) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
|
||||
"unable to set thread priority");
|
||||
}
|
||||
@ -253,28 +236,28 @@ bool ThreadPosix::Start(unsigned int& /*threadID*/)
|
||||
// CPU_ZERO and CPU_SET are not available in NDK r7, so disable
|
||||
// SetAffinity on Android for now.
|
||||
#if (defined(WEBRTC_LINUX) && (!defined(WEBRTC_ANDROID)))
|
||||
bool ThreadPosix::SetAffinity(const int* processorNumbers,
|
||||
const unsigned int amountOfProcessors) {
|
||||
if (!processorNumbers || (amountOfProcessors == 0)) {
|
||||
bool ThreadPosix::SetAffinity(const int* processor_numbers,
|
||||
const unsigned int amount_of_processors) {
|
||||
if (!processor_numbers || (amount_of_processors == 0)) {
|
||||
return false;
|
||||
}
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
|
||||
for (unsigned int processor = 0;
|
||||
processor < amountOfProcessors;
|
||||
processor++) {
|
||||
CPU_SET(processorNumbers[processor], &mask);
|
||||
processor < amount_of_processors;
|
||||
++processor) {
|
||||
CPU_SET(processor_numbers[processor], &mask);
|
||||
}
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
// Android.
|
||||
const int result = syscall(__NR_sched_setaffinity,
|
||||
_pid,
|
||||
pid_,
|
||||
sizeof(mask),
|
||||
&mask);
|
||||
#else
|
||||
// "Normal" Linux.
|
||||
const int result = sched_setaffinity(_pid,
|
||||
const int result = sched_setaffinity(pid_,
|
||||
sizeof(mask),
|
||||
&mask);
|
||||
#endif
|
||||
@ -288,118 +271,99 @@ bool ThreadPosix::SetAffinity(const int* processorNumbers,
|
||||
// NOTE: On Mac OS X, use the Thread affinity API in
|
||||
// /usr/include/mach/thread_policy.h: thread_policy_set and mach_thread_self()
|
||||
// instead of Linux gettid() syscall.
|
||||
bool ThreadPosix::SetAffinity(const int* , const unsigned int)
|
||||
{
|
||||
bool ThreadPosix::SetAffinity(const int* , const unsigned int) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ThreadPosix::SetNotAlive()
|
||||
{
|
||||
CriticalSectionScoped cs(_crit_state);
|
||||
_alive = false;
|
||||
void ThreadPosix::SetNotAlive() {
|
||||
CriticalSectionScoped cs(crit_state_);
|
||||
alive_ = false;
|
||||
}
|
||||
|
||||
bool ThreadPosix::Stop()
|
||||
{
|
||||
bool ThreadPosix::Stop() {
|
||||
bool dead = false;
|
||||
{
|
||||
CriticalSectionScoped cs(_crit_state);
|
||||
_alive = false;
|
||||
dead = _dead;
|
||||
CriticalSectionScoped cs(crit_state_);
|
||||
alive_ = false;
|
||||
dead = dead_;
|
||||
}
|
||||
|
||||
// TODO(hellner) why not use an event here?
|
||||
// Wait up to 10 seconds for the thread to terminate
|
||||
for (int i = 0; i < 1000 && !dead; i++)
|
||||
{
|
||||
for (int i = 0; i < 1000 && !dead; i++) {
|
||||
timespec t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_nsec = 10 * 1000 * 1000;
|
||||
nanosleep(&t, NULL);
|
||||
{
|
||||
CriticalSectionScoped cs(_crit_state);
|
||||
dead = _dead;
|
||||
CriticalSectionScoped cs(crit_state_);
|
||||
dead = dead_;
|
||||
}
|
||||
}
|
||||
if (dead)
|
||||
{
|
||||
if (dead) {
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadPosix::Run()
|
||||
void ThreadPosix::Run() {
|
||||
{
|
||||
{
|
||||
CriticalSectionScoped cs(_crit_state);
|
||||
_alive = true;
|
||||
_dead = false;
|
||||
CriticalSectionScoped cs(crit_state_);
|
||||
alive_ = true;
|
||||
dead_ = false;
|
||||
}
|
||||
#if (defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID))
|
||||
_pid = GetThreadId();
|
||||
pid_ = GetThreadId();
|
||||
#endif
|
||||
// The event the Start() is waiting for.
|
||||
_event->Set();
|
||||
event_->Set();
|
||||
|
||||
if (_setThreadName)
|
||||
{
|
||||
if (set_thread_name_) {
|
||||
#ifdef WEBRTC_LINUX
|
||||
prctl(PR_SET_NAME, (unsigned long)_name, 0, 0, 0);
|
||||
prctl(PR_SET_NAME, (unsigned long)name_, 0, 0, 0);
|
||||
#endif
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
|
||||
"Thread with name:%s started ", _name);
|
||||
} else
|
||||
{
|
||||
"Thread with name:%s started ", name_);
|
||||
} else {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
|
||||
"Thread without name started");
|
||||
}
|
||||
bool alive = true;
|
||||
do
|
||||
{
|
||||
if (_runFunction)
|
||||
{
|
||||
if (!_runFunction(_obj))
|
||||
{
|
||||
do {
|
||||
if (run_function_) {
|
||||
if (!run_function_(obj_)) {
|
||||
alive = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
alive = false;
|
||||
}
|
||||
{
|
||||
CriticalSectionScoped cs(_crit_state);
|
||||
CriticalSectionScoped cs(crit_state_);
|
||||
if (!alive) {
|
||||
_alive = false;
|
||||
alive_ = false;
|
||||
}
|
||||
alive = _alive;
|
||||
alive = alive_;
|
||||
}
|
||||
}
|
||||
while (alive);
|
||||
} while (alive);
|
||||
|
||||
if (_setThreadName)
|
||||
{
|
||||
if (set_thread_name_) {
|
||||
// Don't set the name for the trace thread because it may cause a
|
||||
// deadlock. TODO(hellner) there should be a better solution than
|
||||
// coupling the thread and the trace class like this.
|
||||
if (strcmp(_name, "Trace"))
|
||||
{
|
||||
if (strcmp(name_, "Trace")) {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
|
||||
"Thread with name:%s stopped", _name);
|
||||
"Thread with name:%s stopped", name_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
|
||||
"Thread without name stopped");
|
||||
}
|
||||
{
|
||||
CriticalSectionScoped cs(_crit_state);
|
||||
_dead = true;
|
||||
CriticalSectionScoped cs(crit_state_);
|
||||
dead_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -11,7 +11,8 @@
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_POSIX_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_POSIX_H_
|
||||
|
||||
#include "thread_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace webrtc {
|
||||
@ -19,24 +20,24 @@ namespace webrtc {
|
||||
class CriticalSectionWrapper;
|
||||
class EventWrapper;
|
||||
|
||||
int ConvertToSystemPriority(ThreadPriority priority, int minPrio, int maxPrio);
|
||||
int ConvertToSystemPriority(ThreadPriority priority, int min_prio,
|
||||
int max_prio);
|
||||
|
||||
class ThreadPosix : public ThreadWrapper
|
||||
{
|
||||
class ThreadPosix : public ThreadWrapper {
|
||||
public:
|
||||
static ThreadWrapper* Create(ThreadRunFunction func, ThreadObj obj,
|
||||
ThreadPriority prio, const char* threadName);
|
||||
ThreadPriority prio, const char* thread_name);
|
||||
|
||||
ThreadPosix(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio,
|
||||
const char* threadName);
|
||||
const char* thread_name);
|
||||
~ThreadPosix();
|
||||
|
||||
// From ThreadWrapper
|
||||
// From ThreadWrapper.
|
||||
virtual void SetNotAlive();
|
||||
virtual bool Start(unsigned int& id);
|
||||
// Not implemented on Mac
|
||||
virtual bool SetAffinity(const int* processorNumbers,
|
||||
unsigned int amountOfProcessors);
|
||||
// Not implemented on Mac.
|
||||
virtual bool SetAffinity(const int* processor_numbers,
|
||||
unsigned int amount_of_processors);
|
||||
virtual bool Stop();
|
||||
|
||||
void Run();
|
||||
@ -45,28 +46,28 @@ private:
|
||||
int Construct();
|
||||
|
||||
private:
|
||||
// processing function
|
||||
ThreadRunFunction _runFunction;
|
||||
ThreadObj _obj;
|
||||
ThreadRunFunction run_function_;
|
||||
ThreadObj obj_;
|
||||
|
||||
// internal state
|
||||
CriticalSectionWrapper* _crit_state; // Protects _alive and _dead
|
||||
bool _alive;
|
||||
bool _dead;
|
||||
ThreadPriority _prio;
|
||||
EventWrapper* _event;
|
||||
// Internal state.
|
||||
CriticalSectionWrapper* crit_state_; // Protects alive_ and dead_
|
||||
bool alive_;
|
||||
bool dead_;
|
||||
ThreadPriority prio_;
|
||||
EventWrapper* event_;
|
||||
|
||||
// zero-terminated thread name string
|
||||
char _name[kThreadMaxNameLength];
|
||||
bool _setThreadName;
|
||||
// Zero-terminated thread name string.
|
||||
char name_[kThreadMaxNameLength];
|
||||
bool set_thread_name_;
|
||||
|
||||
// handle to thread
|
||||
// Handle to thread.
|
||||
#if (defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID))
|
||||
pid_t _pid;
|
||||
pid_t pid_;
|
||||
#endif
|
||||
pthread_attr_t _attr;
|
||||
pthread_t _thread;
|
||||
pthread_attr_t attr_;
|
||||
pthread_t thread_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_POSIX_H_
|
||||
|
@ -8,12 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "system_wrappers/source/thread_posix.h"
|
||||
#include "webrtc/system_wrappers/source/thread_posix.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(ThreadTestPosix, PrioritySettings) {
|
||||
// API assumes that maxPrio - minPrio > 2. Test the extreme case.
|
||||
// API assumes that max_prio - min_prio > 2. Test the extreme case.
|
||||
const int kMinPrio = -1;
|
||||
const int kMaxPrio = 2;
|
||||
|
||||
|
@ -8,10 +8,10 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "system_wrappers/interface/thread_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "system_wrappers/interface/scoped_ptr.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -23,7 +23,7 @@ TEST(ThreadTest, NullFunctionPointer) {
|
||||
}
|
||||
|
||||
// Function that does nothing, and reports success.
|
||||
bool NullRunFunction(void* /* obj */) {
|
||||
bool NullRunFunction(void* obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -48,8 +48,10 @@ TEST(ThreadTest, RunFunctionIsCalled) {
|
||||
&flag);
|
||||
unsigned int id = 42;
|
||||
ASSERT_TRUE(thread->Start(id));
|
||||
|
||||
// At this point, the flag may be either true or false.
|
||||
EXPECT_TRUE(thread->Stop());
|
||||
|
||||
// We expect the thread to have run at least once.
|
||||
EXPECT_TRUE(flag);
|
||||
delete thread;
|
||||
|
@ -8,58 +8,53 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "thread_win.h"
|
||||
#include "webrtc/system_wrappers/source/thread_win.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <process.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "set_thread_name_win.h"
|
||||
#include "trace.h"
|
||||
#include "webrtc/system_wrappers/interface/trace.h"
|
||||
#include "webrtc/system_wrappers/source/set_thread_name_win.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ThreadWindows::ThreadWindows(ThreadRunFunction func, ThreadObj obj,
|
||||
ThreadPriority prio, const char* threadName)
|
||||
ThreadPriority prio, const char* thread_name)
|
||||
: ThreadWrapper(),
|
||||
_runFunction(func),
|
||||
_obj(obj),
|
||||
_alive(false),
|
||||
_dead(true),
|
||||
_doNotCloseHandle(false),
|
||||
_prio(prio),
|
||||
_event(NULL),
|
||||
_thread(NULL),
|
||||
_id(0),
|
||||
_name(),
|
||||
_setThreadName(false)
|
||||
{
|
||||
_event = EventWrapper::Create();
|
||||
_critsectStop = CriticalSectionWrapper::CreateCriticalSection();
|
||||
if (threadName != NULL)
|
||||
{
|
||||
run_function_(func),
|
||||
obj_(obj),
|
||||
alive_(false),
|
||||
dead_(true),
|
||||
do_not_close_handle_(false),
|
||||
prio_(prio),
|
||||
event_(NULL),
|
||||
thread_(NULL),
|
||||
id_(0),
|
||||
name_(),
|
||||
set_thread_name_(false) {
|
||||
event_ = EventWrapper::Create();
|
||||
critsect_stop_ = CriticalSectionWrapper::CreateCriticalSection();
|
||||
if (thread_name != NULL) {
|
||||
// Set the thread name to appear in the VS debugger.
|
||||
_setThreadName = true;
|
||||
strncpy(_name, threadName, kThreadMaxNameLength);
|
||||
set_thread_name_ = true;
|
||||
strncpy(name_, thread_name, kThreadMaxNameLength);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadWindows::~ThreadWindows()
|
||||
{
|
||||
ThreadWindows::~ThreadWindows() {
|
||||
#ifdef _DEBUG
|
||||
assert(!_alive);
|
||||
assert(!alive_);
|
||||
#endif
|
||||
if (_thread)
|
||||
{
|
||||
CloseHandle(_thread);
|
||||
if (thread_) {
|
||||
CloseHandle(thread_);
|
||||
}
|
||||
if(_event)
|
||||
{
|
||||
delete _event;
|
||||
if (event_) {
|
||||
delete event_;
|
||||
}
|
||||
if(_critsectStop)
|
||||
{
|
||||
delete _critsectStop;
|
||||
if (critsect_stop_) {
|
||||
delete critsect_stop_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,156 +62,137 @@ uint32_t ThreadWrapper::GetThreadId() {
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
unsigned int WINAPI ThreadWindows::StartThread(LPVOID lpParameter)
|
||||
{
|
||||
static_cast<ThreadWindows*>(lpParameter)->Run();
|
||||
unsigned int WINAPI ThreadWindows::StartThread(LPVOID lp_parameter) {
|
||||
static_cast<ThreadWindows*>(lp_parameter)->Run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ThreadWindows::Start(unsigned int& threadID)
|
||||
{
|
||||
if (!_runFunction) {
|
||||
bool ThreadWindows::Start(unsigned int& thread_id) {
|
||||
if (!run_function_) {
|
||||
return false;
|
||||
}
|
||||
_doNotCloseHandle = false;
|
||||
do_not_close_handle_ = false;
|
||||
|
||||
// Set stack size to 1M
|
||||
_thread=(HANDLE)_beginthreadex(NULL, 1024*1024, StartThread, (void*)this, 0,
|
||||
&threadID);
|
||||
if(_thread == NULL)
|
||||
{
|
||||
thread_ = (HANDLE)_beginthreadex(NULL, 1024 * 1024, StartThread, (void*)this,
|
||||
0, &thread_id);
|
||||
if (thread_ == NULL) {
|
||||
return false;
|
||||
}
|
||||
_id = threadID;
|
||||
_event->Wait(INFINITE);
|
||||
id_ = thread_id;
|
||||
event_->Wait(INFINITE);
|
||||
|
||||
switch(_prio)
|
||||
{
|
||||
switch (prio_) {
|
||||
case kLowPriority:
|
||||
SetThreadPriority(_thread, THREAD_PRIORITY_BELOW_NORMAL);
|
||||
SetThreadPriority(thread_, THREAD_PRIORITY_BELOW_NORMAL);
|
||||
break;
|
||||
case kNormalPriority:
|
||||
SetThreadPriority(_thread, THREAD_PRIORITY_NORMAL);
|
||||
SetThreadPriority(thread_, THREAD_PRIORITY_NORMAL);
|
||||
break;
|
||||
case kHighPriority:
|
||||
SetThreadPriority(_thread, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
break;
|
||||
case kHighestPriority:
|
||||
SetThreadPriority(_thread, THREAD_PRIORITY_HIGHEST);
|
||||
SetThreadPriority(thread_, THREAD_PRIORITY_HIGHEST);
|
||||
break;
|
||||
case kRealtimePriority:
|
||||
SetThreadPriority(_thread, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
SetThreadPriority(thread_, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
break;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThreadWindows::SetAffinity(const int* processorNumbers,
|
||||
const unsigned int amountOfProcessors)
|
||||
{
|
||||
DWORD_PTR processorBitMask = 0;
|
||||
for(unsigned int processorIndex = 0;
|
||||
processorIndex < amountOfProcessors;
|
||||
processorIndex++)
|
||||
{
|
||||
bool ThreadWindows::SetAffinity(const int* processor_numbers,
|
||||
const unsigned int amount_of_processors) {
|
||||
DWORD_PTR processor_bit_mask = 0;
|
||||
for (unsigned int processor_index = 0;
|
||||
processor_index < amount_of_processors;
|
||||
++processor_index) {
|
||||
// Convert from an array with processor numbers to a bitmask
|
||||
// Processor numbers start at zero.
|
||||
// TODO(hellner): this looks like a bug. Shouldn't the '=' be a '+='?
|
||||
// Or even better |=
|
||||
processorBitMask = 1 << processorNumbers[processorIndex];
|
||||
processor_bit_mask = 1 << processor_numbers[processor_index];
|
||||
}
|
||||
return SetThreadAffinityMask(_thread,processorBitMask) != 0;
|
||||
return SetThreadAffinityMask(thread_, processor_bit_mask) != 0;
|
||||
}
|
||||
|
||||
void ThreadWindows::SetNotAlive()
|
||||
{
|
||||
_alive = false;
|
||||
void ThreadWindows::SetNotAlive() {
|
||||
alive_ = false;
|
||||
}
|
||||
|
||||
bool ThreadWindows::Stop()
|
||||
{
|
||||
_critsectStop->Enter();
|
||||
bool ThreadWindows::Stop() {
|
||||
critsect_stop_->Enter();
|
||||
|
||||
// Prevents the handle from being closed in ThreadWindows::Run()
|
||||
_doNotCloseHandle = true;
|
||||
_alive = false;
|
||||
do_not_close_handle_ = true;
|
||||
alive_ = false;
|
||||
bool signaled = false;
|
||||
if (_thread && !_dead)
|
||||
{
|
||||
_critsectStop->Leave();
|
||||
if (thread_ && !dead_) {
|
||||
critsect_stop_->Leave();
|
||||
|
||||
// Wait up to 2 seconds for the thread to complete.
|
||||
if( WAIT_OBJECT_0 == WaitForSingleObject(_thread, 2000))
|
||||
{
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(thread_, 2000)) {
|
||||
signaled = true;
|
||||
}
|
||||
_critsectStop->Enter();
|
||||
critsect_stop_->Enter();
|
||||
}
|
||||
if (_thread)
|
||||
{
|
||||
CloseHandle(_thread);
|
||||
_thread = NULL;
|
||||
if (thread_) {
|
||||
CloseHandle(thread_);
|
||||
thread_ = NULL;
|
||||
}
|
||||
_critsectStop->Leave();
|
||||
critsect_stop_->Leave();
|
||||
|
||||
if (_dead || signaled)
|
||||
{
|
||||
if (dead_ || signaled) {
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadWindows::Run()
|
||||
{
|
||||
_alive = true;
|
||||
_dead = false;
|
||||
_event->Set();
|
||||
void ThreadWindows::Run() {
|
||||
alive_ = true;
|
||||
dead_ = false;
|
||||
event_->Set();
|
||||
|
||||
// All tracing must be after _event->Set to avoid deadlock in Trace.
|
||||
if (_setThreadName)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,
|
||||
"Thread with name:%s started ", _name);
|
||||
SetThreadName(-1, _name); // -1, set thread name for the calling thread.
|
||||
}else
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,
|
||||
// All tracing must be after event_->Set to avoid deadlock in Trace.
|
||||
if (set_thread_name_) {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, id_,
|
||||
"Thread with name:%s started ", name_);
|
||||
SetThreadName(-1, name_); // -1, set thread name for the calling thread.
|
||||
} else {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, id_,
|
||||
"Thread without name started");
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (_runFunction)
|
||||
{
|
||||
if (!_runFunction(_obj))
|
||||
{
|
||||
_alive = false;
|
||||
do {
|
||||
if (run_function_) {
|
||||
if (!run_function_(obj_)) {
|
||||
alive_ = false;
|
||||
}
|
||||
} else {
|
||||
_alive = false;
|
||||
alive_ = false;
|
||||
}
|
||||
} while(_alive);
|
||||
} while (alive_);
|
||||
|
||||
if (_setThreadName)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,
|
||||
"Thread with name:%s stopped", _name);
|
||||
if (set_thread_name_) {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, id_,
|
||||
"Thread with name:%s stopped", name_);
|
||||
} else {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,_id,
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, id_,
|
||||
"Thread without name stopped");
|
||||
}
|
||||
|
||||
_critsectStop->Enter();
|
||||
critsect_stop_->Enter();
|
||||
|
||||
if (_thread && !_doNotCloseHandle)
|
||||
{
|
||||
HANDLE thread = _thread;
|
||||
_thread = NULL;
|
||||
if (thread_ && !do_not_close_handle_) {
|
||||
HANDLE thread = thread_;
|
||||
thread_ = NULL;
|
||||
CloseHandle(thread);
|
||||
}
|
||||
_dead = true;
|
||||
dead_ = true;
|
||||
|
||||
_critsectStop->Leave();
|
||||
critsect_stop_->Leave();
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -8,57 +8,58 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_
|
||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WIN_H_
|
||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WIN_H_
|
||||
|
||||
#include "thread_wrapper.h"
|
||||
#include "event_wrapper.h"
|
||||
#include "critical_section_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class ThreadWindows : public ThreadWrapper
|
||||
{
|
||||
class ThreadWindows : public ThreadWrapper {
|
||||
public:
|
||||
ThreadWindows(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio,
|
||||
const char* threadName);
|
||||
const char* thread_name);
|
||||
virtual ~ThreadWindows();
|
||||
|
||||
virtual bool Start(unsigned int& id);
|
||||
bool SetAffinity(const int* processorNumbers,
|
||||
const unsigned int amountOfProcessors);
|
||||
bool SetAffinity(const int* processor_numbers,
|
||||
const unsigned int amount_of_processors);
|
||||
virtual bool Stop();
|
||||
virtual void SetNotAlive();
|
||||
|
||||
static unsigned int WINAPI StartThread(LPVOID lpParameter);
|
||||
static unsigned int WINAPI StartThread(LPVOID lp_parameter);
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
private:
|
||||
ThreadRunFunction _runFunction;
|
||||
ThreadObj _obj;
|
||||
ThreadRunFunction run_function_;
|
||||
ThreadObj obj_;
|
||||
|
||||
bool _alive;
|
||||
bool _dead;
|
||||
bool alive_;
|
||||
bool dead_;
|
||||
|
||||
// TODO(hellner)
|
||||
// _doNotCloseHandle member seem pretty redundant. Should be able to remove
|
||||
// do_not_close_handle_ member seem pretty redundant. Should be able to remove
|
||||
// it. Basically it should be fine to reclaim the handle when calling stop
|
||||
// and in the destructor.
|
||||
bool _doNotCloseHandle;
|
||||
ThreadPriority _prio;
|
||||
EventWrapper* _event;
|
||||
CriticalSectionWrapper* _critsectStop;
|
||||
bool do_not_close_handle_;
|
||||
ThreadPriority prio_;
|
||||
EventWrapper* event_;
|
||||
CriticalSectionWrapper* critsect_stop_;
|
||||
|
||||
HANDLE _thread;
|
||||
unsigned int _id;
|
||||
char _name[kThreadMaxNameLength];
|
||||
bool _setThreadName;
|
||||
HANDLE thread_;
|
||||
unsigned int id_;
|
||||
char name_[kThreadMaxNameLength];
|
||||
bool set_thread_name_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WIN_H_
|
||||
|
Loading…
x
Reference in New Issue
Block a user