--- 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));
}
--- 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);
--- 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();
--- 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);
}
--- 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<IPath> 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() {