Closed steveohara closed 4 years ago
On Win10 64 bit, v2.5.3, port.isOpen() returns always false even if the port is in use in another application.
Actually further to my initial post, I've managed to tame the library somewhat within j2mod and in SMARTset.
The approach I've taken is to be strict about when and where a port is opened/closed. By protecting ports using a mutex, I've managed to fix the issues we were having.
I also noticed that the isOpened
flag IS getting set/reset somehow whilst in the native method.
What would be very handy though, is a method that brute force closes a port based on it's name. The internal port handles are not available anywhere and if the upstream application loses the SerialPort reference, it cannot recover, so the port cannot be closed and/or re-used.
@recepsahin, that behavior is correct. port.isOpen()
should only return true
for the actual SerialPort object that you called open()
on. This method means "is this port open in the current application using the current port object", not "is any other application on the system currently using the port." Hope that helps!
@steveohara, that's correct. The isOpened
flag is only manipulated within native code...this was done to ensure that port errors occurring in/reported by the OS can cause the port to close and that that change will be visible to users in Java-land. I toyed with the idea of protecting all function calls with mutexes or synchronized
but decided it would be better to keep the library running as quickly and simply as possible under the hood and let the user implement their own locking mechanisms as needed, so glad you were able to get that portion sorted out in your library.
Regarding a method to close a port based on its name, I can definitely implement that if it's something that would be useful to you. I'm thinking a static method very similar to getCommPort(String portDescriptor)
, however I'm not 100% sure that this would work without some substantial library changes. The reason being, if you have an actively running application that has opened a serial port and then somehow lost its handle without closing it, further native OS calls to open()
will always fail reporting that the underlying device is busy. So it should theoretically be impossible to get a second open handle to the same device for the purpose of closing it. Can you give me a more concrete use-case in which a constantly-running upstream application might lose a reference to the SerialPort without closing it? That might help me figure out the best way to approach this. Thanks!
@steveohara, I went through and did a complete overhaul on port-closing logic and functionality, including attempting to avoid race conditions and ensuring that the Java-side application doesn't get stuck waiting on an underlying device driver to carry out a function. Please test the newest release version 2.6.0 and see if that has alleviated any of your problems. Thanks!
I've been testing j2mod with the new version and all is good. We have implemented a mutex around our use of comms ports in the application level (SMARTset as opposed to j2mod) and that works nicely too. Thanks Will
The j2mod Modbus library is no longer working on our ARM based controllers. Works for the very first time, but then fails because the port is in use and is not being closed in jSerialComm
I can trace this all the way back to the
SerialPort
class There is a flag calledisOpened
that is never set/reset so most of the methods in the class are not actually doing very much. This doesn't seem to be a problem on Windows (my j2mod unit tests work fine) but on a RasPi it is.I've looked back in the history and I can see that the flag was being set in
getCommPort
back a year or so ago. I tested with 2.0.2 and that works fine but it looks as though it got broke after 2.1.2If I walk through the code and do a
closePortNative(portHandle)
inclosePort()
using IntelliJ it all works fine.