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 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 reinterpret_cast<ULONG_PTR*>(&threadname_info)); | 69 reinterpret_cast<ULONG_PTR*>(&threadname_info)); |
70 } __except (EXCEPTION_EXECUTE_HANDLER) { | 70 } __except (EXCEPTION_EXECUTE_HANDLER) { |
71 } | 71 } |
72 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) | 72 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) |
73 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name)); | 73 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name)); |
74 #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS) | 74 #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS) |
75 pthread_setname_np(name); | 75 pthread_setname_np(name); |
76 #endif | 76 #endif |
77 } | 77 } |
78 | 78 |
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 { | 79 namespace { |
92 #if defined(WEBRTC_WIN) | 80 #if defined(WEBRTC_WIN) |
93 void CALLBACK RaiseFlag(ULONG_PTR param) { | 81 void CALLBACK RaiseFlag(ULONG_PTR param) { |
94 *reinterpret_cast<bool*>(param) = true; | 82 *reinterpret_cast<bool*>(param) = true; |
95 } | 83 } |
96 #else | 84 #else |
97 struct ThreadAttributes { | 85 struct ThreadAttributes { |
98 ThreadAttributes() { pthread_attr_init(&attr); } | 86 ThreadAttributes() { pthread_attr_init(&attr); } |
99 ~ThreadAttributes() { pthread_attr_destroy(&attr); } | 87 ~ThreadAttributes() { pthread_attr_destroy(&attr); } |
100 pthread_attr_t* operator&() { return &attr; } | 88 pthread_attr_t* operator&() { return &attr; } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 static_cast<PlatformThread*>(param)->Run(); | 120 static_cast<PlatformThread*>(param)->Run(); |
133 return 0; | 121 return 0; |
134 } | 122 } |
135 #else | 123 #else |
136 void* PlatformThread::StartThread(void* param) { | 124 void* PlatformThread::StartThread(void* param) { |
137 static_cast<PlatformThread*>(param)->Run(); | 125 static_cast<PlatformThread*>(param)->Run(); |
138 return 0; | 126 return 0; |
139 } | 127 } |
140 #endif // defined(WEBRTC_WIN) | 128 #endif // defined(WEBRTC_WIN) |
141 | 129 |
142 bool PlatformThread::Start() { | 130 void PlatformThread::Start() { |
143 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 131 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
144 RTC_DCHECK(!thread_) << "Thread already started?"; | 132 RTC_DCHECK(!thread_) << "Thread already started?"; |
145 #if defined(WEBRTC_WIN) | 133 #if defined(WEBRTC_WIN) |
146 stop_ = false; | 134 stop_ = false; |
147 | 135 |
148 // See bug 2902 for background on STACK_SIZE_PARAM_IS_A_RESERVATION. | 136 // See bug 2902 for background on STACK_SIZE_PARAM_IS_A_RESERVATION. |
149 // Set the reserved stack stack size to 1M, which is the default on Windows | 137 // Set the reserved stack stack size to 1M, which is the default on Windows |
150 // and Linux. | 138 // and Linux. |
151 DWORD thread_id; | 139 DWORD thread_id; |
152 thread_ = ::CreateThread(NULL, 1024 * 1024, &StartThread, this, | 140 thread_ = ::CreateThread(NULL, 1024 * 1024, &StartThread, this, |
153 STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id); | 141 STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id); |
154 RTC_CHECK(thread_) << "CreateThread failed"; | 142 RTC_CHECK(thread_) << "CreateThread failed"; |
155 #else | 143 #else |
156 ThreadAttributes attr; | 144 ThreadAttributes attr; |
157 // Set the stack stack size to 1M. | 145 // Set the stack stack size to 1M. |
158 pthread_attr_setstacksize(&attr, 1024 * 1024); | 146 pthread_attr_setstacksize(&attr, 1024 * 1024); |
159 RTC_CHECK_EQ(0, pthread_create(&thread_, &attr, &StartThread, this)); | 147 RTC_CHECK_EQ(0, pthread_create(&thread_, &attr, &StartThread, this)); |
160 #endif // defined(WEBRTC_WIN) | 148 #endif // defined(WEBRTC_WIN) |
161 return true; | |
162 } | 149 } |
163 | 150 |
164 bool PlatformThread::Stop() { | 151 bool PlatformThread::IsRunning() const { |
165 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 152 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
166 #if defined(WEBRTC_WIN) | 153 #if defined(WEBRTC_WIN) |
167 if (thread_) { | 154 return thread_ != nullptr; |
168 // Set stop_ to |true| on the worker thread. | |
169 QueueUserAPC(&RaiseFlag, thread_, reinterpret_cast<ULONG_PTR>(&stop_)); | |
170 WaitForSingleObject(thread_, INFINITE); | |
171 CloseHandle(thread_); | |
172 thread_ = nullptr; | |
173 } | |
174 #else | 155 #else |
175 if (!thread_) | 156 return thread_ != 0; |
176 return true; | 157 #endif // defined(WEBRTC_WIN) |
158 } | |
177 | 159 |
160 void PlatformThread::Stop() { | |
161 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
162 if (!IsRunning()) | |
163 return; | |
164 | |
165 #if defined(WEBRTC_WIN) | |
166 // Set stop_ to |true| on the worker thread. | |
167 QueueUserAPC(&RaiseFlag, thread_, reinterpret_cast<ULONG_PTR>(&stop_)); | |
168 WaitForSingleObject(thread_, INFINITE); | |
169 CloseHandle(thread_); | |
170 thread_ = nullptr; | |
171 #else | |
178 stop_event_.Set(); | 172 stop_event_.Set(); |
179 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); | 173 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); |
180 thread_ = 0; | 174 thread_ = 0; |
181 #endif // defined(WEBRTC_WIN) | 175 #endif // defined(WEBRTC_WIN) |
182 return true; | |
183 } | 176 } |
184 | 177 |
185 void PlatformThread::Run() { | 178 void PlatformThread::Run() { |
186 if (!name_.empty()) | 179 if (!name_.empty()) |
187 rtc::SetCurrentThreadName(name_.c_str()); | 180 rtc::SetCurrentThreadName(name_.c_str()); |
188 do { | 181 do { |
189 // The interface contract of Start/Stop is that for a successfull call to | 182 // The interface contract of Start/Stop is that for a successfull call to |
190 // Start, there should be at least one call to the run function. So we | 183 // Start, there should be at least one call to the run function. So we |
191 // call the function before checking |stop_|. | 184 // call the function before checking |stop_|. |
192 if (!run_function_(obj_)) | 185 if (!run_function_(obj_)) |
193 break; | 186 break; |
194 #if defined(WEBRTC_WIN) | 187 #if defined(WEBRTC_WIN) |
195 // Alertable sleep to permit RaiseFlag to run and update |stop_|. | 188 // Alertable sleep to permit RaiseFlag to run and update |stop_|. |
196 SleepEx(0, true); | 189 SleepEx(0, true); |
197 } while (!stop_); | 190 } while (!stop_); |
198 #else | 191 #else |
199 } while (!stop_event_.Wait(0)); | 192 } while (!stop_event_.Wait(0)); |
200 #endif // defined(WEBRTC_WIN) | 193 #endif // defined(WEBRTC_WIN) |
201 } | 194 } |
202 | 195 |
203 bool PlatformThread::SetPriority(ThreadPriority priority) { | 196 bool PlatformThread::SetPriority(ThreadPriority priority) { |
204 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 197 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
198 if (!IsRunning()) | |
tommi
2015/11/26 16:26:45
nit: this isn't needed. E.g. SetThreadPriority ha
pbos-webrtc
2015/11/26 16:43:03
Turned into a DCHECK. All compiling code uses Star
| |
199 return false; | |
205 #if defined(WEBRTC_WIN) | 200 #if defined(WEBRTC_WIN) |
206 return thread_ && SetThreadPriority(thread_, priority); | 201 return SetThreadPriority(thread_, priority) != FALSE; |
207 #elif defined(__native_client__) | 202 #elif defined(__native_client__) |
208 // Setting thread priorities is not supported in NaCl. | 203 // Setting thread priorities is not supported in NaCl. |
209 return true; | 204 return true; |
210 #elif defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX) | 205 #elif defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX) |
211 // TODO(tommi): Switch to the same mechanism as Chromium uses for changing | 206 // TODO(tommi): Switch to the same mechanism as Chromium uses for changing |
212 // thread priorities. | 207 // thread priorities. |
213 return true; | 208 return true; |
214 #else | 209 #else |
215 if (!thread_) | |
216 return false; | |
217 #ifdef WEBRTC_THREAD_RR | 210 #ifdef WEBRTC_THREAD_RR |
218 const int policy = SCHED_RR; | 211 const int policy = SCHED_RR; |
219 #else | 212 #else |
220 const int policy = SCHED_FIFO; | 213 const int policy = SCHED_FIFO; |
221 #endif | 214 #endif |
222 const int min_prio = sched_get_priority_min(policy); | 215 const int min_prio = sched_get_priority_min(policy); |
223 const int max_prio = sched_get_priority_max(policy); | 216 const int max_prio = sched_get_priority_max(policy); |
224 if (min_prio == -1 || max_prio == -1) { | 217 if (min_prio == -1 || max_prio == -1) { |
225 return false; | 218 return false; |
226 } | 219 } |
(...skipping 21 matching lines...) Expand all Loading... | |
248 param.sched_priority = std::max(top_prio - 1, low_prio); | 241 param.sched_priority = std::max(top_prio - 1, low_prio); |
249 break; | 242 break; |
250 case kRealtimePriority: | 243 case kRealtimePriority: |
251 param.sched_priority = top_prio; | 244 param.sched_priority = top_prio; |
252 break; | 245 break; |
253 } | 246 } |
254 return pthread_setschedparam(thread_, policy, ¶m) == 0; | 247 return pthread_setschedparam(thread_, policy, ¶m) == 0; |
255 #endif // defined(WEBRTC_WIN) | 248 #endif // defined(WEBRTC_WIN) |
256 } | 249 } |
257 | 250 |
258 } // namespace webrtc | 251 } // namespace rtc |
OLD | NEW |