-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SerialPort.closePort not calling native interface on Windows when USB serial adapter is disconnected #107
Comments
Edit: Hmm... the editor says that swallows the exception, so, nope. :) Show code public synchronized boolean closePort() throws SerialPortException {
- checkPortOpened("closePort()");
- if(eventListenerAdded){
- removeEventListener();
- }
- boolean returnValue = serialInterface.closePort(portHandle);
- if(returnValue){
- maskAssigned = false;
- portOpened = false;
+ boolean returnValue = false;
+ try {
+ checkPortOpened("closePort()");
+ if (eventListenerAdded) {
+ removeEventListener();
+ }
+ } finally{
+ returnValue = serialInterface.closePort(portHandle);
+ if (returnValue) {
+ maskAssigned = false;
+ portOpened = false;
+ }
}
return returnValue;
} |
another idea, guard Click to see diff--- a/src/main/java/jssc/SerialPort.java
+++ b/src/main/java/jssc/SerialPort.java
@@ -1049,8 +1049,17 @@ public class SerialPort {
*
* @throws SerialPortException
*/
- public synchronized boolean removeEventListener() throws SerialPortException {
- checkPortOpened("removeEventListener()");
+ public synchronized boolean removeEventListener(boolean force) throws SerialPortException {
+ try {
+ checkPortOpened("removeEventListener()");
+ } catch(SerialPortException e) {
+ if(!force) {
+ throw e;
+ } else {
+ // Swallow exception, but put it to the terminal
+ e.printStackTrace();
+ }
+ }
if(!eventListenerAdded){
throw new SerialPortException(this, "removeEventListener()", SerialPortException.TYPE_CANT_REMOVE_LISTENER);
}
@@ -1071,6 +1080,10 @@ public class SerialPort {
return true;
}
+ public synchronized boolean removeEventListener() throws SerialPortException {
+ return removeEventListener(false);
+ }
+
/**
* Close port. This method deletes event listener first, then closes the port
*
@@ -1079,9 +1092,9 @@ public class SerialPort {
* @throws SerialPortException
*/
public synchronized boolean closePort() throws SerialPortException {
- checkPortOpened("closePort()");
+ // checkPortOpened("closePort()"); // can this cause native closePort() to segfault?
if(eventListenerAdded){
- removeEventListener();
+ removeEventListener(true);
}
boolean returnValue = serialInterface.closePort(portHandle);
if(returnValue){ |
FYI, our production workaround is this, but this particular app is not very portable, so not much testing is done outside of Windows, and perhaps adhering to own javadoc and NOT throwing these exceptions in the first place is the way to go? public class SerialPortEnhanced extends SerialPort {
SerialPortEnhanced(String portName) {
super(portName);
}
@Override
public boolean setEventsMask(int mask) {
try {
return super.setEventsMask(mask);
} catch (SerialPortException e) {
return false;
}
}
} |
I think the proper solution will:
I do not see many use-cases for throwing an exception before cleanup, except perhaps the Thread.join call, but even then, I would expect |
🤣 |
As noted in #63, There are several methods in the library that are described in javadoc as returning
true
orfalse
to signify a success, but in fact throwing an exception on failure. The particulary nasty stack for us is:closePort -> removeEventListener -> setEventMask
because in the case where USB serial adapter is already disconnected, this throws an exception beforeclosePort -> serialInterface.closePort(portHandle);
is fired.As a result, the device is not released. Some other software we use that also queries serial ports still sees that ghost port (or sees multiple COM ports, with duplicated number if the adapter is reconnected), even when Device Manager does not.
The text was updated successfully, but these errors were encountered: