1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

[208029] COM port not released after quick disconnect/reconnect

This commit is contained in:
Martin Oberhuber 2007-10-30 23:38:06 +00:00
parent 1d64f9e9bf
commit 0e1dd48e01
2 changed files with 96 additions and 37 deletions

View file

@ -14,6 +14,7 @@
* Michael Scharf (Wind River) - extracted from TerminalControl
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
* Martin Oberhuber (Wind River) - [207158] improve error message when port not available
* Martin Oberhuber (Wind River) - [208029] COM port not released after quick disconnect/reconnect
*******************************************************************************/
package org.eclipse.tm.internal.terminal.serial;
@ -26,6 +27,7 @@ import java.util.Arrays;
import java.util.Enumeration;
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
public class SerialConnectWorker extends Thread {
@ -41,7 +43,6 @@ public class SerialConnectWorker extends Thread {
super();
fControl = control;
fConn = conn;
fControl.setState(TerminalState.CONNECTING);
}
/**
@ -91,7 +92,7 @@ public class SerialConnectWorker extends Thread {
// nothing to do -- should never happen...
return;
}
// Reinitialise the ports because we have changed the list of known ports
// Reinitialize the ports because we have changed the list of known ports
CommPortIdentifier.getPortIdentifiers();
}
@ -101,6 +102,7 @@ public class SerialConnectWorker extends Thread {
//TODO [206884] This is part of API and should be changed for the next release
final String strID = getClass().getPackage().getName();
//final String strID = "org.eclipse.tm.terminal.serial"; //$NON-NLS-1$
SerialPort serialPort = null;
try {
fControl.setState(TerminalState.OPENED);
ISerialSettings s=fConn.getSerialSettings();
@ -116,7 +118,7 @@ public class SerialConnectWorker extends Thread {
fConn.setSerialPortIdentifier(CommPortIdentifier.getPortIdentifier(portName));
int timeoutInMs = s.getTimeout() * 1000;
SerialPort serialPort=(SerialPort) fConn.getSerialPortIdentifier().open(strID,timeoutInMs);
serialPort=(SerialPort) fConn.getSerialPortIdentifier().open(strID,timeoutInMs);
serialPort.setSerialPortParams(s.getBaudRate(), s.getDataBits(), s.getStopBits(), s.getParity());
serialPort.setFlowControlMode(s.getFlowControl());
serialPort.addEventListener(fConn.getSerialPortHandler());
@ -139,7 +141,22 @@ public class SerialConnectWorker extends Thread {
fControl.displayTextInTerminal("No such port: \"" + msg+"\"\r\n"); //$NON-NLS-1$ //$NON-NLS-2$
} catch (Exception exception) {
Logger.logException(exception);
if (serialPort!=null) {
//Event listener is removed as part of close(),
//but exceptions need to be caught to ensure that close() really succeeds
try {
serialPort.removeEventListener();
Thread.sleep(50); //allow a little time for RXTX Native to catch up - makes stuff more stable
} catch(Exception e) {
Logger.logException(e);
}
serialPort.close();
fConn.getSerialPortIdentifier().removePortOwnershipListener(fConn.getSerialPortHandler());
}
fControl.setState(TerminalState.CLOSED);
} finally {
fConn.doneConnect();
}
}
}

View file

@ -13,7 +13,8 @@
* Contributors:
* Michael Scharf (Wind River) - extracted from TerminalControl
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
* Martin Oberhuber (Wind River) - [206892] Dont connect if already connecting
* Martin Oberhuber (Wind River) - [206892] Don't connect if already connecting
* Martin Oberhuber (Wind River) - [208029] COM port not released after quick disconnect/reconnect
*******************************************************************************/
package org.eclipse.tm.internal.terminal.serial;
@ -42,7 +43,9 @@ public class SerialConnector implements ITerminalConnector {
private CommPortIdentifier fSerialPortIdentifier;
private SerialPortHandler fTerminalSerialPortHandler;
private SerialSettings fSettings;
private SerialConnectWorker fConnectWorker;
private SerialConnectWorker fConnectWorker = null;
private volatile boolean fDisconnectGoingOn = false;
public SerialConnector() {
}
public SerialConnector(SerialSettings settings) {
@ -58,16 +61,37 @@ public class SerialConnector implements ITerminalConnector {
}
public void connect(ITerminalControl control) {
Logger.log("entered."); //$NON-NLS-1$
if (fConnectWorker!=null && fConnectWorker.isAlive()) {
//already connecting
return;
synchronized(this) {
if (fConnectWorker!=null || fDisconnectGoingOn) {
//avoid multiple background connect/disconnect threads at the same time
return;
}
fConnectWorker = new SerialConnectWorker(this, control);
}
fConnectWorker = new SerialConnectWorker(this, control);
fControl=control;
fControl.setState(TerminalState.CONNECTING);
fConnectWorker.start();
}
/**
* Indicate that the connectWorker is finished.
*/
void doneConnect() {
synchronized(this) {
fConnectWorker = null;
}
}
public void disconnect() {
Logger.log("entered."); //$NON-NLS-1$
synchronized(this) {
//avoid multiple background connect/disconnect threads at the same time
if (fConnectWorker!=null) {
fConnectWorker.interrupt();
return;
} else if (fDisconnectGoingOn) {
return;
}
fDisconnectGoingOn = true;
}
// Fix for SPR 112422. When output is being received from the serial port, the
// below call to removePortOwnershipListener() attempts to lock the serial port
@ -85,37 +109,53 @@ public class SerialConnector implements ITerminalConnector {
new Thread("Terminal View Serial Port Disconnect Worker") //$NON-NLS-1$
{
public void run() {
if (getSerialPortIdentifier() != null) {
getSerialPortIdentifier()
.removePortOwnershipListener(getSerialPortHandler());
}
if (getSerialPort() != null) {
getSerialPort().removeEventListener();
Logger.log("Calling close() on serial port ..."); //$NON-NLS-1$
getSerialPort().close();
}
if (getInputStream() != null) {
try {
getInputStream().close();
} catch (Exception exception) {
Logger.logException(exception);
try {
if (getSerialPortIdentifier() != null) {
try {
getSerialPortIdentifier()
.removePortOwnershipListener(getSerialPortHandler());
} catch(Exception e) {
Logger.logException(e);
}
}
}
if (getOutputStream() != null) {
try {
getOutputStream().close();
} catch (Exception exception) {
Logger.logException(exception);
if (getSerialPort() != null) {
//Event listener is removed as part of close(),
//but exceptions need to be caught to ensure that close() really succeeds
try {
getSerialPort().removeEventListener();
Thread.sleep(50); //allow a little time for RXTX Native to catch up - makes stuff more stable
} catch(Exception e) {
Logger.logException(e);
}
Logger.log("Calling close() on serial port ..."); //$NON-NLS-1$
getSerialPort().close();
}
}
setSerialPortIdentifier(null);
cleanSerialPort();
setSerialPortHandler(null);
if (getInputStream() != null) {
try {
getInputStream().close();
} catch (Exception exception) {
Logger.logException(exception);
}
}
if (getOutputStream() != null) {
try {
getOutputStream().close();
} catch (Exception exception) {
Logger.logException(exception);
}
}
setSerialPortIdentifier(null);
cleanSerialPort();
setSerialPortHandler(null);
} catch(Exception e) {
Logger.logException(e);
} finally {
fDisconnectGoingOn = false;
}
}
}.start();
@ -165,6 +205,7 @@ public class SerialConnector implements ITerminalConnector {
return fSerialPortIdentifier;
}
protected void setSerialPortIdentifier(CommPortIdentifier serialPortIdentifier) {
//System.out.println("setSerialPortId: "+Thread.currentThread().getName()+ " - "+serialPortIdentifier + " - "+System.currentTimeMillis());
fSerialPortIdentifier = serialPortIdentifier;
}
void setSerialPortHandler(SerialPortHandler serialPortHandler) {
@ -175,6 +216,7 @@ public class SerialConnector implements ITerminalConnector {
}
public ISerialSettings getSerialSettings() {
return fSettings;
}
public ISettingsPage makeSettingsPage() {
return new SerialSettingsPage(fSettings);