 Chromium Code Reviews
 Chromium Code Reviews Issue 1469013002:
  Move ThreadWrapper to ProcessThread in base.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1469013002:
  Move ThreadWrapper to ProcessThread in base.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| OLD | NEW | 
|---|---|
| 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> | 13 #include <string.h> | 
| 14 | 14 | 
| 15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" | 
| 16 #include "webrtc/base/thread_checker.h" | |
| 16 | 17 | 
| 17 #if defined(WEBRTC_LINUX) | 18 #if defined(WEBRTC_LINUX) | 
| 18 #include <sys/prctl.h> | 19 #include <sys/prctl.h> | 
| 19 #include <sys/syscall.h> | 20 #include <sys/syscall.h> | 
| 20 #endif | 21 #endif | 
| 21 | 22 | 
| 22 namespace rtc { | 23 namespace rtc { | 
| 23 | 24 | 
| 24 PlatformThreadId CurrentThreadId() { | 25 PlatformThreadId CurrentThreadId() { | 
| 25 PlatformThreadId ret; | 26 PlatformThreadId ret; | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 } __except (EXCEPTION_EXECUTE_HANDLER) { | 74 } __except (EXCEPTION_EXECUTE_HANDLER) { | 
| 74 } | 75 } | 
| 75 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) | 76 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) | 
| 76 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name)); | 77 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name)); | 
| 77 #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS) | 78 #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS) | 
| 78 pthread_setname_np(name); | 79 pthread_setname_np(name); | 
| 79 #endif | 80 #endif | 
| 80 } | 81 } | 
| 81 | 82 | 
| 82 } // namespace rtc | 83 } // namespace rtc | 
| 84 | |
| 85 namespace webrtc { | |
| 86 | |
| 87 rtc::scoped_ptr<PlatformThread> PlatformThread::CreateThread( | |
| 88 ThreadRunFunction func, | |
| 89 void* obj, | |
| 90 const char* thread_name) { | |
| 91 return rtc::scoped_ptr<PlatformThread>( | |
| 92 new PlatformThread(func, obj, thread_name)) | |
| 93 .Pass(); | |
| 
tommi
2015/11/23 14:49:11
std::move?
 
pbos-webrtc
2015/11/23 15:05:40
Done.
 | |
| 94 } | |
| 95 | |
| 96 namespace { | |
| 97 #if defined(WEBRTC_WIN) | |
| 98 void CALLBACK RaiseFlag(ULONG_PTR param) { | |
| 99 *reinterpret_cast<bool*>(param) = true; | |
| 100 } | |
| 101 #else | |
| 102 struct ThreadAttributes { | |
| 103 ThreadAttributes() { pthread_attr_init(&attr); } | |
| 104 ~ThreadAttributes() { pthread_attr_destroy(&attr); } | |
| 105 pthread_attr_t* operator&() { return &attr; } | |
| 106 pthread_attr_t attr; | |
| 107 }; | |
| 108 #endif // defined(WEBRTC_WIN) | |
| 109 } | |
| 110 | |
| 111 #if defined(WEBRTC_POSIX) | |
| 112 int PlatformThread::ConvertToSystemPriority(ThreadPriority priority, | |
| 
tommi
2015/11/23 14:49:11
actually, I took a look at the test that calls thi
 
pbos-webrtc
2015/11/23 15:05:39
Deleted, nuked, gone, done (test is that is).
 | |
| 113 int min_prio, | |
| 114 int max_prio) { | |
| 115 RTC_DCHECK(max_prio - min_prio > 2); | |
| 116 const int top_prio = max_prio - 1; | |
| 117 const int low_prio = min_prio + 1; | |
| 118 | |
| 119 switch (priority) { | |
| 120 case kLowPriority: | |
| 121 return low_prio; | |
| 122 case kNormalPriority: | |
| 123 // The -1 ensures that the kHighPriority is always greater or equal to | |
| 124 // kNormalPriority. | |
| 125 return (low_prio + top_prio - 1) / 2; | |
| 126 case kHighPriority: | |
| 127 return std::max(top_prio - 2, low_prio); | |
| 128 case kHighestPriority: | |
| 129 return std::max(top_prio - 1, low_prio); | |
| 130 case kRealtimePriority: | |
| 131 return top_prio; | |
| 132 } | |
| 133 RTC_DCHECK(false); | |
| 134 return low_prio; | |
| 135 } | |
| 136 #endif // defined(WEBRTC_POSIX) | |
| 137 | |
| 138 PlatformThread::PlatformThread(ThreadRunFunction func, | |
| 139 void* obj, | |
| 140 const char* thread_name) | |
| 141 : run_function_(func), | |
| 142 obj_(obj), | |
| 143 name_(thread_name ? thread_name : "webrtc"), | |
| 144 thread_checker_(new rtc::ThreadChecker()), | |
| 145 #if defined(WEBRTC_WIN) | |
| 146 stop_(false), | |
| 147 thread_(NULL) { | |
| 148 #else | |
| 149 stop_event_(false, false), | |
| 150 thread_(0) { | |
| 151 #endif // defined(WEBRTC_WIN) | |
| 152 RTC_DCHECK(func); | |
| 153 RTC_DCHECK(name_.length() < 64); | |
| 154 } | |
| 155 | |
| 156 PlatformThread::~PlatformThread() { | |
| 157 RTC_DCHECK(thread_checker_->CalledOnValidThread()); | |
| 158 #if defined(WEBRTC_WIN) | |
| 159 RTC_DCHECK(!thread_); | |
| 160 #endif // defined(WEBRTC_WIN) | |
| 161 } | |
| 162 | |
| 163 uint32_t PlatformThread::GetThreadId() { | |
| 164 #if defined(WEBRTC_WIN) | |
| 165 return GetCurrentThreadId(); | |
| 166 #else | |
| 167 return rtc::CurrentThreadId(); | |
| 168 #endif // defined(WEBRTC_WIN) | |
| 169 } | |
| 170 | |
| 171 #if defined(WEBRTC_WIN) | |
| 172 DWORD WINAPI PlatformThread::StartThread(void* param) { | |
| 173 static_cast<PlatformThread*>(param)->Run(); | |
| 174 return 0; | |
| 175 } | |
| 176 #else | |
| 177 void* PlatformThread::StartThread(void* param) { | |
| 178 static_cast<PlatformThread*>(param)->Run(); | |
| 179 return 0; | |
| 180 } | |
| 181 #endif // defined(WEBRTC_WIN) | |
| 182 | |
| 183 bool PlatformThread::Start() { | |
| 184 RTC_DCHECK(thread_checker_->CalledOnValidThread()); | |
| 185 RTC_DCHECK(!thread_) << "Thread already started?"; | |
| 186 #if defined(WEBRTC_WIN) | |
| 187 stop_ = false; | |
| 188 | |
| 189 // See bug 2902 for background on STACK_SIZE_PARAM_IS_A_RESERVATION. | |
| 190 // Set the reserved stack stack size to 1M, which is the default on Windows | |
| 191 // and Linux. | |
| 192 DWORD thread_id; | |
| 193 thread_ = ::CreateThread(NULL, 1024 * 1024, &StartThread, this, | |
| 194 STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id); | |
| 195 RTC_CHECK(thread_) << "CreateThread failed"; | |
| 196 #else | |
| 197 ThreadAttributes attr; | |
| 198 // Set the stack stack size to 1M. | |
| 199 pthread_attr_setstacksize(&attr, 1024 * 1024); | |
| 200 RTC_CHECK_EQ(0, pthread_create(&thread_, &attr, &StartThread, this)); | |
| 201 #endif // defined(WEBRTC_WIN) | |
| 202 return true; | |
| 203 } | |
| 204 | |
| 205 bool PlatformThread::Stop() { | |
| 206 RTC_DCHECK(thread_checker_->CalledOnValidThread()); | |
| 207 #if defined(WEBRTC_WIN) | |
| 208 if (thread_) { | |
| 209 // Set stop_ to |true| on the worker thread. | |
| 210 QueueUserAPC(&RaiseFlag, thread_, reinterpret_cast<ULONG_PTR>(&stop_)); | |
| 211 WaitForSingleObject(thread_, INFINITE); | |
| 212 CloseHandle(thread_); | |
| 213 thread_ = nullptr; | |
| 214 } | |
| 215 #else | |
| 216 if (!thread_) | |
| 217 return true; | |
| 218 | |
| 219 stop_event_.Set(); | |
| 220 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); | |
| 221 thread_ = 0; | |
| 222 #endif // defined(WEBRTC_WIN) | |
| 223 return true; | |
| 224 } | |
| 225 | |
| 226 void PlatformThread::Run() { | |
| 227 if (!name_.empty()) | |
| 228 rtc::SetCurrentThreadName(name_.c_str()); | |
| 229 do { | |
| 230 // The interface contract of Start/Stop is that for a successfull call to | |
| 231 // Start, there should be at least one call to the run function. So we | |
| 232 // call the function before checking |stop_|. | |
| 233 if (!run_function_(obj_)) | |
| 234 break; | |
| 235 #if defined(WEBRTC_WIN) | |
| 236 // Alertable sleep to permit RaiseFlag to run and update |stop_|. | |
| 237 SleepEx(0, true); | |
| 238 } while (!stop_); | |
| 239 #else | |
| 240 } while (!stop_event_.Wait(0)); | |
| 241 #endif // defined(WEBRTC_WIN) | |
| 242 } | |
| 243 | |
| 244 bool PlatformThread::SetPriority(ThreadPriority priority) { | |
| 245 RTC_DCHECK(thread_checker_->CalledOnValidThread()); | |
| 246 #if defined(WEBRTC_WIN) | |
| 247 return thread_ && SetThreadPriority(thread_, priority); | |
| 248 #else | |
| 249 if (!thread_) | |
| 250 return false; | |
| 251 #if defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX) | |
| 252 // TODO(tommi): Switch to the same mechanism as Chromium uses for | |
| 253 // changing thread priorities. | |
| 254 return true; | |
| 255 #else | |
| 256 #ifdef WEBRTC_THREAD_RR | |
| 257 const int policy = SCHED_RR; | |
| 258 #else | |
| 259 const int policy = SCHED_FIFO; | |
| 260 #endif | |
| 261 const int min_prio = sched_get_priority_min(policy); | |
| 262 const int max_prio = sched_get_priority_max(policy); | |
| 263 if (min_prio == -1 || max_prio == -1) { | |
| 264 return false; | |
| 265 } | |
| 266 | |
| 267 if (max_prio - min_prio <= 2) | |
| 268 return false; | |
| 269 | |
| 270 sched_param param; | |
| 271 param.sched_priority = ConvertToSystemPriority(priority, min_prio, max_prio); | |
| 272 if (pthread_setschedparam(thread_, policy, ¶m) != 0) { | |
| 273 return false; | |
| 274 } | |
| 275 | |
| 276 return true; | |
| 277 #endif // defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX) | |
| 278 #endif // defined(WEBRTC_WIN) | |
| 279 } | |
| 280 | |
| 281 } // namespace webrtc | |
| OLD | NEW |