Bug 836523 - Protect mCurrentTaskIsCanceled by lock. r=qdot, r=echou
authorThomas Zimmermann <tdz@users.sourceforge.net>
Tue, 12 Feb 2013 09:16:45 -0500
changeset 131508 89edfdd1a350f85a3f1d2b427c8d6e735a4a95e7
parent 131507 702007f2f745c79fd5b8c78d03f8a0e8db14bc40
child 131509 4251e6dd02180f830a61dab98eed7451d9cb4749
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot, echou
bugs836523
milestone21.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 836523 - Protect mCurrentTaskIsCanceled by lock. r=qdot, r=echou The main thread and the I/O thread concurrently access the field mCurrentTaskIsCanceled in UnixSocketImpl. Protect it by a lock.
ipc/unixsocket/UnixSocket.cpp
--- a/ipc/unixsocket/UnixSocket.cpp
+++ b/ipc/unixsocket/UnixSocket.cpp
@@ -47,16 +47,17 @@ public:
                  const nsACString& aAddress)
     : mConsumer(aConsumer)
     , mIOLoop(nullptr)
     , mFd(-1)
     , mConnector(aConnector)
     , mCurrentTaskIsCanceled(false)
     , mTask(nullptr)
     , mAddress(aAddress)
+    , mLock("UnixSocketImpl.mLock")
   {
   }
 
   ~UnixSocketImpl()
   {
     StopTask();
     mReadWatcher.StopWatchingFileDescriptor();
     mWriteWatcher.StopWatchingFileDescriptor();
@@ -75,35 +76,42 @@ public:
 
   void CancelTask()
   {
     if (!mTask) {
       return;
     }
     mTask->Cancel();
     mTask = nullptr;
+    MutexAutoLock lock(mLock);
     mCurrentTaskIsCanceled = true;
   }
   
+  bool IsCanceled()
+  {
+    MutexAutoLock lock(mLock);
+    return mCurrentTaskIsCanceled;
+  }
+
   void UnsetTask()
   {
     mTask = nullptr;
   }
 
   void EnqueueTask(int aDelayMs, CancelableTask* aTask)
   {
     MessageLoopForIO* ioLoop = MessageLoopForIO::current();
     if (!ioLoop) {
       NS_WARNING("No IOLoop to attach to, cancelling self!");
       return;
     }
     if (mTask) {
       return;
     }
-    if (mCurrentTaskIsCanceled) {
+    if (IsCanceled()) {
       return;
     }
     mTask = aTask;
     if (aDelayMs) {
       ioLoop->PostDelayedTask(FROM_HERE, mTask, aDelayMs);
     } else {
       ioLoop->PostTask(FROM_HERE, mTask);
     }
@@ -139,16 +147,17 @@ public:
    * Stop whatever connect/accept task is running
    */
   void StopTask()
   {
     if (mTask) {
       mTask->Cancel();
       mTask = nullptr;
     }
+    MutexAutoLock lock(mLock);
     mCurrentTaskIsCanceled = true;
   }
 
   /** 
    * Set up nonblocking flags on whatever our current file descriptor is.
    *
    * @return true if successful, false otherwise
    */
@@ -247,16 +256,20 @@ private:
    */
   socklen_t mAddrSize;
 
   /**
    * Address struct of the socket currently in use
    */
   sockaddr mAddr;
 
+  /**
+   * Protects mCurrentTaskIsCanceled
+   */
+  mozilla::Mutex mLock;
 };
 
 template<class T>
 class DeleteInstanceRunnable : public nsRunnable
 {
 public:
   DeleteInstanceRunnable(T* aInstance)
   : mInstance(aInstance)