From 03985084e42e262bac1b7c48a97c31db97348f1d Mon Sep 17 00:00:00 2001 From: Jan Kloetzke Date: Tue, 31 Jul 2012 21:08:31 +0200 Subject: erlsrv: gracefully stop emulator on Windows shutdown Windows will send the SERVICE_CONTROL_SHUTDOWN event to the service control handler when shutting down the system. Instead of ignoring the event, erlsrv will now invoke the stop action. Likewise, the Erlang emulator (and it's port drivers) must not quit upon reception of the CTRL_SHUTDOWN_EVENT event in the console control handler. --- erts/doc/src/erlsrv.xml | 13 ++++++++----- erts/emulator/sys/win32/sys_interrupt.c | 4 ++-- erts/etc/win32/erlsrv/erlsrv_service.c | 3 +-- erts/etc/win32/port_entry.c | 2 ++ erts/etc/win32/start_erl.c | 3 +++ 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml index c1ecbc7b77..b2f34ed247 100644 --- a/erts/doc/src/erlsrv.xml +++ b/erts/doc/src/erlsrv.xml @@ -357,11 +357,12 @@ The environment of an Erlang machine started the console subsystem and programs running as window applications. An application which runs in the console subsystem (normal for port programs) uses the win32 function - to a control handler that returns - TRUE in answer to the . Other - applications just forward and - to the default window procedure. Here - is a brief example in C of how to set the console control + to register a control handler + that returns TRUE in answer to the + and events. Other applications + just forward and + to the default window procedure. + Here is a brief example in C of how to set the console control handler:

@@ -372,6 +373,8 @@ The environment of an Erlang machine started BOOL WINAPI service_aware_handler(DWORD ctrl){ if(ctrl == CTRL_LOGOFF_EVENT) return TRUE; + if(ctrl == CTRL_SHUTDOWN_EVENT) + return TRUE; return FALSE; } diff --git a/erts/emulator/sys/win32/sys_interrupt.c b/erts/emulator/sys/win32/sys_interrupt.c index 347c31053b..a507a19480 100644 --- a/erts/emulator/sys/win32/sys_interrupt.c +++ b/erts/emulator/sys/win32/sys_interrupt.c @@ -75,11 +75,11 @@ BOOL WINAPI ctrl_handler_ignore_break(DWORD dwCtrlType) return TRUE; break; case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: if (nohup) return TRUE; /* else pour through... */ case CTRL_CLOSE_EVENT: - case CTRL_SHUTDOWN_EVENT: erl_exit(0, ""); break; } @@ -127,11 +127,11 @@ BOOL WINAPI ctrl_handler(DWORD dwCtrlType) SetEvent(erts_sys_break_event); break; case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: if (nohup) return TRUE; /* else pour through... */ case CTRL_CLOSE_EVENT: - case CTRL_SHUTDOWN_EVENT: erl_exit(0, ""); break; } diff --git a/erts/etc/win32/erlsrv/erlsrv_service.c b/erts/etc/win32/erlsrv/erlsrv_service.c index 242e2905a9..8b734b0c05 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.c +++ b/erts/etc/win32/erlsrv/erlsrv_service.c @@ -104,11 +104,10 @@ static VOID WINAPI handler(DWORD control){ log_debug(buffer); switch(control){ case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: set_stop_pending(30000,1); SetEvent(eventStop); return; - case SERVICE_CONTROL_SHUTDOWN: - return; default: reset_current(); break; diff --git a/erts/etc/win32/port_entry.c b/erts/etc/win32/port_entry.c index 49b5ad2f34..9c3e750cbc 100644 --- a/erts/etc/win32/port_entry.c +++ b/erts/etc/win32/port_entry.c @@ -45,6 +45,8 @@ extern void mainCRTStartup(void); BOOL WINAPI erl_port_default_handler(DWORD ctrl){ if(ctrl == CTRL_LOGOFF_EVENT) return TRUE; + if(ctrl == CTRL_SHUTDOWN_EVENT) + return TRUE; return FALSE; } diff --git a/erts/etc/win32/start_erl.c b/erts/etc/win32/start_erl.c index 28c8e55bd3..41b221d5bc 100644 --- a/erts/etc/win32/start_erl.c +++ b/erts/etc/win32/start_erl.c @@ -585,6 +585,9 @@ BOOL WINAPI LogoffHandlerRoutine( DWORD dwCtrlType ) if(dwCtrlType == CTRL_LOGOFF_EVENT) { return TRUE; } + if(dwCtrlType == CTRL_SHUTDOWN_EVENT) { + return TRUE; + } return FALSE; } -- cgit v1.2.3