From 27cadfbe951abb2cf350d5a1c91876ac958d50cf Mon Sep 17 00:00:00 2001 From: Nat Goodspeed <nat@lindenlab.com> Date: Sat, 17 Oct 2009 12:21:22 -0400 Subject: [PATCH] DEV-40930: Introduce LLAppViewerListener "forceQuit" operation. The bug was driven by the following sequence in llstartup.cpp: if(reason_response == "update" || reason_response == "optional") { // used to resend status event still containing "update", // erroneously instantiating a second forced-update // LLAlertDialog LLLoginInstance::getInstance()->disconnect(); // quit with an LLAlertDialog still on sModalStack used // to result in LL_ERRS LLAppViewer::instance()->forceQuit(); } I hope to be able to introduce a test script to verify the fix. That script would need to be able to call LLAppViewer::forceQuit() rather than requestQuit(), which is already available via LLAppViewerListener. At the same time, changed LLAppViewerListener to bind a functor to retrieve an LLAppViewer instance (namely LLAppViewer::instance) rather than an LLAppViewer*. Apparently the static instantiation of LLAppViewerListener was calling LLAppViewer::instance() too early, before things were ready, so the declaration was changed to pass NULL -- then in each method, call LLAppViewer::instance() if the bound pointer is NULL. Binding the LLAppViewer* is a Feathers tactic intended to avoid the need to reference the singleton. Binding a functor still leaves it up to the instantiating code to reference LLAppViewer::instance, while deferring the actual call to that method. --- indra/newview/llappviewer.cpp | 2 +- indra/newview/llappviewerlistener.cpp | 17 ++++++++++------- indra/newview/llappviewerlistener.h | 7 +++++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a631314d5bf..80749295ffd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -204,7 +204,7 @@ #pragma warning (disable:4702) #endif -static LLAppViewerListener sAppViewerListener("LLAppViewer", NULL); +static LLAppViewerListener sAppViewerListener("LLAppViewer", LLAppViewer::instance); ////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor // diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp index a3af251a3c3..3259309eee7 100644 --- a/indra/newview/llappviewerlistener.cpp +++ b/indra/newview/llappviewerlistener.cpp @@ -19,19 +19,22 @@ // other Linden headers #include "llappviewer.h" -LLAppViewerListener::LLAppViewerListener(const std::string& pumpname, LLAppViewer* llappviewer): +LLAppViewerListener::LLAppViewerListener(const std::string& pumpname, + const LLAppViewerGetter& getter): LLDispatchListener(pumpname, "op"), - mAppViewer(llappviewer) + mAppViewerGetter(getter) { // add() every method we want to be able to invoke via this event API. add("requestQuit", &LLAppViewerListener::requestQuit); + add("forceQuit", &LLAppViewerListener::forceQuit); } void LLAppViewerListener::requestQuit(const LLSD& event) { - if(mAppViewer == NULL) - { - mAppViewer = LLAppViewer::instance(); - } - mAppViewer->requestQuit(); + mAppViewerGetter()->requestQuit(); +} + +void LLAppViewerListener::forceQuit(const LLSD& event) +{ + mAppViewerGetter()->forceQuit(); } diff --git a/indra/newview/llappviewerlistener.h b/indra/newview/llappviewerlistener.h index d702f605ef0..73227cb95a7 100644 --- a/indra/newview/llappviewerlistener.h +++ b/indra/newview/llappviewerlistener.h @@ -13,6 +13,7 @@ #define LL_LLAPPVIEWERLISTENER_H #include "lleventdispatcher.h" +#include <boost/function.hpp> class LLAppViewer; class LLSD; @@ -21,14 +22,16 @@ class LLSD; class LLAppViewerListener: public LLDispatchListener { public: + typedef boost::function<LLAppViewer*(void)> LLAppViewerGetter; /// Specify the pump name on which to listen, and bind the LLAppViewer /// instance to use (e.g. LLAppViewer::instance()). - LLAppViewerListener(const std::string& pumpname, LLAppViewer* llappviewer); + LLAppViewerListener(const std::string& pumpname, const LLAppViewerGetter& getter); private: void requestQuit(const LLSD& event); + void forceQuit(const LLSD& event); - LLAppViewer* mAppViewer; + LLAppViewerGetter mAppViewerGetter; }; #endif /* ! defined(LL_LLAPPVIEWERLISTENER_H) */ -- GitLab