From: Stephen D. <sd...@gm...> - 2005-06-27 05:06:32
|
On 6/24/05, abe-t <it...@us...> wrote: > Update of /cvsroot/naviserver/naviserver/nsd > In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16846/nsd >=20 > Modified Files: > nswin32.c > Log Message: > Added provisions to fake that nsd as a service failed on Windows in ord= er > for the Service Control Manager to restart it automatically. >=20 >=20 > Index: nswin32.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > 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 =3D 0; > static SERVICE_STATUS curStatus; > *************** > *** 57,60 **** > --- 58,62 ---- > static int tick; > static int sigpending; > + static int servicefailed =3D 0; >=20 > #define SysErrMsg() (NsWin32ErrMsg(GetLastError())) > *************** > *** 349,353 **** > */ >=20 > ! void > NsHandleSignals(void) > { > --- 351,355 ---- > */ >=20 > ! int > NsHandleSignals(void) > { > *************** > *** 388,391 **** > --- 390,395 ---- > StartTicker(SERVICE_STOP_PENDING); > } > + > + return pending; > } >=20 > *************** > *** 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 =3D RegisterServiceCtrlHandler(argv[0], ServiceHandler); > ! if (hStatus =3D=3D 0) { > ! Ns_Fatal("nswin32: RegisterServiceCtrlHandler() failed: '%s'", > ! SysErrMsg()); > } > - curStatus.dwServiceType =3D SERVICE_WIN32_OWN_PROCESS; > - curStatus.dwServiceSpecificExitCode =3D 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"); > } >=20 > --- 937,964 ---- > ServiceMain(DWORD argc, LPTSTR *argv) > { > ! __try { > ! hStatus =3D RegisterServiceCtrlHandler(argv[0], ServiceHandler)= ; > ! if (hStatus =3D=3D 0) { > ! Ns_Fatal("nswin32: RegisterServiceCtrlHandler() failed: '%s= '", > ! SysErrMsg()); > ! } > ! curStatus.dwServiceType =3D SERVICE_WIN32_OWN_PROCESS; > ! curStatus.dwServiceSpecificExitCode =3D 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. > } > } >=20 > *************** > *** 1006,1009 **** > --- 1022,1028 ---- > curStatus.dwCurrentState =3D state; > curStatus.dwWin32ExitCode =3D code; > + if (code =3D=3D ERROR_SERVICE_SPECIFIC_ERROR) { > + curStatus.dwServiceSpecificExitCode =3D code; > + } > curStatus.dwWaitHint =3D hint; > if (state =3D=3D SERVICE_RUNNING || state =3D=3D SERVICE_STOPPED) { > *************** > *** 1090,1091 **** > --- 1109,1163 ---- > } >=20 > + > + /* > + *---------------------------------------------------------------------= - > + * > + * NsTclFailServiceObjCmd -- > + * > + * Tell the server not to unregister from the Service Control Manage= r > + * (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 =3D 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. |