diff options
author | Monroe Linden <monroe@lindenlab.com> | 2009-10-05 15:48:00 -0700 |
---|---|---|
committer | Monroe Linden <monroe@lindenlab.com> | 2009-10-05 15:48:00 -0700 |
commit | 374deb8da13c63f80dc1b245488eb254eb86f5d2 (patch) | |
tree | 9335c64f9b01664c2bd13b4bd8fc170b7a070a0f | |
parent | 0c475833994d1b89bbd5a09872eea73c32c8c5c3 (diff) |
Fixes for a different class of plugin failures (where loading the plugin dll fails) causing an error message loop:
Made LLPluginProcessParent differentiate between failures launching/loading the plugin and failures after the plugin has been loaded. This allows us to handle launch failures differently, since retrying is unlikely to fix them.
Added new media event MEDIA_EVENT_PLUGIN_FAILED_LAUNCH to indicate a launch failure.
Added a case for the new event to LLViewerMediaImpl::handleMediaEvent() that sets the "failed init" flag to prevent retries.
-rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 6 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 1 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmediaowner.h | 3 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.cpp | 54 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.h | 5 | ||||
-rw-r--r-- | indra/newview/llmediactrl.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llviewermedia.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llviewerparcelmedia.cpp | 6 | ||||
-rw-r--r-- | indra/test_apps/llplugintest/llmediaplugintest.cpp | 4 |
9 files changed, 77 insertions, 20 deletions
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 7299ede22d..e019cdcf21 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -884,6 +884,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) } /* virtual */ +void LLPluginClassMedia::pluginLaunchFailed() +{ + mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH); +} + +/* virtual */ void LLPluginClassMedia::pluginDied() { mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED); diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 331ca5f6dc..97f2a11ef2 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -135,6 +135,7 @@ public: // Inherited from LLPluginProcessParentOwner /* virtual */ void receivePluginMessage(const LLPluginMessage &message); + /* virtual */ void pluginLaunchFailed(); /* virtual */ void pluginDied(); diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index df6de0925e..cfee847080 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -56,7 +56,8 @@ public: MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are MEDIA_EVENT_CLICK_LINK_NOFOLLOW, - MEDIA_EVENT_PLUGIN_FAILED // The plugin failed to launch or died unexpectedly + MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch + MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly } EMediaEvent; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 41784a713c..c925d4b760 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -83,6 +83,14 @@ void LLPluginProcessParent::killSockets(void) mSocket.reset(); } +void LLPluginProcessParent::errorState(void) +{ + if(mState < STATE_RUNNING) + setState(STATE_LAUNCH_FAILURE); + else + setState(STATE_ERROR); +} + void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename) { mProcess.setExecutable(launcher_filename); @@ -132,7 +140,7 @@ bool LLPluginProcessParent::accept() ll_apr_warn_status(status); // Some other error. - setState(STATE_ERROR); + errorState(); } return result; @@ -150,15 +158,15 @@ void LLPluginProcessParent::idle(void) if(!mMessagePipe->pump()) { // LL_WARNS("Plugin") << "Message pipe hit an error state" << LL_ENDL; - setState(STATE_ERROR); + errorState(); } } - if((mSocketError != APR_SUCCESS) && (mState < STATE_ERROR)) + if((mSocketError != APR_SUCCESS) && (mState <= STATE_RUNNING)) { // The socket is in an error state -- the plugin is gone. LL_WARNS("Plugin") << "Socket hit an error state (" << mSocketError << ")" << LL_ENDL; - setState(STATE_ERROR); + errorState(); } // If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState(). @@ -191,7 +199,7 @@ void LLPluginProcessParent::idle(void) if(ll_apr_warn_status(status)) { killSockets(); - setState(STATE_ERROR); + errorState(); break; } @@ -202,7 +210,7 @@ void LLPluginProcessParent::idle(void) if(ll_apr_warn_status(status)) { killSockets(); - setState(STATE_ERROR); + errorState(); break; } @@ -212,7 +220,7 @@ void LLPluginProcessParent::idle(void) if(ll_apr_warn_status(apr_socket_addr_get(&bound_addr, APR_LOCAL, mListenSocket->getSocket()))) { killSockets(); - setState(STATE_ERROR); + errorState(); break; } mBoundPort = bound_addr->port; @@ -222,7 +230,7 @@ void LLPluginProcessParent::idle(void) LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL; killSockets(); - setState(STATE_ERROR); + errorState(); break; } } @@ -234,7 +242,7 @@ void LLPluginProcessParent::idle(void) if(ll_apr_warn_status(status)) { killSockets(); - setState(STATE_ERROR); + errorState(); break; } @@ -242,7 +250,7 @@ void LLPluginProcessParent::idle(void) if(ll_apr_warn_status(status)) { killSockets(); - setState(STATE_ERROR); + errorState(); break; } @@ -255,7 +263,7 @@ void LLPluginProcessParent::idle(void) if(ll_apr_warn_status(status)) { killSockets(); - setState(STATE_ERROR); + errorState(); break; } @@ -274,7 +282,7 @@ void LLPluginProcessParent::idle(void) mProcess.addArgument(stream.str()); if(mProcess.launch() != 0) { - setState(STATE_ERROR); + errorState(); } else { @@ -290,7 +298,7 @@ void LLPluginProcessParent::idle(void) // waiting for the plugin to connect if(pluginLockedUpOrQuit()) { - setState(STATE_ERROR); + errorState(); } else { @@ -309,7 +317,7 @@ void LLPluginProcessParent::idle(void) if(pluginLockedUpOrQuit()) { - setState(STATE_ERROR); + errorState(); } break; @@ -330,14 +338,14 @@ void LLPluginProcessParent::idle(void) // The load_plugin_response message will kick us from here into STATE_RUNNING if(pluginLockedUpOrQuit()) { - setState(STATE_ERROR); + errorState(); } break; case STATE_RUNNING: if(pluginLockedUpOrQuit()) { - setState(STATE_ERROR); + errorState(); } break; @@ -349,10 +357,18 @@ void LLPluginProcessParent::idle(void) else if(pluginLockedUp()) { LL_WARNS("Plugin") << "timeout in exiting state, bailing out" << llendl; - setState(STATE_ERROR); + errorState(); } break; + case STATE_LAUNCH_FAILURE: + if(mOwner != NULL) + { + mOwner->pluginLaunchFailed(); + } + setState(STATE_CLEANUP); + break; + case STATE_ERROR: if(mOwner != NULL) { @@ -467,7 +483,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) else { LL_WARNS("Plugin") << "received hello message in wrong state -- bailing out" << LL_ENDL; - setState(STATE_ERROR); + errorState(); } } @@ -497,7 +513,7 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message) else { LL_WARNS("Plugin") << "received load_plugin_response message in wrong state -- bailing out" << LL_ENDL; - setState(STATE_ERROR); + errorState(); } } else if(message_name == "heartbeat") diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 0d0b047c88..754ebeb946 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -45,6 +45,7 @@ public: virtual ~LLPluginProcessParentOwner(); virtual void receivePluginMessage(const LLPluginMessage &message) = 0; // This will only be called when the plugin has died unexpectedly + virtual void pluginLaunchFailed() {}; virtual void pluginDied() {}; }; @@ -68,6 +69,9 @@ public: bool isDone(void); void killSockets(void); + + // Go to the proper error state + void errorState(void); void setSleepTime(F64 sleep_time, bool force_send = false); F64 getSleepTime(void) const { return mSleepTime; }; @@ -110,6 +114,7 @@ private: STATE_HELLO, // first message from the plugin process has been received STATE_LOADING, // process has been asked to load the plugin STATE_RUNNING, // + STATE_LAUNCH_FAILURE, // Failure before plugin loaded STATE_ERROR, // generic bailout state STATE_CLEANUP, // clean everything up STATE_EXITING, // Tried to kill process, waiting for it to exit diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b996c15a7d..ad6ebbbc5c 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -903,6 +903,12 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; }; break; + + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; + }; + break; }; // chain all events to any potential observers of this object. diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index d5c75b82a7..d375e7ee4e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1381,6 +1381,18 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla { switch(event) { + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + { + // The plugin failed to load properly. Make sure the timer doesn't retry. + mMediaSourceFailedInit = true; + + // TODO: may want a different message for this case? + LLSD args; + args["PLUGIN"] = LLMIMETypes::implType(mMimeType); + LLNotifications::instance().add("MediaPluginFailed", args); + } + break; + case MEDIA_EVENT_PLUGIN_FAILED: { LLSD args; diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index a3f9c839a0..6fba909983 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -544,6 +544,12 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; }; break; + + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; + }; + break; }; } diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index 7869763302..f9568a9b5d 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -2033,6 +2033,10 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e case MEDIA_EVENT_PLUGIN_FAILED: std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << std::endl; break; + + case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: + std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl; + break; } } |