From 06f9dbd8db9895f81d7bd325d8cf616f68533396 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 18 Jan 2012 01:09:50 -0500
Subject: Introduce static LLProcessLauncher::isRunning(ll_pid_t) method.
 typedef LLProcessLauncher::ll_pid_t to be HANDLE on Windows, pid_t elsewhere.
 Then we can define getProcessID() returning ll_pid_t on all platforms,
 retaining getProcessHandle() for hypothetical existing consumers... of which
 there are none in practice. This lets us define isRunning(ll_pid_t) to
 encapsulate the platform-specific logic to actually check on a running child
 process, turning non-static isRunning() into a fairly trivial wrapper.

---
 indra/llcommon/llprocesslauncher.cpp | 49 +++++++++++++++++++++++-------------
 indra/llcommon/llprocesslauncher.h   | 19 ++++++++++++--
 2 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp
index 25d64e9e28..e1af49c2fb 100644
--- a/indra/llcommon/llprocesslauncher.cpp
+++ b/indra/llcommon/llprocesslauncher.cpp
@@ -143,18 +143,25 @@ int LLProcessLauncher::launch(void)
 
 bool LLProcessLauncher::isRunning(void)
 {
-	if(mProcessHandle != 0)		
+	mProcessHandle = isRunning(mProcessHandle);
+	return (mProcessHandle != 0);
+}
+
+LLProcessLauncher::ll_pid_t LLProcessLauncher::isRunning(ll_pid_t handle)
+{
+	if (! handle)
+		return 0;
+
+	DWORD waitresult = WaitForSingleObject(handle, 0);
+	if(waitresult == WAIT_OBJECT_0)
 	{
-		DWORD waitresult = WaitForSingleObject(mProcessHandle, 0);
-		if(waitresult == WAIT_OBJECT_0)
-		{
-			// the process has completed.
-			mProcessHandle = 0;
-		}			
+		// the process has completed.
+		return 0;
 	}
 
-	return (mProcessHandle != 0);
+	return handle;
 }
+
 bool LLProcessLauncher::kill(void)
 {
 	bool result = true;
@@ -293,19 +300,25 @@ int LLProcessLauncher::launch(void)
 
 bool LLProcessLauncher::isRunning(void)
 {
-	if(mProcessID != 0)
-	{
-		// Check whether the process has exited, and reap it if it has.
-		if(reap_pid(mProcessID))
-		{
-			// the process has exited.
-			mProcessID = 0;
-		}
-	}
-	
+	mProcessID = isRunning(mProcessID);
 	return (mProcessID != 0);
 }
 
+LLProcessLauncher::ll_pid_t LLProcessLauncher::isRunning(ll_pid_t pid)
+{
+    if (! pid)
+        return 0;
+
+    // Check whether the process has exited, and reap it if it has.
+    if(reap_pid(pid))
+    {
+        // the process has exited.
+        return 0;
+    }
+
+    return pid;
+}
+
 bool LLProcessLauncher::kill(void)
 {
 	bool result = true;
diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h
index 1daa980c58..63193abd8f 100644
--- a/indra/llcommon/llprocesslauncher.h
+++ b/indra/llcommon/llprocesslauncher.h
@@ -54,6 +54,8 @@ public:
 	void addArgument(const std::string &arg);
 		
 	int launch(void);
+	// isRunning isn't const because, if child isn't running, it clears stored
+	// process ID
 	bool isRunning(void);
 	
 	// Attempt to kill the process -- returns true if the process is no longer running when it returns.
@@ -72,10 +74,23 @@ public:
 	// Accessors for platform-specific process ID
 #if LL_WINDOWS
 	// (Windows flavor unused as of 2012-01-12)
-	HANDLE getProcessHandle() { return mProcessHandle; };
+	typedef HANDLE ll_pid_t;
+	HANDLE getProcessHandle() const { return mProcessHandle; }
+	ll_pid_t getProcessID() const { return mProcessHandle; }
 #else
-	pid_t getProcessID() { return mProcessID; };
+	typedef pid_t ll_pid_t;
+	ll_pid_t getProcessID() const { return mProcessID; };
 #endif	
+	/**
+	 * Test if a process (ll_pid_t obtained from getProcessID()) is still
+	 * running. Return is same nonzero ll_pid_t value if still running, else
+	 * zero, so you can test it like a bool. But if you want to update a
+	 * stored variable as a side effect, you can write code like this:
+	 * @code
+	 * childpid = LLProcessLauncher::isRunning(childpid);
+	 * @endcode
+	 */
+	static ll_pid_t isRunning(ll_pid_t);
 	
 private:
 	std::string mExecutable;
-- 
cgit v1.2.3