# HG changeset patch # User fturovic # Date 1265834307 21600 # Node ID fbd0e7c75ee186927a49e56d50e1eff231537544 # Parent ddd7e0935476d71d2632a21a863f829fdea6892d# Parent 6743933eec70aa90ae86c94bd11616be5623e189 daily merge diff -r ddd7e0935476 -r fbd0e7c75ee1 connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp --- a/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp Wed Feb 10 14:37:13 2010 -0600 +++ b/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.cpp Wed Feb 10 14:38:27 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)); } diff -r ddd7e0935476 -r fbd0e7c75ee1 connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.h --- a/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.h Wed Feb 10 14:37:13 2010 -0600 +++ b/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/ClientManager.h Wed Feb 10 14:38:27 2010 -0600 @@ -70,6 +70,7 @@ void AppendToLockFile(DWORD processId); void DeleteLockFile(); void DeleteFromLockFile(DWORD processId); + BOOL IsTCFServerActive(DWORD processId); // input stream CInputStream* FindInputStream(long inClientId); diff -r ddd7e0935476 -r fbd0e7c75ee1 connectivity/com.nokia.tcf/native/TCFNative/TCFClient/TCAPIConnectionJni.cpp --- a/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/TCAPIConnectionJni.cpp Wed Feb 10 14:37:13 2010 -0600 +++ b/connectivity/com.nokia.tcf/native/TCFNative/TCFClient/TCAPIConnectionJni.cpp Wed Feb 10 14:38:27 2010 -0600 @@ -84,6 +84,13 @@ TCDEBUGOPEN(); TCDEBUGLOGS("nativeConnect\n"); + if (!gManager->IsServerRunning()) + { + TCDEBUGLOGS("Server not running\n"); + TCDEBUGCLOSE(); + return TCAPI_ERR_COMM_SERVER_RESPONSE_TIMEOUT; + } + gManager->m_Server->WaitforServerPipeAccess(); @@ -1255,6 +1262,13 @@ TCDEBUGOPEN(); TCDEBUGLOGS("nativeSendMessage\n"); TCDEBUGLOGA1(" inClientId=%d\n", inClientId); + if (!gManager->IsServerRunning()) + { + // return right away if TCFServer is dead + TCDEBUGLOGS("nativeSendMessage: server is dead\n"); + TCDEBUGCLOSE(); + return TCAPI_ERR_COMM_SERVER_RESPONSE_TIMEOUT; + } gManager->m_Server->WaitforServerPipeAccess(); diff -r ddd7e0935476 -r fbd0e7c75ee1 connectivity/com.nokia.tcf/src/com/nokia/tcf/impl/TCAPIConnection.java --- a/connectivity/com.nokia.tcf/src/com/nokia/tcf/impl/TCAPIConnection.java Wed Feb 10 14:37:13 2010 -0600 +++ b/connectivity/com.nokia.tcf/src/com/nokia/tcf/impl/TCAPIConnection.java Wed Feb 10 14:38:27 2010 -0600 @@ -46,7 +46,12 @@ } catch (UnsatisfiedLinkError e) { // if Carbide DLL is not found in DE, // try to load one from the plugin itself - System.loadLibrary("TCFClient"); + try { + System.loadLibrary("TCFClient"); + } catch (UnsatisfiedLinkError e2) { + // no native TCF, e.g., not on Windows or in a misconfigured dev layout + e2.printStackTrace(); + } } } } @@ -354,6 +359,23 @@ this.cookie.setConnected(true); this.connection = inConnection; this.messageOptions = inMessageOptions; + } else if (ret == TCErrorConstants.TCAPI_ERR_COMM_SERVER_RESPONSE_TIMEOUT){ + // TCFServer may have died, attempt to restart it + ret = nativeStartServer(); + if (ret == TCErrorConstants.TCAPI_ERR_NONE) { + // now try connecting again + ret = nativeConnect(type, options, settings, moptions, filePath, clientId); + if (ret == TCErrorConstants.TCAPI_ERR_NONE) { + this.cookie.setClientId(clientId[0]); + this.cookie.setConnected(true); + this.connection = inConnection; + this.messageOptions = inMessageOptions; + } else { + status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null); + } + } else { + status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null); + } } else { status = new Status(Status.ERROR, Activator.PLUGIN_ID, (int)ret, TCErrorConstants.getErrorMessage(ret), null); } diff -r ddd7e0935476 -r fbd0e7c75ee1 debuggercdi/com.nokia.cdt.debug.launch/src/com/nokia/cdt/internal/debug/launch/newwizard/DebugRunProcessDialog.java --- a/debuggercdi/com.nokia.cdt.debug.launch/src/com/nokia/cdt/internal/debug/launch/newwizard/DebugRunProcessDialog.java Wed Feb 10 14:37:13 2010 -0600 +++ b/debuggercdi/com.nokia.cdt.debug.launch/src/com/nokia/cdt/internal/debug/launch/newwizard/DebugRunProcessDialog.java Wed Feb 10 14:38:27 2010 -0600 @@ -19,6 +19,7 @@ import java.io.File; import java.text.MessageFormat; +import java.util.List; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; @@ -43,8 +44,6 @@ import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; @@ -156,9 +155,6 @@ attachToProcessRadioButton.setSelection(true); break; } - handleProjectExecutableRadioSelected(); - handleRemoteExecutableRadioSelected(); - handleAttachToProcessRadioSelected(); } private void createPackageConfiguration(Composite composite) { @@ -332,7 +328,8 @@ public void handleEvent(CProjectDescriptionEvent event) { - if (getShell().isDisposed()) { + Shell shell = getShell(); + if (shell == null || shell.isDisposed()) { return; } @@ -365,29 +362,31 @@ } } - - - - - - protected void initUI() { - projectExecutableViewer.setInput(data.getExes()); - - if (data.getExeSelection() == EExeSelection.USE_PROJECT_EXECUTABLE && data.getExeSelectionPath() != null) { - projectExecutableViewer.setSelection(new StructuredSelection(data.getExeSelectionPath())); + List exes = data.getExes(); + projectExecutableViewer.setInput(exes); + IPath exeSelectionPath = data.getExeSelectionPath(); + if (exeSelectionPath.equals(Path.EMPTY) && !exes.isEmpty()) + exeSelectionPath = exes.get(0); + projectExecutableViewer.setSelection(new StructuredSelection(exeSelectionPath)); + IPath remotePath = createSuggestedRemotePath(exeSelectionPath); + remoteProgramEntry.setText(PathUtils.convertPathToWindows(remotePath)); + + if (data.getExeSelection() == EExeSelection.USE_PROJECT_EXECUTABLE && exeSelectionPath != null) { projectExecutableRadioButton.forceFocus(); } - if (data.getExeSelection() == EExeSelection.USE_REMOTE_EXECUTABLE && data.getExeSelectionPath() != null) { - IPath exeSelectionPath = createSuggestedRemotePath(data.getExeSelectionPath()); - remoteProgramEntry.setText(PathUtils.convertPathToWindows(exeSelectionPath)); + if (data.getExeSelection() == EExeSelection.USE_REMOTE_EXECUTABLE && exeSelectionPath != null) { remoteExecutableRadioButton.forceFocus(); } if (data.getExeSelection() == EExeSelection.ATTACH_TO_PROCESS) { attachToProcessRadioButton.forceFocus(); } + + handleProjectExecutableRadioSelected(); + handleRemoteExecutableRadioSelected(); + handleAttachToProcessRadioSelected(); } @@ -451,7 +450,11 @@ if (projectExecutableRadioButton.getSelection()) { projectExecutableViewer.getControl().setEnabled(true); data.setExeSelection(EExeSelection.USE_PROJECT_EXECUTABLE); - + IPath selectedPath = (IPath) ((IStructuredSelection) projectExecutableViewer.getSelection()).getFirstElement(); + if (selectedPath != null) { + String symbianPath = PathUtils.convertPathToWindows(selectedPath); + data.setExeSelectionPath(new Path(symbianPath)); + } validate(); } else { projectExecutableViewer.getControl().setEnabled(false); @@ -483,14 +486,12 @@ }); - remoteProgramEntry.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { + remoteProgramEntry.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { data.setExeSelectionPath(new Path(remoteProgramEntry.getText().trim())); validate(); } }); - } private void handleRemoteExecutableRadioSelected() {