Commits

nat_linden committed 2d6c063

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.

  • Participants
  • Parent commits 7f1cf16
  • Tags DRTVWR-164

Comments (0)

Files changed (3)

File indra/llcommon/llprocess.cpp

 	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());
 }
 
 //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)

File indra/llcommon/llprocess.h

 
 	/// 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
 
 	/// 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
 	// 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()
 	 * 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="");

File indra/llplugin/llpluginprocessparent.cpp

 		// and remove it from our map
 		mSharedMemoryRegions.erase(iter);
 	}
-	
-	if (mProcess)
-	{
-		mProcess->kill();
-	}
+
+	LLProcess::kill(mProcess);
 	killSockets();
 }
 
 			break;
 			
 			case STATE_EXITING:
-				if (! mProcess->isRunning())
+				if (! LLProcess::isRunning(mProcess))
 				{
 					setState(STATE_CLEANUP);
 				}
 			break;
 			
 			case STATE_CLEANUP:
-				mProcess->kill();
+				LLProcess::kill(mProcess);
 				killSockets();
 				setState(STATE_DONE);
 			break;
 {
 	bool result = false;
 	
-	if (! mProcess->isRunning())
+	if (! LLProcess::isRunning(mProcess))
 	{
 		LL_WARNS("Plugin") << "child exited" << LL_ENDL;
 		result = true;