blob: 0fbf88bc60591b74fa02b86dc057bbe563b07db5 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000011#include "webrtc/system_wrappers/source/thread_win.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
niklase@google.com470e71d2011-07-07 08:21:25 +000013#include <process.h>
14#include <stdio.h>
15#include <windows.h>
16
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000017#include "webrtc/base/checks.h"
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000018#include "webrtc/system_wrappers/interface/trace.h"
19#include "webrtc/system_wrappers/source/set_thread_name_win.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
niklase@google.com470e71d2011-07-07 08:21:25 +000021namespace webrtc {
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000022
niklase@google.com470e71d2011-07-07 08:21:25 +000023ThreadWindows::ThreadWindows(ThreadRunFunction func, ThreadObj obj,
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000024 ThreadPriority prio, const char* thread_name)
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000025 : run_function_(func),
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000026 obj_(obj),
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000027 prio_(prio),
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000028 event_(CreateEvent(NULL, FALSE, FALSE, NULL)),
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000029 thread_(NULL),
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000030 name_(thread_name ? thread_name : "webrtc") {
31 DCHECK(func);
32 DCHECK(event_);
niklase@google.com470e71d2011-07-07 08:21:25 +000033}
34
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000035ThreadWindows::~ThreadWindows() {
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000036 DCHECK(main_thread_.CalledOnValidThread());
37 DCHECK(!thread_);
38 CloseHandle(event_);
niklase@google.com470e71d2011-07-07 08:21:25 +000039}
40
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000041// static
pwestin@webrtc.orgb54d7272012-01-11 08:28:04 +000042uint32_t ThreadWrapper::GetThreadId() {
43 return GetCurrentThreadId();
44}
45
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000046// static
47DWORD WINAPI ThreadWindows::StartThread(void* param) {
48 static_cast<ThreadWindows*>(param)->Run();
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000049 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000050}
51
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000052bool ThreadWindows::Start(unsigned int& id) {
53 DCHECK(main_thread_.CalledOnValidThread());
54 DCHECK(!thread_);
55
56 // See bug 2902 for stack size.
57 DWORD thread_id;
58 thread_ = ::CreateThread(NULL, 0, &StartThread, this,
59 STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id);
60 if (!thread_ ) {
61 DCHECK(false) << "CreateThread failed";
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000062 return false;
63 }
niklase@google.com470e71d2011-07-07 08:21:25 +000064
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000065 id = thread_id;
66
67 if (prio_ != kNormalPriority) {
68 int priority = THREAD_PRIORITY_NORMAL;
69 switch (prio_) {
70 case kLowPriority:
71 priority = THREAD_PRIORITY_BELOW_NORMAL;
72 break;
73 case kHighPriority:
74 priority = THREAD_PRIORITY_ABOVE_NORMAL;
75 break;
76 case kHighestPriority:
77 priority = THREAD_PRIORITY_HIGHEST;
78 break;
79 case kRealtimePriority:
80 priority = THREAD_PRIORITY_TIME_CRITICAL;
81 break;
82 default:
83 break;
84 }
85
86 SetThreadPriority(thread_, priority);
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000087 }
niklase@google.com470e71d2011-07-07 08:21:25 +000088
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000089 return true;
90}
91
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000092void ThreadWindows::SetNotAlive() {
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000093 DCHECK(main_thread_.CalledOnValidThread());
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000094}
95
96bool ThreadWindows::Stop() {
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000097 DCHECK(main_thread_.CalledOnValidThread());
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +000098 if (thread_) {
tommi@webrtc.orgaef07792015-01-30 15:06:10 +000099 SetEvent(event_);
100 WaitForSingleObject(thread_, INFINITE);
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +0000101 CloseHandle(thread_);
tommi@webrtc.orgaef07792015-01-30 15:06:10 +0000102 thread_ = nullptr;
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +0000103 }
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +0000104
tommi@webrtc.orgaef07792015-01-30 15:06:10 +0000105 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000106}
107
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +0000108void ThreadWindows::Run() {
tommi@webrtc.orgaef07792015-01-30 15:06:10 +0000109 if (!name_.empty())
110 SetThreadName(static_cast<DWORD>(-1), name_.c_str());
niklase@google.com470e71d2011-07-07 08:21:25 +0000111
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +0000112 do {
tommi@webrtc.orgaef07792015-01-30 15:06:10 +0000113 if (!run_function_(obj_))
114 break;
115 } while (WaitForSingleObject(event_, 0) == WAIT_TIMEOUT);
116}
phoglund@webrtc.orgec9c9422013-01-02 08:45:03 +0000117
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000118} // namespace webrtc