diff options
author | Alexander Færøy <ahf@torproject.org> | 2018-11-22 04:49:23 +0100 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-12-17 16:39:28 -0500 |
commit | bb784cf4f36256a8276ba60641d3ff766b9cd9df (patch) | |
tree | 347af5c98bbeb2edcd4655f6740de9358b70ab62 /src/test/test_process.c | |
parent | 2e957027e28449d4c3254cc404d154f4bce41bfc (diff) | |
download | tor-bb784cf4f36256a8276ba60641d3ff766b9cd9df.tar.gz tor-bb784cf4f36256a8276ba60641d3ff766b9cd9df.zip |
Add Windows backend for the Process subsystem.
This patch adds support for Microsoft Windows in the Process subsystem.
Libevent does not support mixing different types of handles (sockets,
named pipes, etc.) on Windows in its core event loop code. This have
historically meant that Tor have avoided attaching any non-networking
handles to the event loop. This patch uses a slightly different approach
to roughly support the same features for the Process subsystem as we do
with the Unix backend.
In this patch we use Windows Extended I/O functions (ReadFileEx() and
WriteFileEx()) which executes asynchronously in the background and
executes a completion routine when the scheduled read or write operation
have completed. This is much different from the Unix backend where the
operating system signals to us whenever a file descriptor is "ready" to
either being read from or written to.
To make the Windows operating system execute the completion routines of
ReadFileEx() and WriteFileEx() we must get the Tor process into what
Microsoft calls an "alertable" state. To do this we execute SleepEx()
with a zero millisecond sleep time from a main loop timer that ticks
once a second. This moves the process into the "alertable" state and
when we return from the zero millisecond timeout all the outstanding I/O
completion routines will be called and we can schedule the next reads
and writes.
The timer loop is also responsible for detecting whether our child
processes have terminated since the last timer tick.
See: https://bugs.torproject.org/28179
Diffstat (limited to 'src/test/test_process.c')
-rw-r--r-- | src/test/test_process.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/test/test_process.c b/src/test/test_process.c index 816695ccab..85ee9691a4 100644 --- a/src/test/test_process.c +++ b/src/test/test_process.c @@ -14,6 +14,8 @@ #include "lib/process/process.h" #define PROCESS_UNIX_PRIVATE #include "lib/process/process_unix.h" +#define PROCESS_WIN32_PRIVATE +#include "lib/process/process_win32.h" static const char *stdout_read_buffer; static const char *stderr_read_buffer; @@ -553,7 +555,7 @@ test_unix(void *arg) #ifndef _WIN32 process_init(); - process_t *process = process_new(); + process_t *process = process_new(""); /* On Unix all processes should have a Unix process handle. */ tt_ptr_op(NULL, OP_NE, process_get_unix_process(process)); @@ -564,6 +566,24 @@ test_unix(void *arg) #endif } +static void +test_win32(void *arg) +{ + (void)arg; +#ifdef _WIN32 + process_init(); + + process_t *process = process_new(""); + + /* On Win32 all processes should have a Win32 process handle. */ + tt_ptr_op(NULL, OP_NE, process_get_win32_process(process)); + + done: + process_free(process); + process_free_all(); +#endif +} + struct testcase_t process_tests[] = { { "default_values", test_default_values, TT_FORK, NULL, NULL }, { "stringified_types", test_stringified_types, TT_FORK, NULL, NULL }, @@ -575,5 +595,6 @@ struct testcase_t process_tests[] = { { "exit_simple", test_exit_simple, TT_FORK, NULL, NULL }, { "argv_simple", test_argv_simple, TT_FORK, NULL, NULL }, { "unix", test_unix, TT_FORK, NULL, NULL }, + { "win32", test_win32, TT_FORK, NULL, NULL }, END_OF_TESTCASES }; |