aboutsummaryrefslogtreecommitdiff
path: root/libbutl/process.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-08-28 18:19:18 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-08-28 20:19:37 +0300
commit892bbaa0efecaa182d30983e3717e19959a0f576 (patch)
treeddfde530d33e95b3d36786027092f91a50cd6207 /libbutl/process.cxx
parent572dea961662d141b83713a6577acd2c78b03060 (diff)
Use chrono timepoints for MSYS2 process re-spawning heuristics
Diffstat (limited to 'libbutl/process.cxx')
-rw-r--r--libbutl/process.cxx40
1 files changed, 24 insertions, 16 deletions
diff --git a/libbutl/process.cxx b/libbutl/process.cxx
index 7fe43a0..d474b3a 100644
--- a/libbutl/process.cxx
+++ b/libbutl/process.cxx
@@ -39,8 +39,10 @@
# endif // _MSC_VER
# include <map>
+# include <chrono>
# include <cstdlib> // getenv(), __argv[]
+# include <libbutl/timestamp.hxx>
# include <libbutl/small-vector.hxx>
#endif
@@ -1419,7 +1421,7 @@ namespace butl
msys = i->second;
}
- for (DWORD timeout (10500); timeout != 0; ) // Try for about 10s.
+ for (duration timeout (10500ms);;) // Try for about 10s.
{
if (!CreateProcess (
batch != nullptr ? batch : pp.effect_string (),
@@ -1442,7 +1444,7 @@ namespace butl
// still running then we assume all is good. Otherwise, retry if
// this is the DLL initialization error.
//
- DWORD r;
+ timestamp st (timestamp::clock::now ());
// Unlock the mutex to let other processes to be spawned while we are
// waiting. We also need to revert handles to non-inheritable state
@@ -1451,26 +1453,32 @@ namespace butl
il.unlock ();
l.unlock ();
- // Wait in small increments to get (approximate) time elapsed.
- //
- for (size_t i (0); i != 10; ++i, timeout -= 50) // 10 * 50 = 500ms.
- {
- r = WaitForSingleObject (pi.hProcess, 50);
-
- if (r != WAIT_TIMEOUT)
- break;
- }
+ DWORD r (WaitForSingleObject (pi.hProcess, 250));
if (r == WAIT_OBJECT_0 &&
GetExitCodeProcess (pi.hProcess, &r) &&
r == STATUS_DLL_INIT_FAILED)
{
- // Re-lock the mutex and revert handles to inheritable state prior
- // to re-spawning the child process.
+ timestamp now (timestamp::clock::now ());
+
+ // Assume we were waiting for 250 ms if the time adjustment is
+ // detected.
//
- l.lock ();
- il.lock ();
- continue;
+ duration d (now > st ? now - st : 250ms);
+
+ // Re-spawn the process if timeout is not fully exhausted.
+ //
+ if (timeout > d)
+ {
+ timeout -= d;
+
+ // Re-lock the mutex and revert handles to inheritable state
+ // prior to re-spawning the child process.
+ //
+ l.lock ();
+ il.lock ();
+ continue;
+ }
}
}