in src/native/windows/apps/prunsrv/prunsrv.c [1670:1903]
void WINAPI serviceMain(DWORD argc, LPTSTR *argv)
{
DWORD rc = 0;
_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
_service_status.dwCurrentState = SERVICE_START_PENDING;
_service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE;
_service_status.dwWin32ExitCode = 0;
_service_status.dwCheckPoint = 0;
_service_status.dwWaitHint = 0;
_service_status.dwServiceSpecificExitCode = 0;
apxLogWrite(APXLOG_MARK_DEBUG "Inside serviceMain()...");
if (IS_VALID_STRING(_service_name)) {
WCHAR en[SIZ_HUGLEN];
int i;
PSECURITY_ATTRIBUTES sa = GetNullACL();
lstrlcpyW(en, SIZ_DESLEN, L"Global\\");
lstrlcatW(en, SIZ_DESLEN, _service_name);
lstrlcatW(en, SIZ_DESLEN, PRSRV_SIGNAL);
for (i = 7; i < lstrlenW(en); i++) {
if (en[i] == L' ')
en[i] = L'_';
else
en[i] = towupper(en[i]);
}
gSignalEvent = CreateEventW(sa, TRUE, FALSE, en);
CleanNullACL((void *)sa);
if (gSignalEvent) {
DWORD tid;
gSignalThread = CreateThread(NULL, 0, eventThread, NULL, 0, &tid);
}
}
/* Check the StartMode */
if (IS_VALID_STRING(SO_STARTMODE)) {
if (!lstrcmpiW(SO_STARTMODE, PRSRV_JVM)) {
_jni_startup = TRUE;
if (IS_VALID_STRING(SO_STARTCLASS)) {
_jni_rclass = WideToANSI(SO_STARTCLASS);
/* Exchange all dots with slashes */
apxStrCharReplaceA(_jni_rclass, '.', '/');
}
else {
/* Presume its main */
_jni_rclass = WideToANSI(L"Main");
}
_jni_rparam = SO_STARTPARAMS;
}
else if (!lstrcmpiW(SO_STARTMODE, PRSRV_JAVA)) {
LPWSTR jx = NULL, szJH = SO_JAVAHOME;
if (!szJH)
szJH = apxGetJavaSoftHome(gPool, FALSE);
else if (!lstrcmpiW(szJH, PRSRV_JDK)) {
/* Figure out the JDK JavaHome */
szJH = apxGetJavaSoftHome(gPool, FALSE);
}
else if (!lstrcmpiW(szJH, PRSRV_JRE)) {
/* Figure out the JRE JavaHome */
szJH = apxGetJavaSoftHome(gPool, TRUE);
}
if (szJH) {
jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
lstrcpyW(jx, szJH);
lstrcatW(jx, PRSRV_JBIN);
if (!SO_STARTPATH) {
/* Use JAVA_HOME/bin as start path */
LPWSTR szJP = apxPoolAlloc(gPool, (lstrlenW(szJH) + 8) * sizeof(WCHAR));
lstrcpyW(szJP, szJH);
lstrcatW(szJP, PRSRV_PBIN);
SO_STARTPATH = szJP;
}
}
else {
apxLogWrite(APXLOG_MARK_ERROR "Unable to find Java Runtime Environment.");
goto cleanup;
}
_java_startup = TRUE;
/* StartImage now contains the full path to the java.exe */
SO_STARTIMAGE = jx;
}
}
/* Check the StopMode */
if (IS_VALID_STRING(SO_STOPMODE)) {
if (!lstrcmpiW(SO_STOPMODE, PRSRV_JVM)) {
_jni_shutdown = TRUE;
if (IS_VALID_STRING(SO_STOPCLASS)) {
_jni_sclass = WideToANSI(SO_STOPCLASS);
apxStrCharReplaceA(_jni_sclass, '.', '/');
}
else {
/* Defaults to Main */
_jni_sclass = WideToANSI(L"Main");
}
_jni_sparam = SO_STOPPARAMS;
}
else if (!lstrcmpiW(SO_STOPMODE, PRSRV_JAVA)) {
LPWSTR jx = NULL, szJH = SO_JAVAHOME;
if (!szJH)
szJH = apxGetJavaSoftHome(gPool, FALSE);
else if (!lstrcmpiW(szJH, PRSRV_JDK)) {
/* Figure out the JDK JavaHome */
szJH = apxGetJavaSoftHome(gPool, FALSE);
}
else if (!lstrcmpiW(szJH, PRSRV_JRE)) {
/* Figure out the JRE JavaHome */
szJH = apxGetJavaSoftHome(gPool, TRUE);
}
if (szJH) {
jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
lstrcpyW(jx, szJH);
lstrcatW(jx, PRSRV_JBIN);
if (!SO_STOPPATH) {
LPWSTR szJP = apxPoolAlloc(gPool, (lstrlenW(szJH) + 8) * sizeof(WCHAR));
lstrcpyW(szJP, szJH);
lstrcatW(szJP, PRSRV_PBIN);
/* Use JAVA_HOME/bin as stop path */
SO_STOPPATH = szJP;
}
}
else {
apxLogWrite(APXLOG_MARK_ERROR "Unable to find Java Runtime Environment.");
goto cleanup;
}
_java_shutdown = TRUE;
/* StopImage now contains the full path to the java.exe */
SO_STOPIMAGE = jx;
}
}
/* Find the classpath */
if (_jni_shutdown || _jni_startup) {
if (IS_VALID_STRING(SO_JVM)) {
if (lstrcmpW(SO_JVM, PRSRV_AUTO))
_jni_jvmpath = SO_JVM;
}
if (IS_VALID_STRING(SO_CLASSPATH))
_jni_classpath = WideToANSI(SO_CLASSPATH);
if (IS_VALID_STRING(SO_STARTMETHOD))
_jni_rmethod = WideToANSI(SO_STARTMETHOD);
if (IS_VALID_STRING(SO_STOPMETHOD))
_jni_smethod = WideToANSI(SO_STOPMETHOD);
_jni_jvmoptions = MzWideToANSI(SO_JVMOPTIONS);
_jni_jvmoptions9 = MzWideToANSI(SO_JVMOPTIONS9);
}
if (_service_mode) {
/* Register Service Control handler */
_service_status_handle = RegisterServiceCtrlHandlerW(_service_name,
service_ctrl_handler);
if (IS_INVALID_HANDLE(_service_status_handle)) {
apxLogWrite(APXLOG_MARK_ERROR "Failed to register Service Control for '%S'.",
_service_name);
goto cleanup;
}
/* Allocate console so that events gets processed */
if (!AttachConsole(ATTACH_PARENT_PROCESS) &&
GetLastError() == ERROR_INVALID_HANDLE) {
HWND hc;
AllocConsole();
if ((hc = GetConsoleWindow()) != NULL)
ShowWindow(hc, SW_HIDE);
}
}
reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
if ((rc = serviceStart()) == 0) {
/* Service is started */
reportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0);
apxLogWrite(APXLOG_MARK_DEBUG "Waiting for worker to finish...");
/* Set console handler to capture CTRL events */
SetConsoleCtrlHandler((PHANDLER_ROUTINE)console_handler, TRUE);
if (SO_STOPTIMEOUT) {
/* we have a stop timeout */
BOOL bLoopWarningIssued = FALSE;
do {
/* wait 2 seconds */
DWORD rv = apxHandleWait(gWorker, 2000, FALSE);
if (rv == WAIT_OBJECT_0 && !_exe_shutdown) {
if (!bLoopWarningIssued) {
apxLogWrite(APXLOG_MARK_WARN "Start method returned before stop method was called. This should not happen. Using loop with a fixed sleep of 2 seconds waiting for stop method to be called.");
bLoopWarningIssued = TRUE;
}
Sleep(2000);
}
} while (!_exe_shutdown);
apxLogWrite(APXLOG_MARK_DEBUG "waiting %d sec... shutdown: %d", SO_STOPTIMEOUT, _exe_shutdown);
apxHandleWait(gWorker, SO_STOPTIMEOUT*1000, FALSE);
} else {
apxHandleWait(gWorker, INFINITE, FALSE);
}
apxLogWrite(APXLOG_MARK_DEBUG "Worker finished.");
}
else {
apxLogWrite(APXLOG_MARK_ERROR "ServiceStart returned %d.", rc);
goto cleanup;
}
if (gShutdownEvent) {
/* Ensure that shutdown thread exits before us */
apxLogWrite(APXLOG_MARK_DEBUG "Waiting for ShutdownEvent.");
reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, ONE_MINUTE);
WaitForSingleObject(gShutdownEvent, ONE_MINUTE);
apxLogWrite(APXLOG_MARK_DEBUG "ShutdownEvent signaled.");
CloseHandle(gShutdownEvent);
gShutdownEvent = NULL;
/* This will cause to wait for all threads to exit
*/
apxLogWrite(APXLOG_MARK_DEBUG "Waiting 1 minute for all threads to exit.");
reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, ONE_MINUTE);
apxDestroyJvm(ONE_MINUTE);
/* if we are not using JAVA apxDestroyJvm does nothing, check the chid processes in case they hang */
apxProcessTerminateChild( GetCurrentProcessId(), FALSE); /* FALSE kills! */
}
else {
/* We came here without shutdown event
* Probably because main() returned without ensuring all threads
* have finished
*/
apxLogWrite(APXLOG_MARK_DEBUG "Waiting for all threads to exit.");
apxDestroyJvm(INFINITE);
reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
}
apxLogWrite(APXLOG_MARK_DEBUG "JVM destroyed.");
reportServiceStatusStopped(apxGetVmExitCode());
return;
cleanup:
/* Cleanup */
reportServiceStatusStopped(rc);
gExitval = rc;
return;
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
}