mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 02:36:01 +02:00
[208029] COM port not released after quick disconnect/reconnect
This commit is contained in:
parent
1d64f9e9bf
commit
0e1dd48e01
2 changed files with 96 additions and 37 deletions
|
@ -14,6 +14,7 @@
|
||||||
* Michael Scharf (Wind River) - extracted from TerminalControl
|
* Michael Scharf (Wind River) - extracted from TerminalControl
|
||||||
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
|
* 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) - [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;
|
package org.eclipse.tm.internal.terminal.serial;
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ import java.util.Arrays;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
|
||||||
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
|
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;
|
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
|
||||||
|
|
||||||
public class SerialConnectWorker extends Thread {
|
public class SerialConnectWorker extends Thread {
|
||||||
|
@ -41,7 +43,6 @@ public class SerialConnectWorker extends Thread {
|
||||||
super();
|
super();
|
||||||
fControl = control;
|
fControl = control;
|
||||||
fConn = conn;
|
fConn = conn;
|
||||||
fControl.setState(TerminalState.CONNECTING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,7 +92,7 @@ public class SerialConnectWorker extends Thread {
|
||||||
// nothing to do -- should never happen...
|
// nothing to do -- should never happen...
|
||||||
return;
|
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();
|
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
|
//TODO [206884] This is part of API and should be changed for the next release
|
||||||
final String strID = getClass().getPackage().getName();
|
final String strID = getClass().getPackage().getName();
|
||||||
//final String strID = "org.eclipse.tm.terminal.serial"; //$NON-NLS-1$
|
//final String strID = "org.eclipse.tm.terminal.serial"; //$NON-NLS-1$
|
||||||
|
SerialPort serialPort = null;
|
||||||
try {
|
try {
|
||||||
fControl.setState(TerminalState.OPENED);
|
fControl.setState(TerminalState.OPENED);
|
||||||
ISerialSettings s=fConn.getSerialSettings();
|
ISerialSettings s=fConn.getSerialSettings();
|
||||||
|
@ -116,7 +118,7 @@ public class SerialConnectWorker extends Thread {
|
||||||
fConn.setSerialPortIdentifier(CommPortIdentifier.getPortIdentifier(portName));
|
fConn.setSerialPortIdentifier(CommPortIdentifier.getPortIdentifier(portName));
|
||||||
int timeoutInMs = s.getTimeout() * 1000;
|
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.setSerialPortParams(s.getBaudRate(), s.getDataBits(), s.getStopBits(), s.getParity());
|
||||||
serialPort.setFlowControlMode(s.getFlowControl());
|
serialPort.setFlowControlMode(s.getFlowControl());
|
||||||
serialPort.addEventListener(fConn.getSerialPortHandler());
|
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$
|
fControl.displayTextInTerminal("No such port: \"" + msg+"\"\r\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
} catch (Exception exception) {
|
} 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);
|
fControl.setState(TerminalState.CLOSED);
|
||||||
|
} finally {
|
||||||
|
fConn.doneConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,8 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Michael Scharf (Wind River) - extracted from TerminalControl
|
* Michael Scharf (Wind River) - extracted from TerminalControl
|
||||||
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
|
* 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;
|
package org.eclipse.tm.internal.terminal.serial;
|
||||||
|
|
||||||
|
@ -42,7 +43,9 @@ public class SerialConnector implements ITerminalConnector {
|
||||||
private CommPortIdentifier fSerialPortIdentifier;
|
private CommPortIdentifier fSerialPortIdentifier;
|
||||||
private SerialPortHandler fTerminalSerialPortHandler;
|
private SerialPortHandler fTerminalSerialPortHandler;
|
||||||
private SerialSettings fSettings;
|
private SerialSettings fSettings;
|
||||||
private SerialConnectWorker fConnectWorker;
|
private SerialConnectWorker fConnectWorker = null;
|
||||||
|
private volatile boolean fDisconnectGoingOn = false;
|
||||||
|
|
||||||
public SerialConnector() {
|
public SerialConnector() {
|
||||||
}
|
}
|
||||||
public SerialConnector(SerialSettings settings) {
|
public SerialConnector(SerialSettings settings) {
|
||||||
|
@ -58,16 +61,37 @@ public class SerialConnector implements ITerminalConnector {
|
||||||
}
|
}
|
||||||
public void connect(ITerminalControl control) {
|
public void connect(ITerminalControl control) {
|
||||||
Logger.log("entered."); //$NON-NLS-1$
|
Logger.log("entered."); //$NON-NLS-1$
|
||||||
if (fConnectWorker!=null && fConnectWorker.isAlive()) {
|
synchronized(this) {
|
||||||
//already connecting
|
if (fConnectWorker!=null || fDisconnectGoingOn) {
|
||||||
return;
|
//avoid multiple background connect/disconnect threads at the same time
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fConnectWorker = new SerialConnectWorker(this, control);
|
||||||
}
|
}
|
||||||
fConnectWorker = new SerialConnectWorker(this, control);
|
|
||||||
fControl=control;
|
fControl=control;
|
||||||
|
fControl.setState(TerminalState.CONNECTING);
|
||||||
fConnectWorker.start();
|
fConnectWorker.start();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Indicate that the connectWorker is finished.
|
||||||
|
*/
|
||||||
|
void doneConnect() {
|
||||||
|
synchronized(this) {
|
||||||
|
fConnectWorker = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
Logger.log("entered."); //$NON-NLS-1$
|
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
|
// Fix for SPR 112422. When output is being received from the serial port, the
|
||||||
// below call to removePortOwnershipListener() attempts to lock the serial port
|
// 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$
|
new Thread("Terminal View Serial Port Disconnect Worker") //$NON-NLS-1$
|
||||||
{
|
{
|
||||||
public void run() {
|
public void run() {
|
||||||
|
try {
|
||||||
if (getSerialPortIdentifier() != null) {
|
if (getSerialPortIdentifier() != null) {
|
||||||
getSerialPortIdentifier()
|
try {
|
||||||
.removePortOwnershipListener(getSerialPortHandler());
|
getSerialPortIdentifier()
|
||||||
}
|
.removePortOwnershipListener(getSerialPortHandler());
|
||||||
|
} catch(Exception e) {
|
||||||
if (getSerialPort() != null) {
|
Logger.logException(e);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (getOutputStream() != null) {
|
if (getSerialPort() != null) {
|
||||||
try {
|
//Event listener is removed as part of close(),
|
||||||
getOutputStream().close();
|
//but exceptions need to be caught to ensure that close() really succeeds
|
||||||
} catch (Exception exception) {
|
try {
|
||||||
Logger.logException(exception);
|
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);
|
if (getInputStream() != null) {
|
||||||
cleanSerialPort();
|
try {
|
||||||
setSerialPortHandler(null);
|
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();
|
}.start();
|
||||||
|
@ -165,6 +205,7 @@ public class SerialConnector implements ITerminalConnector {
|
||||||
return fSerialPortIdentifier;
|
return fSerialPortIdentifier;
|
||||||
}
|
}
|
||||||
protected void setSerialPortIdentifier(CommPortIdentifier serialPortIdentifier) {
|
protected void setSerialPortIdentifier(CommPortIdentifier serialPortIdentifier) {
|
||||||
|
//System.out.println("setSerialPortId: "+Thread.currentThread().getName()+ " - "+serialPortIdentifier + " - "+System.currentTimeMillis());
|
||||||
fSerialPortIdentifier = serialPortIdentifier;
|
fSerialPortIdentifier = serialPortIdentifier;
|
||||||
}
|
}
|
||||||
void setSerialPortHandler(SerialPortHandler serialPortHandler) {
|
void setSerialPortHandler(SerialPortHandler serialPortHandler) {
|
||||||
|
@ -175,6 +216,7 @@ public class SerialConnector implements ITerminalConnector {
|
||||||
}
|
}
|
||||||
public ISerialSettings getSerialSettings() {
|
public ISerialSettings getSerialSettings() {
|
||||||
return fSettings;
|
return fSettings;
|
||||||
|
|
||||||
}
|
}
|
||||||
public ISettingsPage makeSettingsPage() {
|
public ISettingsPage makeSettingsPage() {
|
||||||
return new SerialSettingsPage(fSettings);
|
return new SerialSettingsPage(fSettings);
|
||||||
|
|
Loading…
Add table
Reference in a new issue