Bug 84473 - Unable to timeout when attaching to a bogus debug port
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties
index f9a8f39..bceafd6 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties
@@ -16,6 +16,8 @@
SocketAttachingConnectorImpl.Host_2=Host
SocketAttachingConnectorImpl.Port_number_to_which_to_attach_for_VM_connections_3=Port number to which to attach for VM connections
SocketAttachingConnectorImpl.Port_4=Port
+SocketAttachingConnectorImpl.1=Connection Timeout
+SocketAttachingConnectorImpl.2=Connection Timeout
SocketAttachingConnectorImpl.Attaches_by_socket_to_other_VMs_5=Attaches by socket to other VMs
SocketAttachingConnectorImpl.Connection_argument_is_not_of_the_right_type_6=Connection argument is not of the right type
SocketAttachingConnectorImpl.Necessary_connection_argument_is_null_7=Necessary connection argument is null
@@ -63,3 +65,5 @@
PacketReceiveManager.Got_{0}_from_Virtual_Machine_1=Got {0} from Virtual Machine
PacketReceiveManager.Got_{0}_from_Virtual_Machine__{1}_1=Got {0} from Virtual Machine: {1}
PacketReceiveManager.0=Timeout occurred while waiting for packet {0}
+SocketTransportService.0=Attach Thread
+SocketTransportService.1=Handshake Thread
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketAttachingConnectorImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketAttachingConnectorImpl.java
index 343f28d..73aba21 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketAttachingConnectorImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketAttachingConnectorImpl.java
@@ -30,6 +30,7 @@
private String fHostname;
/** Port to which is attached. */
private int fPort;
+ private int fTimeout;
/**
* Creates new SocketAttachingConnectorImpl.
@@ -57,6 +58,10 @@
IntegerArgumentImpl intArg = new IntegerArgumentImpl("port", ConnectMessages.getString("SocketAttachingConnectorImpl.Port_number_to_which_to_attach_for_VM_connections_3"), ConnectMessages.getString("SocketAttachingConnectorImpl.Port_4"), true, SocketTransportImpl.MIN_PORTNR, SocketTransportImpl.MAX_PORTNR); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
arguments.put(intArg.name(), intArg);
+ // Timeout
+ IntegerArgumentImpl timeoutArg = new IntegerArgumentImpl("timeout", ConnectMessages.getString("SocketAttachingConnectorImpl.1"), ConnectMessages.getString("SocketAttachingConnectorImpl.2"), false, 0, Integer.MAX_VALUE); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ arguments.put(timeoutArg.name(), timeoutArg);
+
return arguments;
}
@@ -84,7 +89,14 @@
fHostname = ((Connector.StringArgument)connectionArgs.get(attribute)).value();
attribute = "port"; //$NON-NLS-1$
fPort = ((Connector.IntegerArgument)connectionArgs.get(attribute)).intValue();
- // TODO: new timeout attribute ?
+ attribute = "timeout"; //$NON-NLS-1$
+ Object object = connectionArgs.get(attribute);
+ if (object != null) {
+ Connector.IntegerArgument timeoutArg = (IntegerArgument) object;
+ if (timeoutArg.value() != null) {
+ fTimeout = timeoutArg.intValue();
+ }
+ }
} catch (ClassCastException e) {
throw new IllegalConnectorArgumentsException(ConnectMessages.getString("SocketAttachingConnectorImpl.Connection_argument_is_not_of_the_right_type_6"), attribute); //$NON-NLS-1$
} catch (NullPointerException e) {
@@ -102,7 +114,7 @@
getConnectionArguments(connectionArgs);
Connection connection = null;
try {
- connection = ((SocketTransportImpl)fTransport).attach(fHostname, fPort);
+ connection = ((SocketTransportImpl)fTransport).attach(fHostname, fPort, fTimeout, 0);
} catch (IllegalArgumentException e) {
List args = new ArrayList();
args.add("hostname"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportImpl.java
index 1e2b2b2..fa461ac 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportImpl.java
@@ -39,8 +39,8 @@
return TRANSPORT_NAME;
}
- public Connection attach(String hostname, int port) throws IOException {
- return service.attach(hostname, port, 0, 0);
+ public Connection attach(String hostname, int port, long attachTimeout, long handshakeTimeout) throws IOException {
+ return service.attach(hostname, port, attachTimeout, handshakeTimeout);
}
public String startListening(int port) throws IOException {
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java
index 7ae1435..d620692 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java
@@ -20,6 +20,8 @@
import java.net.SocketTimeoutException;
import java.util.Arrays;
+import org.eclipse.jdi.TimeoutException;
+
import com.sun.jdi.connect.TransportTimeoutException;
import com.sun.jdi.connect.spi.ClosedConnectionException;
import com.sun.jdi.connect.spi.Connection;
@@ -118,26 +120,46 @@
return attach(host, port, attachTimeout, handshakeTimeout);
}
- public Connection attach(String host, int port, long attachTimeout, long handshakeTimeout) throws IOException {
+ public Connection attach(final String host, final int port, long attachTimeout, final long handshakeTimeout) throws IOException {
if (attachTimeout > 0){
if (attachTimeout > Integer.MAX_VALUE) {
attachTimeout = Integer.MAX_VALUE; //approx 25 days!
}
- fSocket.setSoTimeout((int) attachTimeout);
}
+
+ final IOException[] ex = new IOException[1];
+ Thread attachThread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ fSocket = new Socket(host, port);
+ fInput = fSocket.getInputStream();
+ fOutput = fSocket.getOutputStream();
+ performHandshake(fInput, fOutput, handshakeTimeout);
+ } catch (IOException e) {
+ ex[0] = e;
+ }
+ }
+ }, ConnectMessages.getString("SocketTransportService.0")); //$NON-NLS-1$
+
+ attachThread.start();
try {
- fSocket = new Socket(host, port);
- } catch (SocketTimeoutException e) {
- throw new TransportTimeoutException();
+ attachThread.join(attachTimeout);
+ if (attachThread.isAlive()) {
+ attachThread.interrupt();
+ throw new TimeoutException();
+ }
+ } catch (InterruptedException e) {
}
- fInput = fSocket.getInputStream();
- fOutput = fSocket.getOutputStream();
- performHandshake(fInput, fOutput, handshakeTimeout);
+
+ if (ex[0] != null) {
+ throw ex[0];
+ }
+
+
return new SocketConnection(this);
}
void performHandshake(final InputStream in, final OutputStream out, final long timeout) throws IOException {
- final Object lock = new Object();
final IOException[] ex = new IOException[1];
final boolean[] handshakeCompleted = new boolean[1];
@@ -146,37 +168,31 @@
try {
writeHandshake(out);
readHandshake(in);
- synchronized(lock) {
- handshakeCompleted[0] = true;
- lock.notify();
- }
+ handshakeCompleted[0] = true;
} catch (IOException e) {
ex[0] = e;
}
}
- });
+ }, ConnectMessages.getString("SocketTransportService.1")); //$NON-NLS-1$
t.start();
- synchronized(lock) {
- try {
- if (!handshakeCompleted[0])
- lock.wait(timeout);
- } catch (InterruptedException e) {
- }
+ try {
+ t.join(timeout);
+ } catch (InterruptedException e1) {
}
-
+
if (handshakeCompleted[0])
return;
-
- if (ex[0] != null)
- throw ex[0];
-
+
try {
- in.close();
- out.close();
+ in.close();
+ out.close();
} catch (IOException e) {
}
+ if (ex[0] != null)
+ throw ex[0];
+
throw new TransportTimeoutException();
}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaRemoteApplicationLaunchConfigurationDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaRemoteApplicationLaunchConfigurationDelegate.java
index 5f8862d..7f116c4 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaRemoteApplicationLaunchConfigurationDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaRemoteApplicationLaunchConfigurationDelegate.java
@@ -59,6 +59,9 @@
}
Map argMap = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, (Map)null);
+
+ int connectTimeout = JavaRuntime.getPreferences().getInt(JavaRuntime.PREF_CONNECT_TIMEOUT);
+ argMap.put("timeout", ""+connectTimeout); //$NON-NLS-1$//$NON-NLS-2$
// check for cancellation
if (monitor.isCanceled()) {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java
index 28ae0e3..07ac2e0 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java
@@ -116,10 +116,18 @@
abort(LaunchingMessages.getString("SocketAttachConnector.Hostname_unspecified_for_remote_connection._4"), null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_HOSTNAME); //$NON-NLS-1$
}
Map map= connector.defaultArguments();
- Connector.Argument param= (Connector.Argument) map.get("hostname"); //$NON-NLS-1$
+
+ Connector.Argument param= (Connector.Argument) map.get("hostname"); //$NON-NLS-1$
param.setValue(host);
param= (Connector.Argument) map.get("port"); //$NON-NLS-1$
param.setValue(portNumberString);
+
+ String timeoutString = (String)arguments.get("timeout"); //$NON-NLS-1$
+ if (timeoutString != null) {
+ param= (Connector.Argument) map.get("timeout"); //$NON-NLS-1$
+ param.setValue(timeoutString);
+ }
+
ILaunchConfiguration configuration = launch.getLaunchConfiguration();
boolean allowTerminate = false;
if (configuration != null) {