On 6/24/05, abe-t <[EMAIL PROTECTED]> wrote:
> Update of /cvsroot/naviserver/naviserver/nsd
> In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16846/nsd
>
> Modified Files:
> nswin32.c
> Log Message:
> Added provisions to fake that nsd as a service failed on Windows in order
> for the Service Control Manager to restart it automatically.
>
>
> Index: nswin32.c
> ===================================================================
> RCS file: /cvsroot/naviserver/naviserver/nsd/nswin32.c,v
> retrieving revision 1.6
> retrieving revision 1.7
> diff -C2 -d -r1.6 -r1.7
> *** nswin32.c 13 Jun 2005 10:17:27 -0000 1.6
> --- nswin32.c 24 Jun 2005 08:40:27 -0000 1.7
> ***************
> *** 51,54 ****
> --- 51,55 ----
> static void ExitService(void);
> static char *GetServiceName(Ns_DString *dsPtr, char *server);
> + static int ReportException(int ec, char *msg);
> static SERVICE_STATUS_HANDLE hStatus = 0;
> static SERVICE_STATUS curStatus;
> ***************
> *** 57,60 ****
> --- 58,62 ----
> static int tick;
> static int sigpending;
> + static int servicefailed = 0;
>
> #define SysErrMsg() (NsWin32ErrMsg(GetLastError()))
> ***************
> *** 349,353 ****
> */
>
> ! void
> NsHandleSignals(void)
> {
> --- 351,355 ----
> */
>
> ! int
> NsHandleSignals(void)
> {
> ***************
> *** 388,391 ****
> --- 390,395 ----
> StartTicker(SERVICE_STOP_PENDING);
> }
> +
> + return pending;
> }
>
> ***************
> *** 413,416 ****
> --- 417,421 ----
> switch (sig) {
> case NS_SIGTERM:
> + case NS_SIGINT:
> case NS_SIGHUP:
> Ns_MutexLock(&lock);
> ***************
> *** 932,948 ****
> ServiceMain(DWORD argc, LPTSTR *argv)
> {
> ! hStatus = RegisterServiceCtrlHandler(argv[0], ServiceHandler);
> ! if (hStatus == 0) {
> ! Ns_Fatal("nswin32: RegisterServiceCtrlHandler() failed: '%s'",
> ! SysErrMsg());
> }
> - curStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
> - curStatus.dwServiceSpecificExitCode = 0;
> - StartTicker(SERVICE_START_PENDING);
> - Ns_Main(argc, argv, NULL);
> - StopTicker();
> - ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 100);
> - ReportStatus(SERVICE_STOPPED, 0, 0);
> - Ns_Log(Notice, "nswin32: service exiting");
> }
>
> --- 937,964 ----
> ServiceMain(DWORD argc, LPTSTR *argv)
> {
> ! __try {
> ! hStatus = RegisterServiceCtrlHandler(argv[0], ServiceHandler);
> ! if (hStatus == 0) {
> ! Ns_Fatal("nswin32: RegisterServiceCtrlHandler() failed: '%s'",
> ! SysErrMsg());
> ! }
> ! curStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
> ! curStatus.dwServiceSpecificExitCode = 0;
> ! StartTicker(SERVICE_START_PENDING);
> ! Ns_Main(argc, argv, NULL);
> ! StopTicker();
> ! ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 100);
> ! if (!servicefailed) {
> ! ReportStatus(SERVICE_STOPPED, 0, 0);
> ! }
> ! Ns_Log(Notice, "nswin32: service exiting");
> !
> ! if(servicefailed) {
> ! exit(-1);
> ! }
> ! }
> ! __except (ReportException(GetExceptionCode(), "ServiceMain")) {
> ! // No code; this block is never executed.
> }
> }
>
> ***************
> *** 1006,1009 ****
> --- 1022,1028 ----
> curStatus.dwCurrentState = state;
> curStatus.dwWin32ExitCode = code;
> + if (code == ERROR_SERVICE_SPECIFIC_ERROR) {
> + curStatus.dwServiceSpecificExitCode = code;
> + }
> curStatus.dwWaitHint = hint;
> if (state == SERVICE_RUNNING || state == SERVICE_STOPPED) {
> ***************
> *** 1090,1091 ****
> --- 1109,1163 ----
> }
>
> +
> + /*
> + *----------------------------------------------------------------------
> + *
> + * NsTclFailServiceObjCmd --
> + *
> + * Tell the server not to unregister from the Service Control Manager
> + * (SCM) when exiting, effectively leaving SCM wondering about the
> + * service, thinking it failed and restarting it
> + * (provided restarting the serice is configured in SCM).
> + *
> + * Results:
> + * None.
> + *
> + *----------------------------------------------------------------------
> + */
> +
> + int
> + NsTclFailServiceObjCmd(ClientData dummy, Tcl_Interp *interp, int argc, char
> **argv)
> + {
> + servicefailed = 1;
> +
> + return TCL_OK;
> + }
This Windows only command asks for a restart, right? This should be
hooked up to the -restart switch of the ns_shutdown command, which is
essentially the same thing. Otherwise, Tcl programmers will have to
test the current platform to portably restart the server.
> + /*
> + *----------------------------------------------------------------------
> + *
> + * reportException --
> + *
> + * Handle expecptions - cause the server to terminate abruptly
> + * and leave a log trace. It is intended to prevents the default
> + * handling in Windows where a Window pops up and the user has to
> + * confirm - which then prevents the service control manager to
> + * restart the service. (The idea, however, does not seem to work
> + * as intended - Windows still brings up the popup for reporting
> + * the "bug" to Microsoft).
> + *
> + * Results:
> + * None.
> + *
> + * Side effects:
> + * Exits the server
> + *
> + *----------------------------------------------------------------------
> + */
> +
> + static int ReportException(int ec, char *msg)
> + {
> + fprintf(stderr, "EXCEPTION %x in %s\n", ec, msg); fflush(stderr);
> + exit(-1);
> + return EXCEPTION_EXECUTE_HANDLER;
> + }
If this is experimental debugging code it probably shouldn't be
committed to CVS. It does look pretty experimental -- there's no way
this function will return a value after calling exit(), for example.