diff -r 3b26c948790f -r 6743933eec70 connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp --- a/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp Wed Feb 10 13:45:43 2010 -0600 +++ b/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp Wed Feb 10 14:32:22 2010 -0600 @@ -488,7 +488,32 @@ TCDEBUGLOGA1("CClientManager::StartServer end numRefs = %d\n", pData->numRefs); return ret; } - +BOOL CClientManager::IsTCFServerActive(DWORD processId) +{ + HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId); + if (h) + { + // is it really still alive? + DWORD exitCode = -5; + BOOL exitCall = ::GetExitCodeProcess(h, &exitCode); + ::CloseHandle(h); + if (exitCall == TRUE && exitCode != STILL_ACTIVE) + { + // TCFServer is really dead + return FALSE; + } + else + { + // TCFServer is still active + return TRUE; + } + } + else + { + // TCFServer is really dead + return FALSE; + } +} long CClientManager::StopServer() { long ret = TCAPI_ERR_NONE; @@ -516,23 +541,34 @@ // substract ref count pData->numRefs--; if (pData->numRefs < 0) pData->numRefs = 0; + + bool sendStop = true; + if (!IsTCFServerActive(pData->serverProcess.dwProcessId)) + { + sendStop = false; + pData->numRefs = 0; + } + // if refcount == 0 then really stop the server process if (pData->numRefs == 0) { - // last client process is closing - // tell server to exit - ServerCommandData cmdrsp; - cmdrsp.command = eCmdExit; - - TCDEBUGLOGS(" SendCommand eCmdExit\n"); - m_Server->SendCommand(&cmdrsp); - TCDEBUGLOGS(" GetResponse eExit\n"); - m_Server->GetResponse(&cmdrsp); - - // wait for process to exit - TCDEBUGLOGS(" WaitForSingleObject start\n"); - DWORD waitErr = ::WaitForSingleObject(m_hServer, 10000L /*INFINITE*/); - TCDEBUGLOGA1("CClientManager::StopServer WaitForSingleObject = %d\n", waitErr); + if (sendStop) + { + // last client process is closing + // tell server to exit + ServerCommandData cmdrsp; + cmdrsp.command = eCmdExit; + + TCDEBUGLOGS(" SendCommand eCmdExit\n"); + m_Server->SendCommand(&cmdrsp); + TCDEBUGLOGS(" GetResponse eExit\n"); + m_Server->GetResponse(&cmdrsp); + + // wait for process to exit + TCDEBUGLOGS(" WaitForSingleObject start\n"); + DWORD waitErr = ::WaitForSingleObject(m_hServer, 10000L /*INFINITE*/); + TCDEBUGLOGA1("CClientManager::StopServer WaitForSingleObject = %d\n", waitErr); + } // now close our handle to server process if (m_hServer != NULL) @@ -580,11 +616,14 @@ BOOL CClientManager::IsServerRunning() { pServerProcessData pData = m_Server->GetProcessPtr(); - if (pData->serverProcess.hProcess != NULL) + if (IsTCFServerActive(pData->serverProcess.dwProcessId)) + { return TRUE; + } else + { return FALSE; - + } } void CClientManager::CreateLockFile(DWORD processId) @@ -640,8 +679,8 @@ void CClientManager::DeleteFromLockFile(DWORD serverProcessId) { - DWORD callingId[10]; - DWORD serverId[10]; + DWORD creatorIds[10]; + DWORD serverIds[10]; int numIds = 0; DWORD ourProcessId = ::GetCurrentProcessId(); @@ -663,16 +702,16 @@ BOOL done = FALSE; while (!done) { - DWORD cId = 0xffffffff; - DWORD sId = 0xffffffff; - int n = fscanf(f, "%ld %ld\n", &cId, &sId); + DWORD creatorId = 0xffffffff; + DWORD serverId = 0xffffffff; + int n = fscanf(f, "%ld %ld\n", &creatorId, &serverId); if (n == 2) { - TCDEBUGLOGA3("CClientManager::DeleteFromLockFile numIds=%d sId=%d pId=%d\n", numIds, cId, sId); - if (cId != ourProcessId || sId != serverProcessId) + TCDEBUGLOGA3("CClientManager::DeleteFromLockFile numIds=%d creatorId=%d serverId=%d\n", numIds, creatorId, serverId); + if (creatorId != ourProcessId || serverId != serverProcessId) { - callingId[numIds] = cId; - serverId[numIds] = sId; + creatorIds[numIds] = creatorId; + serverIds[numIds] = serverId; numIds++; if (numIds > 9) done = TRUE; @@ -695,7 +734,7 @@ { for (int i = 0; i < numIds; i++) { - fprintf(f, "%ld %ld\n", callingId[i], serverId[i]); + fprintf(f, "%ld %ld\n", creatorIds[i], serverIds[i]); } fclose(f); } @@ -708,8 +747,8 @@ // we should not have more than a few Carbide processes connecting to the same TCFServer void CClientManager::TerminateServerThroughLockFile(pServerProcessData pData) { - DWORD callingId[10]; - DWORD serverId[10]; + DWORD creatorIds[10]; + DWORD serverIds[10]; BOOL liveCaller[10]; int numIds = 0; if (m_ServerLockFile != NULL) @@ -729,14 +768,14 @@ BOOL done = FALSE; while (!done) { - DWORD cId = 0xffffffff; - DWORD sId = 0xffffffff; - int n = fscanf(f, "%ld %ld\n", &cId, &sId); + DWORD creatorId = 0xffffffff; + DWORD serverId = 0xffffffff; + int n = fscanf(f, "%ld %ld\n", &creatorId, &serverId); if (n == 2) { - TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile n=%d sId=%d pId=%d\n", n, cId, sId); - callingId[numIds] = cId; - serverId[numIds] = sId; + TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile n=%d creatorId=%d serverId=%d\n", n, creatorId, serverId); + creatorIds[numIds] = creatorId; + serverIds[numIds] = serverId; numIds++; if (numIds > 9) done = TRUE; @@ -751,28 +790,40 @@ int numDeadCallers = 0; for (int i = 0; i < numIds; i++) { - HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, callingId[i]); + HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, creatorIds[i]); if (h) { // calling process is still alive liveCaller[i] = TRUE; + DWORD exitCode = -5; + BOOL exitCall = ::GetExitCodeProcess(h, &exitCode); + DWORD id = ::GetCurrentProcessId(); ::CloseHandle(h); - TCDEBUGLOGA1("CClientManager::TerminateServerThroughLockFile %d alive\n", callingId[i]); + TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d alive exitCall=%d currentId=%d\n", creatorIds[i], exitCall, id); + if (exitCall == TRUE && exitCode != STILL_ACTIVE) + { + liveCaller[i] = FALSE; + numDeadCallers++; + } + { + TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile exitCode=%d still_active=%d\n", exitCode, STILL_ACTIVE); + } } else { liveCaller[i] = FALSE; numDeadCallers++; DWORD err = ::GetLastError(); - TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d dead err=%d:%s\n", callingId[i], err, GetErrorText(err)); + TCDEBUGLOGA3("CClientManager::TerminateServerThroughLockFile %d dead err=%d:%s\n", creatorIds[i], err, GetErrorText(err)); } } if (numDeadCallers == numIds) { + // All clients of this TCFServer are dead // terminate the TCFServer, and delete lock file pData->numRefs = 0; ::remove(m_ServerLockFile); - HANDLE h = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, serverId[0]); + HANDLE h = ::OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, serverIds[0]); if (h) { BOOL ret = ::TerminateProcess(h, -1); @@ -786,27 +837,43 @@ } else { - // leave TCFServer running, recreate lock file and save live callers - ::remove(m_ServerLockFile); - f = fopen(m_ServerLockFile, "wt"); - if (f) + // some java clients are still alive + // check to see if TCFServer is still alive + if (IsTCFServerActive(serverIds[0])) { - for (int i = 0; i < numIds; i++) + // TCFServer is still active + // leave TCFServer running, recreate lock file and save live callers + ::remove(m_ServerLockFile); + f = fopen(m_ServerLockFile, "wt"); + if (f) { - if (liveCaller[i]) + for (int i = 0; i < numIds; i++) { - fprintf(f, "%ld %ld\n", callingId[i], serverId[i]); + if (liveCaller[i]) + { + fprintf(f, "%ld %ld\n", creatorIds[i], serverIds[i]); + } } + fclose(f); } - fclose(f); + pData->numRefs -= numDeadCallers; + if (pData->numRefs < 0) pData->numRefs = 0; } - pData->numRefs -= numDeadCallers; - if (pData->numRefs < 0) pData->numRefs = 0; + else + { + // TCFServer is really dead + pData->numRefs = 0; + ::remove(m_ServerLockFile); + } } } else { // error opening lock file + // perhaps the user deleted it, + // if so, we assume he has also deleted the TCFServer as we now have no way of verifying if the + // process is dead. + pData->numRefs = 0; DWORD err = ::GetLastError(); TCDEBUGLOGA2("CClientManager::TerminateServerThroughLockFile fopenErr=%d:%s\n", err, GetErrorText(err)); }