From: Timo Sirainen Date: Fri, 18 Jun 2021 11:19:36 +0000 (+0300) Subject: lib-test: Add notification signal send/wait API X-Git-Tag: 2.3.17~399 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec04bc903e6558d122ecfbfe29c5c5a0f1d4db38;p=thirdparty%2Fdovecot%2Fcore.git lib-test: Add notification signal send/wait API This allows a simple way for child/parent processes to communicate when they're ready. SIGHUP signal is reserved for this. --- diff --git a/src/lib-test/test-subprocess.c b/src/lib-test/test-subprocess.c index 4c51924b7e..aec1ddde50 100644 --- a/src/lib-test/test-subprocess.c +++ b/src/lib-test/test-subprocess.c @@ -5,6 +5,7 @@ #include "hostpid.h" #include "array.h" #include "ioloop.h" +#include "sleep.h" #include "test-common.h" #include "test-subprocess.h" @@ -18,6 +19,7 @@ struct test_subprocess { volatile sig_atomic_t test_subprocess_is_child = 0; static bool test_subprocess_lib_init = FALSE; +static volatile bool test_subprocess_notification_signal_received = FALSE; static struct event *test_subprocess_event = NULL; static ARRAY(struct test_subprocess *) test_subprocesses = ARRAY_INIT; static void (*test_subprocess_cleanup_callback)(void) = NULL; @@ -297,6 +299,41 @@ void test_subprocess_set_cleanup_callback(void (*callback)(void)) test_subprocess_cleanup_callback = callback; } +void test_subprocess_notify_signal_send(pid_t pid) +{ + if (kill(pid, SIGHUP) < 0) + i_fatal("kill(%ld, SIGHUP) failed: %m", (long)pid); +} + +void test_subprocess_notify_signal_send_parent(void) +{ + test_subprocess_notify_signal_send(getppid()); +} + +void test_subprocess_notify_signal_reset(void) +{ + test_subprocess_notification_signal_received = FALSE; +} + +void test_subprocess_notify_signal_wait(unsigned int timeout_msecs) +{ + unsigned int i, count = timeout_msecs / 10; + + for (i = 0; i < count; i++) { + if (test_subprocess_notification_signal_received) + return; + i_sleep_msecs(10); + } + i_fatal("Didn't receive wait notification signal from server"); +} + +static void +test_subprocess_notification_signal(const siginfo_t *si ATTR_UNUSED, + void *context ATTR_UNUSED) +{ + test_subprocess_notification_signal_received = TRUE; +} + void test_subprocesses_init(bool debug) { if (!lib_is_initialized()) { @@ -313,6 +350,8 @@ void test_subprocesses_init(bool debug) lib_signals_set_handler(SIGINT, 0, test_subprocess_terminate, NULL); lib_signals_set_handler(SIGSEGV, 0, test_subprocess_terminate, NULL); lib_signals_set_handler(SIGABRT, 0, test_subprocess_terminate, NULL); + lib_signals_set_handler(SIGHUP, LIBSIG_FLAG_RESTART, + test_subprocess_notification_signal, NULL); i_array_init(&test_subprocesses, 8); diff --git a/src/lib-test/test-subprocess.h b/src/lib-test/test-subprocess.h index fed6d0464f..35f6300526 100644 --- a/src/lib-test/test-subprocess.h +++ b/src/lib-test/test-subprocess.h @@ -23,6 +23,18 @@ void test_subprocess_kill_all(unsigned int timeout_secs); exit()s unexpectedly. Note that this may be run in signal context. */ void test_subprocess_set_cleanup_callback(void (*callback)(void)); +/* Send a notification signal (SIGHUP) to the given PID */ +void test_subprocess_notify_signal_send(pid_t pid); +/* Send a notificatino signal to the parent process. */ +void test_subprocess_notify_signal_send_parent(void); +/* Reset any previously sent notification signals. */ +void test_subprocess_notify_signal_reset(void); +/* Wait until a notification signal is sent, or return immediately if it was + already sent. test_subprocess_notify_signal_reset() should be called before + this to make sure it's not returning due to a previously sent signal. + If the timeout is reached, i_fatal() is called. */ +void test_subprocess_notify_signal_wait(unsigned int timeout_msecs); + void test_subprocesses_init(bool debug); void test_subprocesses_deinit(void);