diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2012-06-06 16:38:16 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2012-06-06 16:38:16 -0400 |
commit | 166f75d91f180d0ac45f0b8ee7c3a1b6742209fa (patch) | |
tree | e94ed285a533101cf8d8d358d88651ec718a7de6 | |
parent | fd3ae758d0dc3cb4330ea9c7a9af8c0ffa046dfc (diff) |
MAINT-1144: Defend against NULL LLPluginProcessParent::mProcess.
The change from LLProcessLauncher to LLProcess introduces the possibility of a
NULL (default-constructed) LLProcessPtr. Add certain static LLProcess methods
accepting LLProcessPtr, forwarding to nonstatic method when non-NULL but doing
something reasonable with NULL. Use these methods in LLPLuginProcessParent.
-rw-r--r-- | indra/llcommon/llprocess.cpp | 38 | ||||
-rw-r--r-- | indra/llcommon/llprocess.h | 11 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.cpp | 13 |
3 files changed, 52 insertions, 10 deletions
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 9667e4e033..715df36f39 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -819,16 +819,43 @@ bool LLProcess::kill(const std::string& who) return ! isRunning(); } +//static +bool LLProcess::kill(const LLProcessPtr& p, const std::string& who) +{ + if (! p) + return true; // process dead! (was never running) + return p->kill(who); +} + bool LLProcess::isRunning() const { return getStatus().mState == RUNNING; } +//static +bool LLProcess::isRunning(const LLProcessPtr& p) +{ + if (! p) + return false; + return p->isRunning(); +} + LLProcess::Status LLProcess::getStatus() const { return mStatus; } +//static +LLProcess::Status LLProcess::getStatus(const LLProcessPtr& p) +{ + if (! p) + { + // default-constructed Status has mState == UNSTARTED + return Status(); + } + return p->getStatus(); +} + std::string LLProcess::getStatusString() const { return getStatusString(getStatus()); @@ -840,6 +867,17 @@ std::string LLProcess::getStatusString(const Status& status) const } //static +std::string LLProcess::getStatusString(const std::string& desc, const LLProcessPtr& p) +{ + if (! p) + { + // default-constructed Status has mState == UNSTARTED + return getStatusString(desc, Status()); + } + return desc + " " + p->getStatusString(); +} + +//static std::string LLProcess::getStatusString(const std::string& desc, const Status& status) { if (status.mState == UNSTARTED) diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index 51010966f9..d711ce2f74 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -239,6 +239,10 @@ public: /// Is child process still running? bool isRunning() const; + // static isRunning(LLProcessPtr), getStatus(LLProcessPtr), + // getStatusString(LLProcessPtr), kill(LLProcessPtr) handle the case in + // which the passed LLProcessPtr might be NULL (default-constructed). + static bool isRunning(const LLProcessPtr&); /** * State of child process @@ -272,8 +276,10 @@ public: /// Status query Status getStatus() const; + static Status getStatus(const LLProcessPtr&); /// English Status string query, for logging etc. std::string getStatusString() const; + static std::string getStatusString(const std::string& desc, const LLProcessPtr&); /// English Status string query for previously-captured Status std::string getStatusString(const Status& status) const; /// static English Status string query @@ -282,6 +288,7 @@ public: // Attempt to kill the process -- returns true if the process is no longer running when it returns. // Note that even if this returns false, the process may exit some time after it's called. bool kill(const std::string& who=""); + static bool kill(const LLProcessPtr& p, const std::string& who=""); #if LL_WINDOWS typedef int id; ///< as returned by getProcessID() @@ -314,10 +321,10 @@ public: * New functionality should be added as nonstatic members operating on * the same data as getProcessHandle(). * - * In particular, if child termination is detected by static isRunning() + * In particular, if child termination is detected by this static isRunning() * rather than by nonstatic isRunning(), the LLProcess object won't be * aware of the child's changed status and may encounter OS errors trying - * to obtain it. static isRunning() is only intended for after the + * to obtain it. This static isRunning() is only intended for after the * launching LLProcess object has been destroyed. */ static handle isRunning(handle, const std::string& desc=""); diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index f10eaee5b4..71a6145b58 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -134,11 +134,8 @@ LLPluginProcessParent::~LLPluginProcessParent() // and remove it from our map mSharedMemoryRegions.erase(iter); } - - if (mProcess) - { - mProcess->kill(); - } + + LLProcess::kill(mProcess); killSockets(); } @@ -471,7 +468,7 @@ void LLPluginProcessParent::idle(void) break; case STATE_EXITING: - if (! mProcess->isRunning()) + if (! LLProcess::isRunning(mProcess)) { setState(STATE_CLEANUP); } @@ -499,7 +496,7 @@ void LLPluginProcessParent::idle(void) break; case STATE_CLEANUP: - mProcess->kill(); + LLProcess::kill(mProcess); killSockets(); setState(STATE_DONE); break; @@ -1078,7 +1075,7 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit() { bool result = false; - if (! mProcess->isRunning()) + if (! LLProcess::isRunning(mProcess)) { LL_WARNS("Plugin") << "child exited" << LL_ENDL; result = true; |