Index: webrtc/base/platform_thread.cc |
diff --git a/webrtc/base/platform_thread.cc b/webrtc/base/platform_thread.cc |
index b6fd8732aaab343e5b1d9c1cacdb563d7fff6108..286bee95f1299823920ec03175962dbf61e9cba8 100644 |
--- a/webrtc/base/platform_thread.cc |
+++ b/webrtc/base/platform_thread.cc |
@@ -99,7 +99,8 @@ PlatformThread::PlatformThread(ThreadRunFunction func, |
name_(thread_name ? thread_name : "webrtc"), |
#if defined(WEBRTC_WIN) |
stop_(false), |
- thread_(NULL) { |
+ thread_(NULL), |
+ thread_id_(0) { |
#else |
stop_event_(false, false), |
thread_(0) { |
@@ -112,6 +113,7 @@ PlatformThread::~PlatformThread() { |
RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
#if defined(WEBRTC_WIN) |
RTC_DCHECK(!thread_); |
+ RTC_DCHECK(!thread_id_); |
#endif // defined(WEBRTC_WIN) |
} |
@@ -136,10 +138,10 @@ void PlatformThread::Start() { |
// See bug 2902 for background on STACK_SIZE_PARAM_IS_A_RESERVATION. |
// Set the reserved stack stack size to 1M, which is the default on Windows |
// and Linux. |
- DWORD thread_id; |
thread_ = ::CreateThread(NULL, 1024 * 1024, &StartThread, this, |
- STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id); |
+ STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id_); |
RTC_CHECK(thread_) << "CreateThread failed"; |
+ RTC_DCHECK(thread_id_); |
#else |
ThreadAttributes attr; |
// Set the stack stack size to 1M. |
@@ -157,6 +159,14 @@ bool PlatformThread::IsRunning() const { |
#endif // defined(WEBRTC_WIN) |
} |
+PlatformThreadRef PlatformThread::GetThreadRef() const { |
+#if defined(WEBRTC_WIN) |
+ return thread_id_; |
+#else |
+ return thread_; |
+#endif // defined(WEBRTC_WIN) |
+} |
+ |
void PlatformThread::Stop() { |
RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
if (!IsRunning()) |
@@ -164,10 +174,13 @@ void PlatformThread::Stop() { |
#if defined(WEBRTC_WIN) |
// Set stop_ to |true| on the worker thread. |
- QueueUserAPC(&RaiseFlag, thread_, reinterpret_cast<ULONG_PTR>(&stop_)); |
+ bool queued = QueueAPC(&RaiseFlag, reinterpret_cast<ULONG_PTR>(&stop_)); |
+ // Queuing the APC can fail if the thread is being terminated. |
+ RTC_CHECK(queued || GetLastError() == ERROR_GEN_FAILURE); |
WaitForSingleObject(thread_, INFINITE); |
CloseHandle(thread_); |
thread_ = nullptr; |
+ thread_id_ = 0; |
#else |
stop_event_.Set(); |
RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); |
@@ -247,4 +260,13 @@ bool PlatformThread::SetPriority(ThreadPriority priority) { |
#endif // defined(WEBRTC_WIN) |
} |
+#if defined(WEBRTC_WIN) |
+bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) { |
+ RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
+ RTC_DCHECK(IsRunning()); |
+ |
+ return QueueUserAPC(function, thread_, data) != FALSE; |
+} |
+#endif |
+ |
} // namespace rtc |