summaryrefslogtreecommitdiff
path: root/indra/llcommon/tests
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-02-13 17:38:25 -0500
committerNat Goodspeed <nat@lindenlab.com>2012-02-13 17:38:25 -0500
commitaae61392be822218cabcab91d95eb1e75d471764 (patch)
treec2d2f16fb5e8d4d9a0f56a1b4c79ebc9cd481a68 /indra/llcommon/tests
parentd4f887e43ccf0a8b7a84ebbfe6889462a1d9c25f (diff)
Use per-frame ticks on "mainloop" LLEventPump to update LLProcess.
When we reimplemented LLProcess on APR, necessitating APR's funny callback mechanism to sense child-process status, every isRunning() or getStatus() call called the APR poll function that calls ALL registered LLProcess callbacks. In other words, every time any consumer called any LLProcess::isRunning() method, all LLProcess callbacks were redundantly fired. Change that so that the single APR poll function is called once per frame, courtesy of the "mainloop" LLEventPump. Once per viewer frame should be well within the realtime duration in which it's reasonable to expect child-process status to change. In effect, this changes LLProcess's public API to introduce a dependency on "mainloop" ticks. Add such ticks to llprocess_test.cpp as well.
Diffstat (limited to 'indra/llcommon/tests')
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp42
1 files changed, 26 insertions, 16 deletions
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 711715e373..8c21be196b 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -33,6 +33,7 @@
#include "../test/namedtempfile.h"
#include "stringize.h"
#include "llsdutil.h"
+#include "llevents.h"
#if defined(LL_WINDOWS)
#define sleep(secs) _sleep((secs) * 1000)
@@ -88,6 +89,27 @@ static std::string readfile(const std::string& pathname, const std::string& desc
return output;
}
+/// Looping on LLProcess::isRunning() must now be accompanied by pumping
+/// "mainloop" -- otherwise the status won't update and you get an infinite
+/// loop.
+void waitfor(LLProcess& proc)
+{
+ while (proc.isRunning())
+ {
+ sleep(1);
+ LLEventPumps::instance().obtain("mainloop").post(LLSD());
+ }
+}
+
+void waitfor(LLProcess::handle h, const std::string& desc)
+{
+ while (LLProcess::isRunning(h, desc))
+ {
+ sleep(1);
+ LLEventPumps::instance().obtain("mainloop").post(LLSD());
+ }
+}
+
/**
* Construct an LLProcess to run a Python script.
*/
@@ -120,10 +142,7 @@ struct PythonProcessLauncher
// there's no API to wait for the child to terminate -- but given
// its use in our graphics-intensive interactive viewer, it's
// understandable.
- while (mPy->isRunning())
- {
- sleep(1);
- }
+ waitfor(*mPy);
}
/**
@@ -619,10 +638,7 @@ namespace tut
// script has performed its first write and should now be sleeping.
py.mPy->kill();
// wait for the script to terminate... one way or another.
- while (py.mPy->isRunning())
- {
- sleep(1);
- }
+ waitfor(*py.mPy);
#if LL_WINDOWS
ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
ensure_equals("Status.mData", py.mPy->getStatus().mData, -1);
@@ -672,10 +688,7 @@ namespace tut
// Destroy the LLProcess, which should kill the child.
}
// wait for the script to terminate... one way or another.
- while (LLProcess::isRunning(phandle, "kill() script"))
- {
- sleep(1);
- }
+ waitfor(phandle, "kill() script");
// If kill() failed, the script would have woken up on its own and
// overwritten the file with 'bad'. But if kill() succeeded, it should
// not have had that chance.
@@ -737,10 +750,7 @@ namespace tut
outf << "go";
} // flush and close.
// now wait for the script to terminate... one way or another.
- while (LLProcess::isRunning(phandle, "autokill script"))
- {
- sleep(1);
- }
+ waitfor(phandle, "autokill script");
// If the LLProcess destructor implicitly called kill(), the
// script could not have written 'ack' as we expect.
ensure_equals("autokill script output", readfile(from.getName()), "ack");