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 /indra/llcommon | |
| 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).
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llinitparam.h | 3 | ||||
| -rw-r--r-- | indra/llcommon/llleap.cpp | 51 | ||||
| -rw-r--r-- | indra/llcommon/llleap.h | 14 | 
3 files changed, 49 insertions, 19 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 | 
