Bug 1371079 - Use PRThread for IPC thread safety checking (r=dvander)
authorBill McCloskey <billm@mozilla.com>
Thu, 25 May 2017 16:51:31 -0700
changeset 412327 34adc718cf1f
parent 412326 894903d30183
child 412328 ccc624eb77e1
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs1371079
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1371079 - Use PRThread for IPC thread safety checking (r=dvander) MozReview-Commit-ID: 9qRiC43LuVP
ipc/glue/MessageChannel.cpp
ipc/glue/MessageChannel.h
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -516,17 +516,17 @@ MessageChannel::MessageChannel(const cha
                                IToplevelProtocol *aListener)
   : mName(aName),
     mListener(aListener),
     mChannelState(ChannelClosed),
     mSide(UnknownSide),
     mLink(nullptr),
     mWorkerLoop(nullptr),
     mChannelErrorTask(nullptr),
-    mWorkerLoopID(-1),
+    mWorkerThread(nullptr),
     mTimeoutMs(kNoTimeout),
     mInTimeoutSecondHalf(false),
     mNextSeqno(0),
     mLastSendError(SyncSendError::SendSuccess),
     mDispatchingAsyncMessage(false),
     mDispatchingAsyncMessageNestedLevel(0),
     mTransactionStack(nullptr),
     mTimedOutMessageSeqno(0),
@@ -684,17 +684,17 @@ MessageChannel::WillDestroyCurrentMessag
 #endif
     MOZ_CRASH("MessageLoop destroyed before MessageChannel that's bound to it");
 #endif
 }
 
 void
 MessageChannel::Clear()
 {
-    // Don't clear mWorkerLoopID; we use it in AssertLinkThread() and
+    // Don't clear mWorkerThread; we use it in AssertLinkThread() and
     // AssertWorkerThread().
     //
     // Also don't clear mListener.  If we clear it, then sending a message
     // through this channel after it's Clear()'ed can cause this process to
     // crash.
     //
     // In practice, mListener owns the channel, so the channel gets deleted
     // before mListener.  But just to be safe, mListener is a weak pointer.
@@ -769,17 +769,17 @@ private:
 
 bool
 MessageChannel::Open(Transport* aTransport, MessageLoop* aIOLoop, Side aSide)
 {
     NS_PRECONDITION(!mLink, "Open() called > once");
 
     mMonitor = new RefCountedMonitor();
     mWorkerLoop = MessageLoop::current();
-    mWorkerLoopID = mWorkerLoop->id();
+    mWorkerThread = GetCurrentVirtualThread();
     mWorkerLoop->AddDestructionObserver(this);
     mListener->SetIsMainThreadProtocol();
 
     if (!AbstractThread::GetCurrent()) {
         mWorkerLoop->AddDestructionObserver(
             new AbstractThreadWrapperCleanup(
                 MessageLoopAbstractThreadWrapper::Create(mWorkerLoop)));
     }
@@ -855,17 +855,17 @@ MessageChannel::OnOpenAsSlave(MessageCha
     aTargetChan->mChannelState = ChannelConnected;
     aTargetChan->mMonitor->Notify();
 }
 
 void
 MessageChannel::CommonThreadOpenInit(MessageChannel *aTargetChan, Side aSide)
 {
     mWorkerLoop = MessageLoop::current();
-    mWorkerLoopID = mWorkerLoop->id();
+    mWorkerThread = GetCurrentVirtualThread();
     mWorkerLoop->AddDestructionObserver(this);
     mListener->SetIsMainThreadProtocol();
 
     if (!AbstractThread::GetCurrent()) {
         mWorkerLoop->AddDestructionObserver(
             new AbstractThreadWrapperCleanup(
                 MessageLoopAbstractThreadWrapper::Create(mWorkerLoop)));
     }
--- a/ipc/glue/MessageChannel.h
+++ b/ipc/glue/MessageChannel.h
@@ -21,16 +21,17 @@
 #include "mozilla/ipc/Neutering.h"
 #endif // defined(OS_WIN)
 #include "mozilla/ipc/Transport.h"
 #if defined(MOZ_CRASHREPORTER) && defined(OS_WIN)
 #include "mozilla/mozalloc_oom.h"
 #include "nsExceptionHandler.h"
 #endif
 #include "MessageLink.h"
+#include "nsThreadUtils.h"
 
 #include <deque>
 #include <functional>
 #include <map>
 #include <math.h>
 #include <stack>
 
 namespace mozilla {
@@ -500,28 +501,28 @@ class MessageChannel : HasResultCodes, M
     // Run on the not current thread.
     void NotifyChannelClosed();
     void NotifyMaybeChannelError();
 
   private:
     // Can be run on either thread
     void AssertWorkerThread() const
     {
-        MOZ_ASSERT(mWorkerLoopID != -1, "Channel hasn't been opened yet");
-        MOZ_RELEASE_ASSERT(mWorkerLoopID == MessageLoop::current()->id(),
+        MOZ_ASSERT(mWorkerThread, "Channel hasn't been opened yet");
+        MOZ_RELEASE_ASSERT(mWorkerThread == GetCurrentVirtualThread(),
                            "not on worker thread!");
     }
 
     // The "link" thread is either the I/O thread (ProcessLink) or the
     // other actor's work thread (ThreadLink).  In either case, it is
     // NOT our worker thread.
     void AssertLinkThread() const
     {
-        MOZ_ASSERT(mWorkerLoopID != -1, "Channel hasn't been opened yet");
-        MOZ_RELEASE_ASSERT(mWorkerLoopID != MessageLoop::current()->id(),
+        MOZ_ASSERT(mWorkerThread, "Channel hasn't been opened yet");
+        MOZ_RELEASE_ASSERT(mWorkerThread != GetCurrentVirtualThread(),
                            "on worker thread but should not be!");
     }
 
   private:
     class MessageTask :
         public CancelableRunnable,
         public LinkedListElement<RefPtr<MessageTask>>,
         public nsIRunnablePriority
@@ -571,19 +572,19 @@ class MessageChannel : HasResultCodes, M
     IToplevelProtocol* mListener;
     ChannelState mChannelState;
     RefPtr<RefCountedMonitor> mMonitor;
     Side mSide;
     MessageLink* mLink;
     MessageLoop* mWorkerLoop;           // thread where work is done
     RefPtr<CancelableRunnable> mChannelErrorTask;  // NotifyMaybeChannelError runnable
 
-    // id() of mWorkerLoop.  This persists even after mWorkerLoop is cleared
-    // during channel shutdown.
-    int mWorkerLoopID;
+    // Thread we are allowed to send and receive on. This persists even after
+    // mWorkerLoop is cleared during channel shutdown.
+    PRThread* mWorkerThread;
 
     // Timeout periods are broken up in two to prevent system suspension from
     // triggering an abort. This method (called by WaitForEvent with a 'did
     // timeout' flag) decides if we should wait again for half of mTimeoutMs
     // or give up.
     int32_t mTimeoutMs;
     bool mInTimeoutSecondHalf;