Update PlatformThread to support a couple of new properties.
- name(): Returns the name of the thread (useful for debugging).
- GetThreadRef(): Returns the ID of the worker thread (also useful for debugging).
- QueueApc(): This is a Windows-only, protected function that allows derived classes on Windows to queue APCs to the worker thread.

NOTRY=true
(using notry since the patch has already passed the trybots and the cq is currently stalled)

Review URL: https://codereview.webrtc.org/1908373002

Cr-Commit-Position: refs/heads/master@{#12472}
diff --git a/webrtc/base/platform_thread.cc b/webrtc/base/platform_thread.cc
index b6fd873..286bee9 100644
--- a/webrtc/base/platform_thread.cc
+++ b/webrtc/base/platform_thread.cc
@@ -99,7 +99,8 @@
       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 @@
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
 #if defined(WEBRTC_WIN)
   RTC_DCHECK(!thread_);
+  RTC_DCHECK(!thread_id_);
 #endif  // defined(WEBRTC_WIN)
 }
 
@@ -136,10 +138,10 @@
   // 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 @@
 #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 @@
 
 #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 @@
 #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