@@ -41,7 +41,6 @@ public class SerialPort {
4141 private final String portName ;
4242 private volatile boolean portOpened = false ;
4343 private boolean maskAssigned = false ;
44- private boolean eventListenerAdded = false ;
4544
4645 //since 2.2.0 ->
4746 private volatile Method methodErrorOccurred = null ;
@@ -1104,7 +1103,7 @@ public void addEventListener(SerialPortEventListener listener, int mask) throws
11041103 */
11051104 private synchronized void addEventListener (SerialPortEventListener listener , int mask , boolean overwriteMask ) throws SerialPortException {
11061105 checkPortOpened ("addEventListener()" );
1107- if (! eventListenerAdded ){
1106+ if (eventThread == null || ! eventThread . isAlive () ){
11081107 if ((maskAssigned && overwriteMask ) || !maskAssigned ) {
11091108 setEventsMask (mask );
11101109 }
@@ -1125,7 +1124,6 @@ private synchronized void addEventListener(SerialPortEventListener listener, int
11251124 }
11261125 //<- since 2.2.0
11271126 eventThread .start ();
1128- eventListenerAdded = true ;
11291127 }
11301128 else {
11311129 throw new SerialPortException (this , "addEventListener()" , SerialPortException .TYPE_LISTENER_ALREADY_ADDED );
@@ -1155,24 +1153,26 @@ private EventThread getNewEventThread() {
11551153 * @throws SerialPortException if exception occurred
11561154 */
11571155 public synchronized boolean removeEventListener () throws SerialPortException {
1158- checkPortOpened ("removeEventListener()" );
1159- if (!eventListenerAdded ){
1160- throw new SerialPortException (this , "removeEventListener()" , SerialPortException .TYPE_CANT_REMOVE_LISTENER );
1156+ if (eventThread == null || !eventThread .isAlive ()){
1157+ return false ;
11611158 }
11621159 eventThread .terminateThread ();
1163- setEventsMask (0 );
1160+ if (portOpened ) {
1161+ setEventsMask (0 );
1162+ }
1163+ //Guard against currentThread().join deadlock
11641164 if (Thread .currentThread ().getId () != eventThread .getId ()){
1165- if (eventThread .isAlive ()){
1166- try {
1167- eventThread .join (5000 );
1168- }
1169- catch (InterruptedException ex ) {
1170- throw new SerialPortException (this , "removeEventListener()" , SerialPortException .TYPE_LISTENER_THREAD_INTERRUPTED );
1165+ try {
1166+ eventThread .join (5000 );
1167+ if (eventThread .isAlive ()) {
1168+ throw new SerialPortException (this , "removeEventListener()" , SerialPortException .TYPE_CANT_REMOVE_LISTENER );
11711169 }
11721170 }
1171+ catch (InterruptedException ex ) {
1172+ throw new SerialPortException (this , "removeEventListener()" , SerialPortException .TYPE_LISTENER_THREAD_INTERRUPTED );
1173+ }
11731174 }
11741175 methodErrorOccurred = null ;
1175- eventListenerAdded = false ;
11761176 return true ;
11771177 }
11781178
@@ -1184,14 +1184,21 @@ public synchronized boolean removeEventListener() throws SerialPortException {
11841184 * @throws SerialPortException if exception occurred
11851185 */
11861186 public synchronized boolean closePort () throws SerialPortException {
1187- checkPortOpened ("closePort()" );
1188- if (eventListenerAdded ){
1187+ boolean returnValue ;
1188+ //removeEventListener calls setEventsMask, and must occur before calling closePort
1189+ try {
11891190 removeEventListener ();
11901191 }
1191- boolean returnValue = serialInterface .closePort (portHandle );
1192- if (returnValue ){
1193- maskAssigned = false ;
1194- portOpened = false ;
1192+ finally {
1193+ if (portOpened ) {
1194+ returnValue = serialInterface .closePort (portHandle );
1195+ if (returnValue ) {
1196+ maskAssigned = false ;
1197+ portOpened = false ;
1198+ }
1199+ } else {
1200+ returnValue = false ;
1201+ }
11951202 }
11961203 return returnValue ;
11971204 }
0 commit comments