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.
meow-7.2.2
Nat Goodspeed 2012-06-06 16:38:16 -04:00
parent fd3ae758d0
commit 166f75d91f
3 changed files with 52 additions and 10 deletions

View File

@ -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());
@ -839,6 +866,17 @@ std::string LLProcess::getStatusString(const Status& status) const
return getStatusString(mDesc, status);
}
//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)
{

View File

@ -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="");

View File

@ -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;