Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: webrtc/base/platform_thread.cc

Issue 1469013002: Move ThreadWrapper to ProcessThread in base. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: removed comment Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/platform_thread.h ('k') | webrtc/base/platform_thread_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/base/platform_thread.h" 11 #include "webrtc/base/platform_thread.h"
12 12
13 #include <string.h>
14
15 #include "webrtc/base/checks.h" 13 #include "webrtc/base/checks.h"
16 14
17 #if defined(WEBRTC_LINUX) 15 #if defined(WEBRTC_LINUX)
18 #include <sys/prctl.h> 16 #include <sys/prctl.h>
19 #include <sys/syscall.h> 17 #include <sys/syscall.h>
20 #endif 18 #endif
21 19
22 namespace rtc { 20 namespace rtc {
23 21
24 PlatformThreadId CurrentThreadId() { 22 PlatformThreadId CurrentThreadId() {
(...skipping 26 matching lines...) Expand all
51 49
52 bool IsThreadRefEqual(const PlatformThreadRef& a, const PlatformThreadRef& b) { 50 bool IsThreadRefEqual(const PlatformThreadRef& a, const PlatformThreadRef& b) {
53 #if defined(WEBRTC_WIN) 51 #if defined(WEBRTC_WIN)
54 return a == b; 52 return a == b;
55 #elif defined(WEBRTC_POSIX) 53 #elif defined(WEBRTC_POSIX)
56 return pthread_equal(a, b); 54 return pthread_equal(a, b);
57 #endif 55 #endif
58 } 56 }
59 57
60 void SetCurrentThreadName(const char* name) { 58 void SetCurrentThreadName(const char* name) {
61 RTC_DCHECK(strlen(name) < 64);
62 #if defined(WEBRTC_WIN) 59 #if defined(WEBRTC_WIN)
63 struct { 60 struct {
64 DWORD dwType; 61 DWORD dwType;
65 LPCSTR szName; 62 LPCSTR szName;
66 DWORD dwThreadID; 63 DWORD dwThreadID;
67 DWORD dwFlags; 64 DWORD dwFlags;
68 } threadname_info = {0x1000, name, static_cast<DWORD>(-1), 0}; 65 } threadname_info = {0x1000, name, static_cast<DWORD>(-1), 0};
69 66
70 __try { 67 __try {
71 ::RaiseException(0x406D1388, 0, sizeof(threadname_info) / sizeof(DWORD), 68 ::RaiseException(0x406D1388, 0, sizeof(threadname_info) / sizeof(DWORD),
72 reinterpret_cast<ULONG_PTR*>(&threadname_info)); 69 reinterpret_cast<ULONG_PTR*>(&threadname_info));
73 } __except (EXCEPTION_EXECUTE_HANDLER) { 70 } __except (EXCEPTION_EXECUTE_HANDLER) {
74 } 71 }
75 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) 72 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID)
76 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name)); 73 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name));
77 #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS) 74 #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
78 pthread_setname_np(name); 75 pthread_setname_np(name);
79 #endif 76 #endif
80 } 77 }
81 78
82 } // namespace rtc 79 } // namespace rtc
80
81 namespace webrtc {
82
83 rtc::scoped_ptr<PlatformThread> PlatformThread::CreateThread(
84 ThreadRunFunction func,
85 void* obj,
86 const char* thread_name) {
87 return rtc::scoped_ptr<PlatformThread>(
88 new PlatformThread(func, obj, thread_name));
89 }
90
91 namespace {
92 #if defined(WEBRTC_WIN)
93 void CALLBACK RaiseFlag(ULONG_PTR param) {
94 *reinterpret_cast<bool*>(param) = true;
95 }
96 #else
97 struct ThreadAttributes {
98 ThreadAttributes() { pthread_attr_init(&attr); }
99 ~ThreadAttributes() { pthread_attr_destroy(&attr); }
100 pthread_attr_t* operator&() { return &attr; }
101 pthread_attr_t attr;
102 };
103
104 int ConvertToSystemPriority(ThreadPriority priority,
105 int min_prio,
106 int max_prio) {
107 RTC_DCHECK(max_prio - min_prio > 2);
108 const int top_prio = max_prio - 1;
109 const int low_prio = min_prio + 1;
110
111 switch (priority) {
112 case kLowPriority:
113 return low_prio;
114 case kNormalPriority:
115 // The -1 ensures that the kHighPriority is always greater or equal to
116 // kNormalPriority.
117 return (low_prio + top_prio - 1) / 2;
118 case kHighPriority:
119 return std::max(top_prio - 2, low_prio);
120 case kHighestPriority:
121 return std::max(top_prio - 1, low_prio);
122 case kRealtimePriority:
123 return top_prio;
124 }
125 RTC_DCHECK(false);
126 return low_prio;
127 }
128 #endif // defined(WEBRTC_WIN)
129 }
130
131 PlatformThread::PlatformThread(ThreadRunFunction func,
132 void* obj,
133 const char* thread_name)
134 : run_function_(func),
135 obj_(obj),
136 name_(thread_name ? thread_name : "webrtc"),
137 #if defined(WEBRTC_WIN)
138 stop_(false),
139 thread_(NULL) {
140 #else
141 stop_event_(false, false),
142 thread_(0) {
143 #endif // defined(WEBRTC_WIN)
144 RTC_DCHECK(func);
145 RTC_DCHECK(name_.length() < 64);
146 }
147
148 PlatformThread::~PlatformThread() {
149 RTC_DCHECK(thread_checker_.CalledOnValidThread());
150 #if defined(WEBRTC_WIN)
151 RTC_DCHECK(!thread_);
152 #endif // defined(WEBRTC_WIN)
153 }
154
155 #if defined(WEBRTC_WIN)
156 DWORD WINAPI PlatformThread::StartThread(void* param) {
157 static_cast<PlatformThread*>(param)->Run();
158 return 0;
159 }
160 #else
161 void* PlatformThread::StartThread(void* param) {
162 static_cast<PlatformThread*>(param)->Run();
163 return 0;
164 }
165 #endif // defined(WEBRTC_WIN)
166
167 bool PlatformThread::Start() {
168 RTC_DCHECK(thread_checker_.CalledOnValidThread());
169 RTC_DCHECK(!thread_) << "Thread already started?";
170 #if defined(WEBRTC_WIN)
171 stop_ = false;
172
173 // See bug 2902 for background on STACK_SIZE_PARAM_IS_A_RESERVATION.
174 // Set the reserved stack stack size to 1M, which is the default on Windows
175 // and Linux.
176 DWORD thread_id;
177 thread_ = ::CreateThread(NULL, 1024 * 1024, &StartThread, this,
178 STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id);
179 RTC_CHECK(thread_) << "CreateThread failed";
180 #else
181 ThreadAttributes attr;
182 // Set the stack stack size to 1M.
183 pthread_attr_setstacksize(&attr, 1024 * 1024);
184 RTC_CHECK_EQ(0, pthread_create(&thread_, &attr, &StartThread, this));
185 #endif // defined(WEBRTC_WIN)
186 return true;
187 }
188
189 bool PlatformThread::Stop() {
190 RTC_DCHECK(thread_checker_.CalledOnValidThread());
191 #if defined(WEBRTC_WIN)
192 if (thread_) {
193 // Set stop_ to |true| on the worker thread.
194 QueueUserAPC(&RaiseFlag, thread_, reinterpret_cast<ULONG_PTR>(&stop_));
195 WaitForSingleObject(thread_, INFINITE);
196 CloseHandle(thread_);
197 thread_ = nullptr;
198 }
199 #else
200 if (!thread_)
201 return true;
202
203 stop_event_.Set();
204 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr));
205 thread_ = 0;
206 #endif // defined(WEBRTC_WIN)
207 return true;
208 }
209
210 void PlatformThread::Run() {
211 if (!name_.empty())
212 rtc::SetCurrentThreadName(name_.c_str());
213 do {
214 // The interface contract of Start/Stop is that for a successfull call to
215 // Start, there should be at least one call to the run function. So we
216 // call the function before checking |stop_|.
217 if (!run_function_(obj_))
218 break;
219 #if defined(WEBRTC_WIN)
220 // Alertable sleep to permit RaiseFlag to run and update |stop_|.
221 SleepEx(0, true);
222 } while (!stop_);
223 #else
224 } while (!stop_event_.Wait(0));
225 #endif // defined(WEBRTC_WIN)
226 }
227
228 bool PlatformThread::SetPriority(ThreadPriority priority) {
229 RTC_DCHECK(thread_checker_.CalledOnValidThread());
230 #if defined(WEBRTC_WIN)
231 return thread_ && SetThreadPriority(thread_, priority);
232 #else
233 if (!thread_)
234 return false;
235 #if defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX)
236 // TODO(tommi): Switch to the same mechanism as Chromium uses for
237 // changing thread priorities.
238 return true;
239 #else
240 #ifdef WEBRTC_THREAD_RR
241 const int policy = SCHED_RR;
242 #else
243 const int policy = SCHED_FIFO;
244 #endif
245 const int min_prio = sched_get_priority_min(policy);
246 const int max_prio = sched_get_priority_max(policy);
247 if (min_prio == -1 || max_prio == -1) {
248 return false;
249 }
250
251 if (max_prio - min_prio <= 2)
252 return false;
253
254 sched_param param;
255 param.sched_priority = ConvertToSystemPriority(priority, min_prio, max_prio);
256 if (pthread_setschedparam(thread_, policy, &param) != 0) {
257 return false;
258 }
259
260 return true;
261 #endif // defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX)
262 #endif // defined(WEBRTC_WIN)
263 }
264
265 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/base/platform_thread.h ('k') | webrtc/base/platform_thread_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698