Merge backout
authorChris Jones <jones.chris.g@gmail.com>
Thu, 11 Mar 2010 05:07:51 -0600
changeset 39276 e968afb45a8d912d3673fbdd47b4ddc6d93fdbb1
parent 39274 ae008deedbda235e4524b056566178ad004ffa58 (current diff)
parent 39275 f6d40b96a97869f3798dc989b93e3c180ca114da (diff)
child 39277 79443803350cb2fd207b82d1b9c84c7c29a45573
push id12111
push usercjones@mozilla.com
push dateThu, 11 Mar 2010 11:09:52 +0000
treeherdermozilla-central@e968afb45a8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a3pre
Merge backout
dom/plugins/PluginModuleParent.cpp
dom/plugins/PluginModuleParent.h
ipc/glue/RPCChannel.cpp
ipc/glue/RPCChannel.h
ipc/ipdl/ipdl/lower.py
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -65,16 +65,34 @@ PR_STATIC_ASSERT(sizeof(NPIdentifier) ==
 template<>
 struct RunnableMethodTraits<mozilla::plugins::PluginModuleParent>
 {
     typedef mozilla::plugins::PluginModuleParent Class;
     static void RetainCallee(Class* obj) { }
     static void ReleaseCallee(Class* obj) { }
 };
 
+class PluginCrashed : public nsRunnable
+{
+public:
+    PluginCrashed(nsNPAPIPlugin* plugin,
+                  const nsString& dumpID)
+        : mDumpID(dumpID),
+          mPlugin(plugin) { }
+
+    NS_IMETHOD Run() {
+        mPlugin->PluginCrashed(mDumpID);
+        return NS_OK;
+    }
+
+private:
+    nsNPAPIPlugin* mPlugin;
+    nsString mDumpID;
+};
+
 // static
 PluginLibrary*
 PluginModuleParent::LoadModule(const char* aFilePath)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
 
     // Block on the child process being launched and initialized.
     PluginModuleParent* parent = new PluginModuleParent(aFilePath);
@@ -89,36 +107,28 @@ PluginModuleParent::LoadModule(const cha
 
 
 PluginModuleParent::PluginModuleParent(const char* aFilePath)
     : mSubprocess(new PluginProcessParent(aFilePath))
     , mShutdown(false)
     , mNPNIface(NULL)
     , mPlugin(NULL)
     , mProcessStartTime(time(NULL))
-    , mPluginCrashedTask(NULL)
 {
     NS_ASSERTION(mSubprocess, "Out of memory!");
 
     if (!mValidIdentifiers.Init()) {
         NS_ERROR("Out of memory");
     }
 
     nsContentUtils::RegisterPrefCallback(kTimeoutPref, TimeoutChanged, this);
 }
 
 PluginModuleParent::~PluginModuleParent()
 {
-    NS_ASSERTION(OkToCleanup(), "unsafe destruction");
-
-    if (mPluginCrashedTask) {
-        mPluginCrashedTask->Cancel();
-        mPluginCrashedTask = 0;
-    }
-
     if (!mShutdown) {
         NS_WARNING("Plugin host deleted the module without shutting down.");
         NPError err;
         NP_Shutdown(&err);
     }
     NS_ASSERTION(mShutdown, "NP_Shutdown didn't");
 
     if (mSubprocess) {
@@ -254,64 +264,47 @@ PluginModuleParent::ShouldContinueFromRe
 }
 
 void
 PluginModuleParent::ActorDestroy(ActorDestroyReason why)
 {
     switch (why) {
     case AbnormalShutdown: {
         nsCOMPtr<nsIFile> dump;
+        nsAutoString dumpID;
         if (GetMinidump(getter_AddRefs(dump))) {
             WriteExtraDataForMinidump(dump);
-            if (NS_SUCCEEDED(dump->GetLeafName(mDumpID))) {
-                mDumpID.Replace(mDumpID.Length() - 4, 4,
-                                NS_LITERAL_STRING(""));
+            if (NS_SUCCEEDED(dump->GetLeafName(dumpID))) {
+                dumpID.Replace(dumpID.Length() - 4, 4,
+                               NS_LITERAL_STRING(""));
             }
         }
         else {
             NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
         }
 
         mShutdown = true;
         // Defer the PluginCrashed method so that we don't re-enter
         // and potentially modify the actor child list while enumerating it.
         if (mPlugin) {
-            mPluginCrashedTask = NewRunnableMethod(
-                this, &PluginModuleParent::NotifyPluginCrashed);
-            MessageLoop::current()->PostTask(FROM_HERE, mPluginCrashedTask);
+            nsCOMPtr<nsIRunnable> r =
+                new PluginCrashed(mPlugin, dumpID);
+            NS_DispatchToMainThread(r);
         }
         break;
     }
     case NormalShutdown:
         mShutdown = true;
         break;
 
     default:
         NS_ERROR("Unexpected shutdown reason for toplevel actor.");
     }
 }
 
-void
-PluginModuleParent::NotifyPluginCrashed()
-{
-    // MessageLoop owns this
-    mPluginCrashedTask = NULL;
-
-    if (!OkToCleanup()) {
-        // there's still plugin code on the C++ stack.  try again
-        mPluginCrashedTask = NewRunnableMethod(
-            this, &PluginModuleParent::NotifyPluginCrashed);
-        MessageLoop::current()->PostTask(FROM_HERE, mPluginCrashedTask);
-        return;
-    }
-
-    if (mPlugin)
-        mPlugin->PluginCrashed(mDumpID);
-}
-
 PPluginInstanceParent*
 PluginModuleParent::AllocPPluginInstance(const nsCString& aMimeType,
                                          const uint16_t& aMode,
                                          const nsTArray<nsCString>& aNames,
                                          const nsTArray<nsCString>& aValues,
                                          NPError* rv)
 {
     NS_ERROR("Not reachable!");
--- a/dom/plugins/PluginModuleParent.h
+++ b/dom/plugins/PluginModuleParent.h
@@ -115,20 +115,16 @@ public:
     const NPNetscapeFuncs* GetNetscapeFuncs() {
         return mNPNIface;
     }
 
     base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
 
     bool EnsureValidNPIdentifier(NPIdentifier aIdentifier);
 
-    bool OkToCleanup() const {
-        return !IsOnCxxStack();
-    }
-
 protected:
     NS_OVERRIDE
     virtual mozilla::ipc::RPCChannel::RacyRPCPolicy
     MediateRPCRace(const Message& parent, const Message& child)
     {
         return MediateRace(parent, child);
     }
 
@@ -234,25 +230,22 @@ private:
                              NPError* error);
 private:
     void WriteExtraDataForMinidump(nsIFile* dumpFile);
     void WriteExtraDataEntry(nsIFileOutputStream* stream,
                              const char* key,
                              const char* value);
     void CleanupFromTimeout();
     static int TimeoutChanged(const char* aPref, void* aModule);
-    void NotifyPluginCrashed();
 
     nsCString mCrashNotes;
     PluginProcessParent* mSubprocess;
     bool mShutdown;
     const NPNetscapeFuncs* mNPNIface;
     nsTHashtable<nsVoidPtrHashKey> mValidIdentifiers;
     nsNPAPIPlugin* mPlugin;
     time_t mProcessStartTime;
-    CancelableTask* mPluginCrashedTask;
-    nsString mDumpID;
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif  // ifndef dom_plugins_PluginModuleParent_h
--- a/ipc/glue/RPCChannel.cpp
+++ b/ipc/glue/RPCChannel.cpp
@@ -176,26 +176,16 @@ RPCChannel::Call(Message* msg, Message* 
     msg->set_rpc_local_stack_depth(1 + StackDepth());
     mStack.push(*msg);
 
     mIOLoop->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &RPCChannel::OnSend, msg));
 
     while (1) {
-        // if a handler invoked by *Dispatch*() spun a nested event
-        // loop, and the connection was broken during that loop, we
-        // might have already processed the OnError event. if so,
-        // trying another loop iteration will be futile because
-        // channel state will have been cleared
-        if (!Connected()) {
-            ReportConnectionError("RPCChannel");
-            return false;
-        }
-
         // now might be the time to process a message deferred because
         // of race resolution
         MaybeProcessDeferredIncall();
 
         // here we're waiting for something to happen. see long
         // comment about the queue in RPCChannel.h
         while (!EventOccurred()) {
             bool maybeTimedOut = !RPCChannel::WaitForNotify();
--- a/ipc/glue/RPCChannel.h
+++ b/ipc/glue/RPCChannel.h
@@ -129,21 +129,16 @@ public:
     //
     // It is an error to
     //  - call this on the child side of the channel
     //  - call this without a matching |BlockChild()|
     //
     // Return true iff successful.
     bool UnblockChild();
 
-    // Return true iff this has code on the C++ stack.
-    bool IsOnCxxStack() const {
-        return 0 < mCxxStackFrames;
-    }
-
     NS_OVERRIDE
     virtual bool OnSpecialMessage(uint16 id, const Message& msg);
 
     // Override the SyncChannel handler so we can dispatch RPC
     // messages.  Called on the IO thread only.
     NS_OVERRIDE
     virtual void OnMessageReceived(const Message& msg);
     NS_OVERRIDE
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1351,20 +1351,16 @@ class Protocol(ipdl.ast.Protocol):
     def enteredCxxStackVar(self):
         assert self.decl.type.isToplevel()
         return ExprVar('EnteredCxxStack')
 
     def exitedCxxStackVar(self):
         assert self.decl.type.isToplevel()
         return ExprVar('ExitedCxxStack')
 
-    def onCxxStackVar(self):
-        assert self.decl.type.isToplevel()
-        return ExprVar('IsOnCxxStack')
-
     def nextActorIdExpr(self, side):
         assert self.decl.type.isToplevel()
         if side is 'parent':   op = '++'
         elif side is 'child':  op = '--'
         else: assert 0
         return ExprPrefixUnop(self.lastActorIdVar(), op)
 
     def actorIdInit(self, side):
@@ -2875,33 +2871,25 @@ class _GenerateProtocolActorCode(ipdl.as
             else:
                 ontimeout.addstmts([
                     _runtimeAbort("`OnReplyTimeout' called on non-toplevel actor"),
                     StmtReturn(ExprLiteral.FALSE)
                 ])
 
             self.cls.addstmts([ ontimeout, Whitespace.NL ])
 
-        # C++-stack-related methods
+        # On[Entered/Exited]CxxStack()
         if ptype.isToplevel() and toplevel.talksRpc():
-            # OnEnteredCxxStack()
             onentered = MethodDefn(MethodDecl('OnEnteredCxxStack'))
             onentered.addstmt(StmtReturn(ExprCall(p.enteredCxxStackVar())))
 
-            # OnExitedCxxStack()
             onexited = MethodDefn(MethodDecl('OnExitedCxxStack'))
             onexited.addstmt(StmtReturn(ExprCall(p.exitedCxxStackVar())))
 
-            # bool IsOnCxxStack()
-            onstack = MethodDefn(
-                MethodDecl(p.onCxxStackVar().name, ret=Type.BOOL, const=1))
-            onstack.addstmt(StmtReturn(ExprCall(
-                ExprSelect(p.channelVar(), '.', p.onCxxStackVar().name))))
-
-            self.cls.addstmts([ onentered, onexited, onstack, Whitespace.NL ])
+            self.cls.addstmts([ onentered, onexited, Whitespace.NL ])
 
         # OnChannelClose()
         onclose = MethodDefn(MethodDecl('OnChannelClose'))
         if ptype.isToplevel():
             onclose.addstmts([
                 StmtExpr(ExprCall(destroysubtreevar,
                                   args=[ _DestroyReason.NormalShutdown ])),
                 StmtExpr(ExprCall(deallocsubtreevar))