Remove isOpened field and detect openness based on file descriptor

This commit is contained in:
hedgecrw85 2020-02-19 11:45:13 -06:00
parent 9b77808440
commit 5e41067f00
2 changed files with 24 additions and 27 deletions

View File

@ -55,7 +55,7 @@ jfieldID serialPortFdField;
jfieldID comPortField; jfieldID comPortField;
jfieldID friendlyNameField; jfieldID friendlyNameField;
jfieldID portDescriptionField; jfieldID portDescriptionField;
jfieldID isOpenedField; jfieldID eventListenerRunningField;
jfieldID disableConfigField; jfieldID disableConfigField;
jfieldID isDtrEnabledField; jfieldID isDtrEnabledField;
jfieldID isRtsEnabledField; jfieldID isRtsEnabledField;
@ -114,7 +114,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;"); comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;");
friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;"); friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;");
portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;"); portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;");
isOpenedField = (*env)->GetFieldID(env, serialCommClass, "isOpened", "Z"); eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z");
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
@ -172,14 +172,13 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
// Configure the port parameters and timeouts // Configure the port parameters and timeouts
if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD)) if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD))
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_TRUE); (*env)->SetLongField(env, obj, serialPortHandleField, serialPortFD);
else else
{ {
// Close the port if there was a problem setting the parameters // Close the port if there was a problem setting the parameters
tcdrain(serialPortFD); tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF)); while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1; serialPortFD = -1;
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
} }
} }
@ -435,7 +434,6 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
// Ensure that the port is open // Ensure that the port is open
if (serialPortFD <= 0) if (serialPortFD <= 0)
return JNI_TRUE; return JNI_TRUE;
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
// Force the port to enter non-blocking mode to ensure that any current reads return // Force the port to enter non-blocking mode to ensure that any current reads return
struct termios options = {0}; struct termios options = {0};
@ -460,9 +458,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(J
{ {
// Problem detected, close the port // Problem detected, close the port
tcdrain(serialPortFD); tcdrain(serialPortFD);
while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); while ((close(serialPortFD) == -1) && (errno != EBADF));
(*env)->SetLongField(env, obj, serialPortFdField, -1l); (*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
} }
return numBytesAvailable; return numBytesAvailable;
@ -497,10 +494,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1)))
{ {
// Problem reading, close port // Problem reading, close port
while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1; serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l); (*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
break; break;
} }
@ -528,10 +524,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1)))
{ {
// Problem reading, close port // Problem reading, close port
while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1; serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l); (*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
break; break;
} }
@ -551,10 +546,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1)))
{ {
// Problem reading, close port // Problem reading, close port
while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1; serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l); (*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
} }
else else
numBytesReadTotal = numBytesRead; numBytesReadTotal = numBytesRead;
@ -563,7 +557,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
// Return number of bytes read if successful // Return number of bytes read if successful
(*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer); (*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer);
free(readBuffer); free(readBuffer);
return (numBytesRead == -1) || !((*env)->GetBooleanField(env, obj, isOpenedField)) ? -1 : numBytesReadTotal; return (numBytesRead == -1) || (serialPortFD == -1) ? -1 : numBytesReadTotal;
} }
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset) JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset)
@ -580,10 +574,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
{ {
// Problem writing, close the port // Problem writing, close the port
ioctl(serialPortFD, TCSBRK, 1); ioctl(serialPortFD, TCSBRK, 1);
while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1; serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l); (*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
} }
// Wait until all bytes were written in write-blocking mode // Wait until all bytes were written in write-blocking mode

View File

