From: Gurucharan Shetty Date: Wed, 26 Feb 2014 16:25:42 +0000 (-0800) Subject: fatal-signal: Fatal signal handling for Windows. X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=84a6cbae3684abe57733ea8e297eb5c63358908a;p=ovs.git fatal-signal: Fatal signal handling for Windows. Windows does not have a SIGHUP or SIGALRM. It does have a SIGINT and SIGTERM. The documentation at msdn says that SIGINT is not supported for win32 applications because WIN32 operating systems generate a new thread to specifically handle Ctrl+C. This commit handles SIGTERM for Windows. The documentation also states that nothing generates SIGTERM in Windows, but one can use raise(SIGTERM) to manage it. The idea for handling SIGTERM for Windows is to just have a place holder if there is need to raise() a signal for some other purpose. We use SIGALRM in timeval.c if we wake up from a sleep after 'deadline'. For Windows, print an error message and then use SIGTERM. There is an atexit() function for Windows, so we can call cleanup functions during exit. An upcoming commit separately handles Ctrl+C so that we can call clean up functions for that use case. Signed-off-by: Gurucharan Shetty Acked-by: Ben Pfaff --- diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c index b1a0341f5..1e63d48d6 100644 --- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -41,7 +41,11 @@ VLOG_DEFINE_THIS_MODULE(fatal_signal); /* Signals to catch. */ +#ifndef _WIN32 static const int fatal_signals[] = { SIGTERM, SIGINT, SIGHUP, SIGALRM }; +#else +static const int fatal_signals[] = { SIGTERM }; +#endif /* Hooks to call upon catching a signal */ struct hook { @@ -55,6 +59,7 @@ static struct hook hooks[MAX_HOOKS]; static size_t n_hooks; static int signal_fds[2]; +HANDLE wevent; static volatile sig_atomic_t stored_sig_nr = SIG_ATOMIC_MAX; static struct ovs_mutex mutex; @@ -78,10 +83,19 @@ fatal_signal_init(void) inited = true; ovs_mutex_init_recursive(&mutex); +#ifndef _WIN32 xpipe_nonblocking(signal_fds); +#else + wevent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!wevent) { + char *msg_buf = ovs_lasterror_to_string(); + VLOG_FATAL("Failed to create a event (%s).", msg_buf); + } +#endif for (i = 0; i < ARRAY_SIZE(fatal_signals); i++) { int sig_nr = fatal_signals[i]; +#ifndef _WIN32 struct sigaction old_sa; xsigaction(sig_nr, NULL, &old_sa); @@ -89,6 +103,11 @@ fatal_signal_init(void) && signal(sig_nr, fatal_signal_handler) == SIG_ERR) { VLOG_FATAL("signal failed (%s)", ovs_strerror(errno)); } +#else + if (signal(sig_nr, fatal_signal_handler) == SIG_ERR) { + VLOG_FATAL("signal failed (%s)", ovs_strerror(errno)); + } +#endif } atexit(atexit_handler); } @@ -136,7 +155,11 @@ fatal_signal_add_hook(void (*hook_cb)(void *aux), void (*cancel_cb)(void *aux), void fatal_signal_handler(int sig_nr) { +#ifndef _WIN32 ignore(write(signal_fds[1], "", 1)); +#else + SetEvent(wevent); +#endif stored_sig_nr = sig_nr; } @@ -164,8 +187,12 @@ fatal_signal_run(void) ovs_mutex_lock(&mutex); +#ifndef _WIN32 VLOG_WARN("terminating with signal %d (%s)", (int)sig_nr, signal_name(sig_nr, namebuf, sizeof namebuf)); +#else + VLOG_WARN("terminating with signal %d", (int)sig_nr); +#endif call_hooks(sig_nr); /* Re-raise the signal with the default handling so that the program @@ -182,7 +209,7 @@ void fatal_signal_wait(void) { fatal_signal_init(); - poll_fd_wait(signal_fds[0], POLLIN); + poll_fd_wait_event(signal_fds[0], wevent, POLLIN); } static void diff --git a/lib/timeval.c b/lib/timeval.c index 691cf74e1..3e7719fe7 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -282,7 +282,12 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, #endif if (deadline <= time_msec()) { +#ifndef _WIN32 fatal_signal_handler(SIGALRM); +#else + VLOG_ERR("wake up from WaitForMultipleObjects after deadline"); + fatal_signal_handler(SIGTERM); +#endif if (retval < 0) { retval = 0; }