PY-21278 Deadlock on closing PyCharm when Python debug server configuration is waiting for a script to be connected fixed

This commit is contained in:
Alexander Koshevoy
2016-10-30 02:27:40 +03:00
parent 0e5a4664b3
commit 7b6bf38ab7
@@ -5,7 +5,6 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import com.jetbrains.python.debugger.pydev.ProtocolFrame;
import com.jetbrains.python.debugger.pydev.RemoteDebugger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
@@ -20,10 +19,10 @@ public class ServerModeDebuggerTransport extends BaseDebuggerTransport {
private static final Logger LOG = Logger.getInstance(ServerModeDebuggerTransport.class);
@NotNull private final ServerSocket myServerSocket;
@Nullable private DebuggerReader myDebuggerReader;
private volatile DebuggerReader myDebuggerReader;
private volatile boolean myConnected = false;
@Nullable private Socket mySocket;
private volatile Socket mySocket;
private int myConnectionTimeout;
public ServerModeDebuggerTransport(RemoteDebugger debugger, @NotNull ServerSocket socket, int connectionTimeout) {
@@ -34,45 +33,44 @@ public class ServerModeDebuggerTransport extends BaseDebuggerTransport {
@Override
public void waitForConnect() throws IOException {
//noinspection SocketOpenedButNotSafelyClosed
myServerSocket.setSoTimeout(myConnectionTimeout);
synchronized (mySocketObject) {
//noinspection SocketOpenedButNotSafelyClosed
myServerSocket.setSoTimeout(myConnectionTimeout);
Socket socket = myServerSocket.accept();
mySocket = myServerSocket.accept();
myConnected = true;
try {
myDebuggerReader = new DebuggerReader(myDebugger, socket.getInputStream());
}
catch (IOException e) {
try {
socket.close();
}
catch (IOException ignore) {
}
throw e;
}
mySocket = socket;
// mySocket is closed in close() method on process termination
}
try {
synchronized (mySocketObject) {
myDebuggerReader = new DebuggerReader(myDebugger, mySocket.getInputStream());
}
}
catch (IOException e) {
try {
mySocket.close();
}
catch (IOException ignore) {
}
throw e;
}
// mySocket is closed in close() method on process termination
}
@Override
public void close() {
synchronized (mySocketObject) {
try {
if (myDebuggerReader != null) {
myDebuggerReader.stop();
}
try {
if (myDebuggerReader != null) {
myDebuggerReader.stop();
}
finally {
if (!myServerSocket.isClosed()) {
try {
myServerSocket.close();
}
catch (IOException e) {
LOG.warn("Error closing socket", e);
}
}
finally {
if (!myServerSocket.isClosed()) {
try {
myServerSocket.close();
}
catch (IOException e) {
LOG.warn("Error closing socket", e);
}
}
}
@@ -80,7 +78,7 @@ public class ServerModeDebuggerTransport extends BaseDebuggerTransport {
@Override
public boolean isConnected() {
return myConnected && mySocket != null && !mySocket.isClosed();
return myConnected && mySocket != null && !mySocket.isClosed();
}
@Override