@ -2,7 +2,7 @@
* SerialPort_Posix.c * SerialPort_Posix.c
* *
* Created on: Feb 25, 2012 * Created on: Feb 25, 2012
* Last Updated on: Feb 18, 2020 * Last Updated on: Feb 19, 2020
* Author: Will Hedgecock * Author: Will Hedgecock
* *
* Copyright (C) 2012-2020 Fazecast, Inc. * Copyright (C) 2012-2020 Fazecast, Inc.
@ -53,7 +53,7 @@ jfieldID serialPortFdField;
jfieldID comPortField; jfieldID comPortField;
jfieldID friendlyNameField; jfieldID friendlyNameField;
jfieldID portDescriptionField; jfieldID portDescriptionField;
jfieldID isOpenedField; jfieldID eventListenerRunningField;
jfieldID disableConfigField; jfieldID disableConfigField;
jfieldID isDtrEnabledField; jfieldID isDtrEnabledField;
jfieldID isRtsEnabledField; jfieldID isRtsEnabledField;
@ -218,7 +218,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;"); comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;");
friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;"); friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;");
portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;"); portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;");
isOpenedField = (*env)->GetFieldID(env, serialCommClass, "isOpened", "Z"); eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z");
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
@ -259,7 +259,9 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
// Ensure that multiple root users cannot access the device simultaneously // Ensure that multiple root users cannot access the device simultaneously
if (flock(serialPortFD, LOCK_EX | LOCK_NB) == -1) if (flock(serialPortFD, LOCK_EX | LOCK_NB) == -1)
{ {
while ((close(serialPortFD) == -1) && (errno == EINTR)); tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno == EINTR))
errno = 0;
serialPortFD = -1; serialPortFD = -1;
} }
else else
@ -284,14 +286,14 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
// Configure the port parameters and timeouts // Configure the port parameters and timeouts
if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD)) if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD))
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_TRUE); (*env)->SetLongField(env, obj, serialPortFdField, serialPortFD);
else else
{ {
// Close the port if there was a problem setting the parameters // Close the port if there was a problem setting the parameters
tcdrain(serialPortFD); tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno == EINTR)); while ((close(serialPortFD) == -1) && (errno == EINTR))
errno = 0;
serialPortFD = -1; serialPortFD = -1;
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
} }
} }
} }
@ -499,7 +501,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
struct pollfd waitingSet = { serialPortFD, POLLIN, 0 }; struct pollfd waitingSet = { serialPortFD, POLLIN, 0 };
// Wait for a serial port event // Wait for a serial port event
if (poll(&waitingSet, 1, 1000) <= 0) if (poll(&waitingSet, 1, 500) <= 0)
return 0; return 0;
return (waitingSet.revents & POLLIN) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0; return (waitingSet.revents & POLLIN) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0;
} }
@ -523,10 +525,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
// Close the port // Close the port
flock(serialPortFD, LOCK_UN | LOCK_NB); flock(serialPortFD, LOCK_UN | LOCK_NB);
while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno == EINTR)) while ((close(serialPortFD) == -1) && (errno == EINTR))
errno = 0; errno = 0;
(*env)->SetLongField(env, obj, serialPortFdField, -1l); (*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
return JNI_TRUE; return JNI_TRUE;
} }
@ -569,6 +570,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{ {
// Problem reading, close the port // Problem reading, close the port
Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD); Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD);
serialPortFD = -1;
break; break;
} }
@ -597,6 +599,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{ {
// Problem reading, close the port // Problem reading, close the port
Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD); Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD);
serialPortFD = -1;
break; break;
} }
@ -616,6 +619,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{ {
// Problem reading, close the port // Problem reading, close the port
Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD); Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD);
serialPortFD = -1;
} }
else else
numBytesReadTotal = numBytesRead; numBytesReadTotal = numBytesRead;
@ -624,7 +628,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
// Return number of bytes read if successful // Return number of bytes read if successful
(*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer); (*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer);
free(readBuffer); free(readBuffer);
return (numBytesRead == -1) || !((*env)->GetBooleanField(env, obj, isOpenedField)) ? -1 : numBytesReadTotal; return ((numBytesRead == -1) || (serialPortFD == -1)) ? -1 : numBytesReadTotal;
} }
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset) JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset)