From: abe-t <it...@us...> - 2005-06-24 08:40:36
|
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; + } + + /* + *---------------------------------------------------------------------- + * + * 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; + } |