Author: mturk Date: Sun Mar 18 08:04:48 2007 New Revision: 519622 URL: http://svn.apache.org/viewvc?view=rev&rev=519622 Log: Fix JIRA DAEMON-34. Use the maximum system timeout for shutdown. Patch provided from Robert Longson.
Modified: jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/apps/prunsrv/prunsrv.c jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/registry.h jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/service.h jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/src/registry.c Modified: jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/apps/prunsrv/prunsrv.c URL: http://svn.apache.org/viewvc/jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/apps/prunsrv/prunsrv.c?view=diff&rev=519622&r1=519621&r2=519622 ============================================================================== --- jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/apps/prunsrv/prunsrv.c (original) +++ jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/apps/prunsrv/prunsrv.c Sun Mar 18 08:04:48 2007 @@ -32,6 +32,10 @@ #include <fcntl.h> #include <io.h> /* _open_osfhandle */ +#ifndef MIN +#define MIN(a,b) (((a)<(b)) ? (a) : (b)) +#endif + #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 @@ -796,12 +800,13 @@ } /* Executed when the service receives stop event */ -static DWORD serviceStop() +static DWORD WINAPI serviceStop(LPVOID lpParameter) { APXHANDLE hWorker = NULL; DWORD rv = 0; BOOL wait_to_die = FALSE; DWORD timeout = SO_STOPTIMEOUT * 1000; + DWORD dwCtrlType = (DWORD)((BYTE *)lpParameter - (BYTE *)0); apxLogWrite(APXLOG_MARK_INFO "Stopping service..."); @@ -918,6 +923,10 @@ if (wait_to_die && !timeout) timeout = 300 * 1000; /* Use the 5 minute default shutdown */ + if (dwCtrlType == SERVICE_CONTROL_SHUTDOWN) + timeout = MIN(timeout, apxGetMaxServiceTimeout(gPool)); + reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, timeout); + if (timeout) { FILETIME fts, fte; ULARGE_INTEGER s, e; @@ -945,6 +954,7 @@ } apxLogWrite(APXLOG_MARK_INFO "Service stopped."); + reportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0); return rv; } @@ -1063,19 +1073,40 @@ */ void WINAPI service_ctrl_handler(DWORD dwCtrlCode) { + DWORD threadId; + HANDLE stopThread; + switch (dwCtrlCode) { case SERVICE_CONTROL_STOP: - apxLogWrite(APXLOG_MARK_INFO "Service STOP signaled"); - reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); - /* Call the stop handler that will actualy stop the service */ - serviceStop(); + reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 3000); + /* Stop the service asynchronously */ + stopThread = CreateThread(NULL, 0, + serviceStop, + (LPVOID)SERVICE_CONTROL_STOP, + 0, &threadId); + WaitForSingleObject(stopThread, INFINITE); + CloseHandle(stopThread); + + return; + case SERVICE_CONTROL_SHUTDOWN: + apxLogWrite(APXLOG_MARK_INFO "Service SHUTDOWN signaled"); + reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 3000); + /* Stop the service asynchronously */ + stopThread = CreateThread(NULL, 0, + serviceStop, + (LPVOID)SERVICE_CONTROL_SHUTDOWN, + 0, &threadId); + WaitForSingleObject(stopThread, INFINITE); + CloseHandle(stopThread); return; case SERVICE_CONTROL_INTERROGATE: - break; + reportServiceStatus(_service_status.dwCurrentState, + _service_status.dwWin32ExitCode, + _service_status.dwWaitHint); + return; default: - break; + break; } - reportServiceStatus(_service_status.dwCurrentState, NO_ERROR, 0); } /* Console control handler @@ -1089,20 +1120,20 @@ return FALSE; case CTRL_C_EVENT: apxLogWrite(APXLOG_MARK_INFO "Console CTRL+C event signaled"); - serviceStop(); + serviceStop((LPVOID)SERVICE_CONTROL_STOP); return TRUE; case CTRL_CLOSE_EVENT: apxLogWrite(APXLOG_MARK_INFO "Console CTRL+CLOSE event signaled"); - serviceStop(); + serviceStop((LPVOID)SERVICE_CONTROL_STOP); return TRUE; case CTRL_SHUTDOWN_EVENT: apxLogWrite(APXLOG_MARK_INFO "Console SHUTDOWN event signaled"); - serviceStop(); + serviceStop((LPVOID)SERVICE_CONTROL_SHUTDOWN); return TRUE; case CTRL_LOGOFF_EVENT: apxLogWrite(APXLOG_MARK_INFO "Console LOGOFF event signaled"); if (!_service_mode) { - serviceStop(); + serviceStop((LPVOID)SERVICE_CONTROL_STOP); } return TRUE; break; Modified: jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/registry.h URL: http://svn.apache.org/viewvc/jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/registry.h?view=diff&rev=519622&r1=519621&r2=519622 ============================================================================== --- jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/registry.h (original) +++ jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/registry.h Sun Mar 18 08:04:48 2007 @@ -134,7 +134,6 @@ BOOL apxRegistryDeleteW(APXHANDLE hRegistry, DWORD dwFrom, LPCWSTR szSubkey, LPCWSTR szValueName); - #ifdef _UNICODE #define apxRegistryDelete apxRegistryDeleteW #else Modified: jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/service.h URL: http://svn.apache.org/viewvc/jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/service.h?view=diff&rev=519622&r1=519621&r2=519622 ============================================================================== --- jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/service.h (original) +++ jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/include/service.h Sun Mar 18 08:04:48 2007 @@ -68,6 +68,8 @@ LPAPXFNCALLBACK fnDisplayCallback, LPVOID lpCbData); +DWORD apxGetMaxServiceTimeout(APXHANDLE hPool); + __APXEND_DECLS #endif /* _SERVICE_H_INCLUDED_ */ Modified: jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/src/registry.c URL: http://svn.apache.org/viewvc/jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/src/registry.c?view=diff&rev=519622&r1=519621&r2=519622 ============================================================================== --- jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/src/registry.c (original) +++ jakarta/commons/proper/daemon/trunk/src/native/nt/procrun/src/registry.c Sun Mar 18 08:04:48 2007 @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include "apxwin.h" #include "private.h" @@ -32,12 +32,14 @@ static LPCWSTR JAVA_RUNTIME = L"RuntimeLib"; static LPCWSTR JAVA_HOME = L"JAVA_HOME"; static LPCWSTR JAVAHOME = L"JavaHome"; +static LPCWSTR CONTROL_REGKEY = L"SYSTEM\\CurrentControlSet\\Control"; +static LPCWSTR REGTIMEOUT = L"WaitToKillServiceTimeout"; #define REG_CAN_CREATE(r) \ - ((r)->samOptions & KEY_CREATE_SUB_KEY) + ((r)->samOptions & KEY_CREATE_SUB_KEY) #define REG_CAN_WRITE(r) \ - ((r)->samOptions & KEY_SET_VALUE) + ((r)->samOptions & KEY_SET_VALUE) #define REG_GET_KEY(r, w, k) \ @@ -58,7 +60,7 @@ typedef struct APXREGSUBKEY APXREGSUBKEY; struct APXREGSUBKEY { - APXHANDLE hRegistry; + APXHANDLE hRegistry; HKEY hKey; LPCTSTR syKeyName; TAILQ_ENTRY(APXREGSUBKEY); @@ -74,7 +76,7 @@ HKEY hSparamKey; /* service\\Parameters */ HKEY hUparamKey; /* service\\Parameters */ REGSAM samOptions; - /** list enty for opened subkeys */ + /** list enty for opened subkeys */ TAILQ_HEAD(_lSubkeys, APXREGSUBKEY) lSubkeys; }; @@ -93,11 +95,11 @@ lpReg = APXHANDLE_DATA(hObject); switch (uMsg) { case WM_CLOSE: - SAFE_CLOSE_KEY(lpReg->hCurrKey); + SAFE_CLOSE_KEY(lpReg->hCurrKey); SAFE_CLOSE_KEY(lpReg->hRparamKey); SAFE_CLOSE_KEY(lpReg->hSparamKey); SAFE_CLOSE_KEY(lpReg->hUparamKey); - SAFE_CLOSE_KEY(lpReg->hRootKey); + SAFE_CLOSE_KEY(lpReg->hRootKey); SAFE_CLOSE_KEY(lpReg->hServKey); SAFE_CLOSE_KEY(lpReg->hUserKey); break; @@ -240,17 +242,17 @@ return NULL; /* make the HKLM\\SOFTWARE key */ - lstrcpyW(buff, REGSOFTWARE_ROOT); + lstrcpyW(buff, REGSOFTWARE_ROOT); if (szRoot) lstrcatW(buff, szRoot); else - lstrcatW(buff, REGAPACHE_ROOT); + lstrcatW(buff, REGAPACHE_ROOT); lstrcatW(buff, REGSEPARATOR); lstrcatW(buff, szKeyName); /* Open or create the root key */ if (dwOptions & APXREG_SOFTWARE) { if (samDesired & KEY_CREATE_SUB_KEY) - rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, buff, 0, NULL, 0, + rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, buff, 0, NULL, 0, samDesired, NULL, &hRootKey, NULL); else @@ -262,7 +264,7 @@ } /* Open or create the root parameters key */ if (samDesired & KEY_CREATE_SUB_KEY) - rc = RegCreateKeyExW(hRootKey, REGPARAMS, 0, NULL, 0, + rc = RegCreateKeyExW(hRootKey, REGPARAMS, 0, NULL, 0, samDesired, NULL, &hRparamKey, NULL); else @@ -277,7 +279,7 @@ if (dwOptions & APXREG_USER) { /* Open or create the users root key */ if (samDesired & KEY_CREATE_SUB_KEY) - rc = RegCreateKeyExW(HKEY_CURRENT_USER, buff, 0, NULL, 0, + rc = RegCreateKeyExW(HKEY_CURRENT_USER, buff, 0, NULL, 0, samDesired, NULL, &hUserKey, NULL); else @@ -289,7 +291,7 @@ } /* Open or create the users parameters key */ if (samDesired & KEY_CREATE_SUB_KEY) - rc = RegCreateKeyExW(hUserKey, REGPARAMS, 0, NULL, 0, + rc = RegCreateKeyExW(hUserKey, REGPARAMS, 0, NULL, 0, samDesired, NULL, &hUparamKey, NULL); else @@ -302,7 +304,7 @@ } /* Check if we need a service key */ if (dwOptions & APXREG_SERVICE) { - lstrcpyW(buff, REGSERVICE_ROOT); + lstrcpyW(buff, REGSERVICE_ROOT); lstrcatW(buff, szKeyName); /* Service has to be created allready */ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, buff, 0, @@ -313,7 +315,7 @@ } /* Open or create the root parameters key */ if (samDesired & KEY_CREATE_SUB_KEY) - rc = RegCreateKeyExW(hServKey, REGPARAMS, 0, NULL, 0, + rc = RegCreateKeyExW(hServKey, REGPARAMS, 0, NULL, 0, samDesired, NULL, &hSparamKey, NULL); else @@ -350,7 +352,7 @@ SAFE_CLOSE_KEY(hRootKey); SAFE_CLOSE_KEY(hServKey); SAFE_CLOSE_KEY(hUserKey); - + SetLastError(rc); return NULL; } @@ -378,7 +380,7 @@ { LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return NULL; lpReg = APXHANDLE_DATA(hRegistry); @@ -405,7 +407,7 @@ { LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return NULL; lpReg = APXHANDLE_DATA(hRegistry); @@ -433,7 +435,7 @@ { LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return NULL; lpReg = APXHANDLE_DATA(hRegistry); @@ -471,7 +473,7 @@ { LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return NULL; lpReg = APXHANDLE_DATA(hRegistry); @@ -510,7 +512,7 @@ DWORD dwRval, rl; DWORD rc, dwType = REG_DWORD; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return 0; lpReg = APXHANDLE_DATA(hRegistry); @@ -541,7 +543,7 @@ { LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return NULL; lpReg = APXHANDLE_DATA(hRegistry); @@ -581,7 +583,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_BINARY; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -614,7 +616,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_BINARY; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -647,7 +649,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_MULTI_SZ; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -680,7 +682,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_SZ; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -700,7 +702,7 @@ } if (!szValue || !lstrlenA(szValue)) { if (RegDeleteValueA(hKey, szValueName) != ERROR_SUCCESS) - return FALSE; + return FALSE; } else if (RegSetValueExA(hKey, szValueName, 0, dwType, (LPBYTE)szValue, lstrlenA(szValue)) != ERROR_SUCCESS) @@ -717,7 +719,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_SZ; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -737,7 +739,7 @@ } if (!szValue || !lstrlenW(szValue)) { if (RegDeleteValueW(hKey, szValueName) != ERROR_SUCCESS) - return FALSE; + return FALSE; } else if (RegSetValueExW(hKey, szValueName, 0, dwType, (LPBYTE)szValue, @@ -755,7 +757,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_DWORD; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -789,7 +791,7 @@ LPAPXREGISTRY lpReg; HKEY hKey, hSub = NULL; DWORD dwType = REG_SZ; - if (IS_INVALID_HANDLE(hRegistry) || + if (IS_INVALID_HANDLE(hRegistry) || hRegistry->dwType != APXHANDLE_TYPE_REGISTRY) return FALSE; lpReg = APXHANDLE_DATA(hRegistry); @@ -826,23 +828,23 @@ if (szRoot && lstrlenW(szRoot) > SIZ_RESMAX) return FALSE; - lstrcpyW(buff, REGSOFTWARE_ROOT); + lstrcpyW(buff, REGSOFTWARE_ROOT); if (szRoot) lstrcatW(buff, szRoot); else - lstrcatW(buff, REGAPACHE_ROOT); + lstrcatW(buff, REGAPACHE_ROOT); lstrcatW(buff, REGSEPARATOR); lstrcatW(buff, szKeyName); - + rv = SHDeleteKeyW(HKEY_LOCAL_MACHINE, buff); rv += SHDeleteKeyW(HKEY_CURRENT_USER, buff); if (bDeleteEmpty) { - lstrcpyW(buff, REGSOFTWARE_ROOT); + lstrcpyW(buff, REGSOFTWARE_ROOT); if (szRoot) lstrcatW(buff, szRoot); else - lstrcatW(buff, REGAPACHE_ROOT); + lstrcatW(buff, REGAPACHE_ROOT); SHDeleteEmptyKeyW(HKEY_LOCAL_MACHINE, buff); SHDeleteEmptyKeyW(HKEY_CURRENT_USER, buff); @@ -891,12 +893,12 @@ 0, KEY_READ, &hKey)) != ERROR_SUCCESS) { return NULL; } - if ((err = RegQueryValueExW(hKey, JAVA_CURRENT, NULL, NULL, + if ((err = RegQueryValueExW(hKey, JAVA_CURRENT, NULL, NULL, (LPBYTE)off, &dwLen)) != ERROR_SUCCESS) { RegCloseKey(hKey); return NULL; - } + } RegCloseKey(hKey); if ((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wsBuf, 0, KEY_READ, &hKey)) != ERROR_SUCCESS) { @@ -926,12 +928,12 @@ 0, KEY_READ, &hKey)) != ERROR_SUCCESS) { return NULL; } - if ((err = RegQueryValueExW(hKey, JAVA_CURRENT, NULL, NULL, + if ((err = RegQueryValueExW(hKey, JAVA_CURRENT, NULL, NULL, (LPBYTE)off, &dwLen)) != ERROR_SUCCESS) { RegCloseKey(hKey); return NULL; - } + } RegCloseKey(hKey); if ((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wsBuf, 0, KEY_READ, &hKey)) != ERROR_SUCCESS) { @@ -948,8 +950,8 @@ BOOL apxRegistryEnumServices(LPAPXREGENUM lpEnum, LPAPXSERVENTRY lpEntry) { DWORD rc, dwLength = SIZ_RESLEN; - - if (IS_INVALID_HANDLE(lpEnum->hServicesKey)) { + + if (IS_INVALID_HANDLE(lpEnum->hServicesKey)) { rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, REGSERVICE_ROOT, 0, KEY_READ, &(lpEnum->hServicesKey)); if (rc != ERROR_SUCCESS) { @@ -1008,7 +1010,7 @@ return TRUE; } -/* We could use the ChangeServiceConfig2 on WIN2K+ +/* We could use the ChangeServiceConfig2 on WIN2K+ * For now use the registry. */ BOOL apxSetServiceDescriptionW(LPCWSTR szServiceName, LPCWSTR szDescription) @@ -1021,12 +1023,12 @@ return FALSE; lstrcpyW(wcName, REGSERVICE_ROOT); lstrcatW(wcName, szServiceName); - + rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wcName, 0, KEY_WRITE, &hKey); if (rc != ERROR_SUCCESS) { return FALSE; } - + rc = RegSetValueExW(hKey, REGDESCRIPTION, 0, REG_SZ, (CONST BYTE *)szDescription, lstrlenW(szDescription) * sizeof(WCHAR)); SAFE_CLOSE_KEY(hKey); @@ -1045,7 +1047,7 @@ return FALSE; lstrcpyW(wcName, REGSERVICE_ROOT); lstrcatW(wcName, szServiceName); - + rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wcName, 0, KEY_READ, &hKey); if (rc != ERROR_SUCCESS) { return FALSE; @@ -1070,7 +1072,7 @@ return FALSE; lstrcpyW(wcName, REGSERVICE_ROOT); lstrcatW(wcName, szServiceName); - + rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wcName, 0, KEY_READ, &hKey); if (rc != ERROR_SUCCESS) { return FALSE; @@ -1082,4 +1084,29 @@ return TRUE; else return FALSE; +} + +DWORD apxGetMaxServiceTimeout(APXHANDLE hPool) +{ + DWORD maxTimeout = 20000; + LPWSTR wsMaxTimeout; + DWORD err; + HKEY hKey; + WCHAR wsBuf[SIZ_BUFLEN]; + + lstrcpyW(wsBuf, CONTROL_REGKEY); + + if ((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wsBuf, + 0, KEY_READ, &hKey)) != ERROR_SUCCESS) { + return maxTimeout; + } + wsMaxTimeout = __apxGetRegistrySzW(hPool, hKey, REGTIMEOUT); + RegCloseKey(hKey); + + if (wsMaxTimeout[0]) { + maxTimeout = (DWORD)apxAtoulW(wsMaxTimeout); + } + apxFree(wsMaxTimeout); + + return maxTimeout; } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]