diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2018-10-03 14:00:05 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2018-10-03 14:00:05 -0400 |
commit | b1955d4247a4d28a3a4c259036390ff632e80008 (patch) | |
tree | 3cc4f620431c4cef25dd880e1ff391ada1a2c93b | |
parent | 6e1b2e137e2b6c6d92d14f478b6908c0c2f1e231 (diff) |
DRTVWR-474: Do NOT autokill updater process on viewer termination.
The updater is required to survive beyond termination of the viewer that
launched it so it can launch the next installer, or a replacement viewer.
Having the old viewer forcibly terminate it on shutdown would be counter-
productive.
Introduce a third LLLeap::create() overload taking LLProcess::Params, which
gives access to autokill, cwd and other options previously unsupported by
LLLeap. Reimplement the existing create() overloads in terms of this new one,
since LLLeapImpl::LLLeapImpl() is already based on LLProcess::Params anyway.
Use LLProcess::Params in LLAppViewer::init() to specify the updater process,
setting autokill=false.
Refactoring LLLeapImpl() apparently involved engaging an LLInitParam::Block
feature never before used: had to drag operator() into Multiple from its base
class TypedParam (as has been done in other TypedParam subclasses).
-rw-r--r-- | indra/llcommon/llinitparam.h | 3 | ||||
-rw-r--r-- | indra/llcommon/llleap.cpp | 51 | ||||
-rw-r--r-- | indra/llcommon/llleap.h | 14 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 33 |
4 files changed, 65 insertions, 36 deletions
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index f1f4226c40..7f5b9b4ac2 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -2115,6 +2115,9 @@ namespace LLInitParam typedef typename super_t::iterator iterator; typedef typename super_t::const_iterator const_iterator; + using super_t::operator(); + using super_t::operator const container_t&; + explicit Multiple(const char* name = "") : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount) {} diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index c87d2a3e58..cf8f8cc6a5 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -47,9 +47,9 @@ class LLLeapImpl: public LLLeap LOG_CLASS(LLLeap); public: // Called only by LLLeap::create() - LLLeapImpl(const std::string& desc, const std::vector<std::string>& plugin): + LLLeapImpl(const LLProcess::Params& cparams): // We might reassign mDesc in the constructor body if it's empty here. - mDesc(desc), + mDesc(cparams.desc), // We expect multiple LLLeapImpl instances. Definitely tweak // mDonePump's name for uniqueness. mDonePump("LLLeap", true), @@ -67,17 +67,17 @@ public: // this class or method name. mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2))) { - // Rule out empty vector - if (plugin.empty()) + // Rule out unpopulated Params block + if (! cparams.executable.isProvided()) { LLTHROW(Error("no plugin command")); } // Don't leave desc empty either, but in this case, if we weren't // given one, we'll fake one. - if (desc.empty()) + if (mDesc.empty()) { - mDesc = LLProcess::basename(plugin[0]); + mDesc = LLProcess::basename(cparams.executable); // how about a toLower() variant that returns the transformed string?! std::string desclower(mDesc); LLStringUtil::toLower(desclower); @@ -87,9 +87,9 @@ public: // notice Python specially: we provide Python LLSD serialization // support, so there's a pretty good reason to implement plugins // in that language. - if (plugin.size() >= 2 && (desclower == "python" || desclower == "python.exe")) + if (cparams.args.size() && (desclower == "python" || desclower == "python.exe")) { - mDesc = LLProcess::basename(plugin[1]); + mDesc = LLProcess::basename(cparams.args()[0]); } } @@ -97,14 +97,10 @@ public: mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::bad_launch, this, _1)); // Okay, launch child. - LLProcess::Params params; + // Get a modifiable copy of params block to set files and postend. + LLProcess::Params params(cparams); + // copy our deduced mDesc back into the params block params.desc = mDesc; - std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end()); - params.executable = *pi++; - for ( ; pi != pend; ++pi) - { - params.args.add(*pi); - } params.files.add(LLProcess::FileParam("pipe")); // stdin params.files.add(LLProcess::FileParam("pipe")); // stdout params.files.add(LLProcess::FileParam("pipe")); // stderr @@ -429,17 +425,17 @@ private: boost::scoped_ptr<LLLeapListener> mListener; }; -// This must follow the declaration of LLLeapImpl, so it may as well be last. -LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc) +// These must follow the declaration of LLLeapImpl, so they may as well be last. +LLLeap* LLLeap::create(const LLProcess::Params& params, bool exc) { // If caller is willing to permit exceptions, just instantiate. if (exc) - return new LLLeapImpl(desc, plugin); + return new LLLeapImpl(params); // Caller insists on suppressing LLLeap::Error. Very well, catch it. try { - return new LLLeapImpl(desc, plugin); + return new LLLeapImpl(params); } catch (const LLLeap::Error&) { @@ -447,6 +443,23 @@ LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& } } +LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc) +{ + LLProcess::Params params; + params.desc = desc; + std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end()); + // could validate here, but let's rely on LLLeapImpl's constructor + if (pi != pend) + { + params.executable = *pi++; + } + for ( ; pi != pend; ++pi) + { + params.args.add(*pi); + } + return create(params, exc); +} + LLLeap* LLLeap::create(const std::string& desc, const std::string& plugin, bool exc) { // Use LLStringUtil::getTokens() to parse the command line diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h index 8aac8a64c5..7cecdf2f8f 100644 --- a/indra/llcommon/llleap.h +++ b/indra/llcommon/llleap.h @@ -14,6 +14,7 @@ #include "llinstancetracker.h" #include "llexception.h" +#include "llprocess.h" #include <string> #include <vector> @@ -62,6 +63,19 @@ public: bool exc=true); /** + * Pass an LLProcess::Params instance to specify desc, executable, args et al. + * + * Note that files and postend are set implicitly; any values you set in + * those fields will be disregarded. + * + * Pass exc=false to suppress LLLeap::Error exception. Obviously in that + * case the caller cannot discover the nature of the error, merely that an + * error of some kind occurred (because create() returned NULL). Either + * way, the error is logged. + */ + static LLLeap* create(const LLProcess::Params& params, bool exc=true); + + /** * Exception thrown for invalid create() arguments, e.g. no plugin * program. This is more resiliant than an LL_ERRS failure, because the * string(s) passed to create() might come from an external source. This diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 776fc85a2d..bc4ce19f77 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1130,30 +1130,35 @@ bool LLAppViewer::init() gGLActive = FALSE; - std::vector<std::string> updater + LLProcess::Params updater; + updater.desc = "updater process"; + // Because it's the updater, it MUST persist beyond the lifespan of the + // viewer itself. + updater.autokill = false; #if LL_WINDOWS - { gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") }; + updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe"); #elif LL_DARWIN // explicitly run the system Python interpreter on updater.py - { "python", gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") }; + updater.executable = "python"; + updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py")); #else - { gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") }; + updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater"); #endif // add LEAP mode command-line argument to whichever of these we selected - updater.push_back("leap"); + updater.args.add("leap"); // UpdaterServiceSettings - updater.push_back(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); + updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); // channel - updater.push_back(LLVersionInfo::getChannel()); + updater.args.add(LLVersionInfo::getChannel()); // testok - updater.push_back(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest"))); + updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest"))); // UpdaterServiceURL - updater.push_back(gSavedSettings.getString("UpdaterServiceURL")); + updater.args.add(gSavedSettings.getString("UpdaterServiceURL")); // ForceAddressSize - updater.push_back(stringize(gSavedSettings.getU32("ForceAddressSize"))); + updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize"))); // Run the updater. An exception from launching the updater should bother us. - LLLeap::create("updater process", updater, true); + LLLeap::create(updater, true); // Iterate over --leap command-line options. But this is a bit tricky: if // there's only one, it won't be an array at all. @@ -3923,12 +3928,6 @@ void LLAppViewer::requestQuit() gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. } - // Try to send last batch of avatar rez metrics. - if (!gDisconnected && isAgentAvatarValid()) - { - gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. - } - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); effectp->setPositionGlobal(gAgent.getPositionGlobal()); effectp->setColor(LLColor4U(gAgent.getEffectColor())); |