@@ -4045,9 +4045,16 @@ management_sleep(const int n)
{
management_event_loop_n_seconds(management, n);
}
- else if (n > 0)
+ else
{
- sleep(n);
+#ifdef _WIN32
+ win32_sleep(n);
+#else
+ if (n > 0)
+ {
+ sleep(n);
+ }
+#endif
}
}
@@ -4088,13 +4095,18 @@ man_persist_client_stats(struct management *man, struct context *c)
#else /* ifdef ENABLE_MANAGEMENT */
+#include "win32.h"
void
management_sleep(const int n)
{
+#ifdef _WIN32
+ win32_sleep(n);
+#else
if (n > 0)
{
sleep(n);
}
+#endif /* ifdef _WIN32 */
}
#endif /* ENABLE_MANAGEMENT */
@@ -642,50 +642,44 @@ int
win32_signal_get(struct win32_signal *ws)
{
int ret = 0;
- if (siginfo_static.signal_received)
- {
- ret = siginfo_static.signal_received;
- }
- else
+
+ if (ws->mode == WSO_MODE_SERVICE)
{
- if (ws->mode == WSO_MODE_SERVICE)
+ if (win32_service_interrupt(ws))
{
- if (win32_service_interrupt(ws))
- {
- ret = SIGTERM;
- }
+ ret = SIGTERM;
}
- else if (ws->mode == WSO_MODE_CONSOLE)
+ }
+ else if (ws->mode == WSO_MODE_CONSOLE)
+ {
+ switch (win32_keyboard_get(ws))
{
- switch (win32_keyboard_get(ws))
- {
- case 0x3B: /* F1 -> USR1 */
- ret = SIGUSR1;
- break;
+ case 0x3B: /* F1 -> USR1 */
+ ret = SIGUSR1;
+ break;
- case 0x3C: /* F2 -> USR2 */
- ret = SIGUSR2;
- break;
+ case 0x3C: /* F2 -> USR2 */
+ ret = SIGUSR2;
+ break;
- case 0x3D: /* F3 -> HUP */
- ret = SIGHUP;
- break;
+ case 0x3D: /* F3 -> HUP */
+ ret = SIGHUP;
+ break;
- case 0x3E: /* F4 -> TERM */
- ret = SIGTERM;
- break;
+ case 0x3E: /* F4 -> TERM */
+ ret = SIGTERM;
+ break;
- case 0x03: /* CTRL-C -> TERM */
- ret = SIGTERM;
- break;
- }
- }
- if (ret)
- {
- throw_signal(ret); /* this will update signinfo_static.signal received */
+ case 0x03: /* CTRL-C -> TERM */
+ ret = SIGTERM;
+ break;
}
}
- return ret;
+ if (ret)
+ {
+ throw_signal(ret); /* this will update signinfo_static.signal received */
+ }
+ return (siginfo_static.signal_received);
}
void
@@ -1603,4 +1597,47 @@ set_openssl_env_vars()
}
}
+void
+win32_sleep(const int n)
+{
+ if (n < 0)
+ {
+ return;
+ }
+
+ /* Sleep() is not interruptible. Use a WAIT_OBJECT to catch signal */
+
+ if (!HANDLE_DEFINED(win32_signal.in.read))
+ {
+ if (n > 0)
+ {
+ Sleep(n*1000);
+ }
+ return;
+ }
+
+ update_time();
+ time_t expire = now + n;
+
+ while (expire >= now)
+ {
+ DWORD status = WaitForSingleObject(win32_signal.in.read, (expire-now)*1000);
+ if ((status == WAIT_OBJECT_0 && win32_signal_get(&win32_signal))
+ || status == WAIT_TIMEOUT)
+ {
+ return;
+ }
+
+ update_time();
+
+ if (status != WAIT_OBJECT_0) /* wait failed or some unexpected error ? */
+ {
+ if (expire > now)
+ {
+ Sleep((expire-now)*1000);
+ }
+ return;
+ }
+ }
+}
#endif /* ifdef _WIN32 */
@@ -330,5 +330,8 @@ openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in
bool
openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const format, ...);
+/* Sleep that can be interrupted by signals and exit event */
+void win32_sleep(const int n);
+
#endif /* ifndef OPENVPN_WIN32_H */
#endif /* ifdef _WIN32 */