Bug 910962 - Make DeallocShmem not assert when child has crashed (r=bsmedberg)
authorBill McCloskey <wmccloskey@mozilla.com>
Fri, 31 Jan 2014 10:43:44 -0800
changeset 183396 fcb20c4c1ef87abbb81f96fa60908fa243edc05f
parent 183395 df85e7787732b1c262205c8cfe895f786a66899e
child 183397 f55a6150f6ee0df055ecf676b2cb4dc452a77a7f
push id462
push userraliiev@mozilla.com
push dateTue, 22 Apr 2014 00:22:30 +0000
treeherdermozilla-release@ac5db8c74ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs910962
milestone29.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 910962 - Make DeallocShmem not assert when child has crashed (r=bsmedberg)
CLOBBER
ipc/glue/MessageChannel.cpp
ipc/glue/MessageChannel.h
ipc/ipdl/ipdl/lower.py
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-bug 960811 - clobber to rebuild preprocessed files when enabling synthetic APKs
+Bug 925536 - Changing ipc/ipdl/ipdl/lower.py requires a clobber.
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -247,16 +247,23 @@ MessageChannel::Connected() const
 {
     mMonitor->AssertCurrentThreadOwns();
 
     // The transport layer allows us to send messages before
     // receiving the "connected" ack from the remote side.
     return (ChannelOpening == mChannelState || ChannelConnected == mChannelState);
 }
 
+bool
+MessageChannel::CanSend() const
+{
+    MonitorAutoLock lock(*mMonitor);
+    return Connected();
+}
+
 void
 MessageChannel::Clear()
 {
     // Don't clear mWorkerLoopID; 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
--- a/ipc/glue/MessageChannel.h
+++ b/ipc/glue/MessageChannel.h
@@ -89,16 +89,18 @@ class MessageChannel : HasResultCodes
     bool Echo(Message* aMsg);
 
     // Synchronously send |msg| (i.e., wait for |reply|)
     bool Send(Message* aMsg, Message* aReply);
 
     // Make an Interrupt call to the other side of the channel
     bool Call(Message* aMsg, Message* aReply);
 
+    bool CanSend() const;
+
     void SetReplyTimeoutMs(int32_t aTimeoutMs);
 
     bool IsOnCxxStack() const {
         return !mCxxStackFrames.empty();
     }
 
     void FlushPendingInterruptQueue();
 
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -3701,37 +3701,49 @@ class _GenerateProtocolActorCode(ipdl.as
             # bool DestroySharedMemory(shmem):
             #   id = shmem.Id()
             #   SharedMemory* rawmem = Lookup(id)
             #   if (!rawmem)
             #     return false;
             #   Message descriptor = UnShare(subprocess, mId, descriptor)
             #   mShmemMap.Remove(id)
             #   Shmem::Dealloc(rawmem)
+            #   if (!mChannel.CanSend()) {
+            #     delete descriptor;
+            #     return true;
+            #   }
             #   return descriptor && Send(descriptor)
             destroyshmem.addstmts([
                 StmtDecl(Decl(_shmemIdType(), idvar.name),
                          init=_shmemId(shmemvar)),
                 StmtDecl(Decl(_rawShmemType(ptr=1), rawvar.name),
                          init=_lookupShmem(idvar))
             ])
 
             failif = StmtIf(ExprNot(rawvar))
             failif.addifstmt(StmtReturn.FALSE)
+            cansend = ExprCall(ExprSelect(p.channelVar(), '.', 'CanSend'), [])
+            returnif = StmtIf(ExprNot(cansend))
+            returnif.addifstmts([
+                    StmtExpr(ExprDelete(descriptorvar)),
+                    StmtReturn.TRUE])
             destroyshmem.addstmts([
                 failif,
+                Whitespace.NL,
                 StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name),
                          init=_shmemUnshareFrom(
                              shmemvar,
                              p.callOtherProcess(),
                              p.routingId())),
                 Whitespace.NL,
                 StmtExpr(p.removeShmemId(idvar)),
                 StmtExpr(_shmemDealloc(rawvar)),
                 Whitespace.NL,
+                returnif,
+                Whitespace.NL,
                 StmtReturn(ExprBinary(
                     descriptorvar, '&&',
                     ExprCall(
                         ExprSelect(p.channelVar(), p.channelSel(), 'Send'),
                         args=[ descriptorvar ])))
             ])