summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-06-06 16:38:16 -0400
committerNat Goodspeed <nat@lindenlab.com>2012-06-06 16:38:16 -0400
commit166f75d91f180d0ac45f0b8ee7c3a1b6742209fa (patch)
treee94ed285a533101cf8d8d358d88651ec718a7de6
parentfd3ae758d0dc3cb4330ea9c7a9af8c0ffa046dfc (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.cpp38
-rw-r--r--indra/llcommon/llprocess.h11
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp13
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;