[pywin32-checkins] pywin32/win32/src PythonService.cpp,1.13,1.14
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
|
From: Mark H. <mha...@us...> - 2004-09-10 21:55:58
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24075 Modified Files: PythonService.cpp Log Message: * Add RunningAsService() * Correctly initialize a static array (which I'm amazed didn't crash!) * Prevent 2 log messages on a simple import error. * Add extra comments to indicate how the control flow. Index: PythonService.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/PythonService.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** PythonService.cpp 20 Feb 2004 08:10:43 -0000 1.13 --- PythonService.cpp 10 Sep 2004 06:58:57 -0000 1.14 *************** *** 36,39 **** --- 36,40 ---- TCHAR g_szEventSourceName[MAX_PATH] = _T("Python Service"); BOOL bServiceDebug = FALSE; + BOOL bServiceRunning = FALSE; // Globals *************** *** 68,72 **** // The global SCM dispatch table. A trailing NULL indicates to the SCM // how many are used - as we add new entries, we null the next. ! static SERVICE_TABLE_ENTRY DispatchTable[] = { { NULL, NULL } --- 69,73 ---- // The global SCM dispatch table. A trailing NULL indicates to the SCM // how many are used - as we add new entries, we null the next. ! static SERVICE_TABLE_ENTRY DispatchTable[MAX_SERVICES] = { { NULL, NULL } *************** *** 321,324 **** --- 322,336 ---- } + // @pymethod True/False|servicemanager|RunningAsService|Indicates if the code is + // being executed as a service. + static PyObject *PyRunningAsService(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":RunningAsService")) + return NULL; + PyObject *rc = bServiceRunning ? Py_True : Py_False; + Py_INCREF(rc); + return rc; + } + // @pymethod int|servicemanager|PumpWaitingMessages|Pumps all waiting messages. // @rdesc Returns 1 if a WM_QUIT message was received, else 0 *************** *** 442,445 **** --- 454,458 ---- {"PrepareToHostSingle", PyPrepareToHostSingle, 1}, // @pymeth PrepareToHostSingle| {"PrepareToHostMultiple", PyPrepareToHostMultiple, 1}, // @pymeth PrepareToHostMultiple| + {"RunningAsService", PyRunningAsService, 1}, // @pymeth RunningAsService|Indicates if the code is running as a service. {NULL} }; *************** *** 736,742 **** --- 749,763 ---- PyObject *start = NULL; + bServiceRunning = TRUE; if (bServiceDebug) SetConsoleCtrlHandler( DebugControlHandler, TRUE ); + // NOTE: If possible, we want to always call RegisterServiceCtrlHandlerEx, + // even in error situations. Otherwise Windows will get a little upset + // and turn us into a zombie. Grabbing the service handle and reporting + // an error condition works correctly, whereas exiting doesn't. + // Note also that in the usual, non-error case, + // RegisterServiceCtrlHandlerEx is actually called via the Python code + // (servicemanager.RegisterServiceCtrlHandler), not via us. CEnterLeavePython _celp; PY_SERVICE_TABLE_ENTRY *pe; *************** *** 753,760 **** LPTSTR lpszStrings[] = {lpszArgv[0], NULL}; ReportError(E_PYS_NO_SERVICE, (LPCTSTR *)lpszStrings); goto cleanup; } assert(pe->sshStatusHandle==0); // should have no scm handle yet. ! instance = LoadPythonServiceInstance(pe->klass, dwArgc, lpszArgv); // If Python has not yet registered the service control handler, then // we are in serious trouble - it is likely the service will enter a --- 774,784 ---- LPTSTR lpszStrings[] = {lpszArgv[0], NULL}; ReportError(E_PYS_NO_SERVICE, (LPCTSTR *)lpszStrings); + // This is still yucky and will send us zombie. It should never happen + // and needs too much of a reorg to fix. goto cleanup; } assert(pe->sshStatusHandle==0); // should have no scm handle yet. ! if (pe->klass) // avoid an extra redundant log message. ! instance = LoadPythonServiceInstance(pe->klass, dwArgc, lpszArgv); // If Python has not yet registered the service control handler, then // we are in serious trouble - it is likely the service will enter a *************** *** 764,771 **** // is rooted (that is a technical term!) if (!bServiceDebug && pe->sshStatusHandle==0) { ! // If Python seemed to init OK, but hasnt done what we expect, ! // report an error, as we are gunna fail! if (instance) ReportPythonError(E_PYS_NOT_CONTROL_HANDLER); if (!bServiceDebug) // Note - we upgraded this to the win2k only "Ex" function. --- 788,798 ---- // is rooted (that is a technical term!) if (!bServiceDebug && pe->sshStatusHandle==0) { ! // If we don't have a pe->sshStatusHandle(), then the Python code ! // failed to register itself with the SCM. ! // If we have an instance, it means that instance simply neglected ! // to do the right thing - report that as an error. if (instance) ReportPythonError(E_PYS_NOT_CONTROL_HANDLER); + // else no instance - an error has already been reported. if (!bServiceDebug) // Note - we upgraded this to the win2k only "Ex" function. *************** *** 1011,1020 **** if (obPath==NULL) { ReportPythonError(PYS_E_NO_SYS_PATH); ! return FALSE; } PyObject *obNew = PyString_FromString(valueBuf); if (obNew==NULL) { ReportPythonError(PYS_E_NO_MEMORY_FOR_SYS_PATH); ! return FALSE; } PyList_Append(obPath, obNew); --- 1038,1047 ---- if (obPath==NULL) { ReportPythonError(PYS_E_NO_SYS_PATH); ! return NULL; } PyObject *obNew = PyString_FromString(valueBuf); if (obNew==NULL) { ReportPythonError(PYS_E_NO_MEMORY_FOR_SYS_PATH); ! return NULL; } PyList_Append(obPath, obNew); |