changeset 127:21dba9ff250c

8130128: The generateBreak method of UART not implemented Summary: The method is implemented Reviewed-by: alkonsta
author snazarki
date Thu, 02 Jul 2015 20:37:36 +0300
parents dc977f532a4a
children 26cdefd05bf5
files src/se/native/com/oracle/dio/uart/impl/jni_uart.cpp src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java src/share/linux/native/com/oracle/dio/uart/uart.c src/share/native/com/oracle/dio/javacall_uart.h
diffstat 4 files changed, 146 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/se/native/com/oracle/dio/uart/impl/jni_uart.cpp	Fri Mar 27 12:28:09 2015 +0300
+++ b/src/se/native/com/oracle/dio/uart/impl/jni_uart.cpp	Thu Jul 02 20:37:36 2015 +0300
@@ -549,6 +549,65 @@
     return (jint)grp;
 }
 
+/*
+ * Class:     com_oracle_dio_uart_impl_UARTImpl
+ * Method:    generateBreak0
+ */
+JNIEXPORT void JNICALL Java_com_oracle_dio_uart_impl_UARTImpl_generateBreak0
+  (JNIEnv* env, jobject obj, jint duration) {
+    javacall_dio_result result = JAVACALL_DIO_CLOSED;
+
+    // Get synchronized with the object to avoid closing the handle by another
+    // thread. See the implementation of close(). Always check the handle is valid.
+    // Do not generate ClosedDeviceException until all JNI calls are made.
+    env->MonitorEnter(obj);
+    if (env->ExceptionCheck() != JNI_TRUE) {
+        device_reference device = getDeviceReferenceFromDeviceObject(env, obj);
+        if (device != INVALID_DEVICE_REFERENCE) {
+            javacall_handle handle = getDeviceHandle(device);
+            if (handle != JAVACALL_INVALID_HANDLE) {
+                result = javacall_uart_generate_break_start(handle, duration);
+                if (result == JAVACALL_DIO_WOULD_BLOCK) {
+                    retainDeviceReference(device);
+                }
+            }
+        }
+    }
+    env->MonitorExit(obj);
+
+    do {
+        if (result == JAVACALL_DIO_WOULD_BLOCK) {
+
+            javacall_handle status = NULL;
+            result = waitForSignal(COMM_CLOSE_SIGNAL, getDeviceHandle(device), &status, 0);
+            releaseDeviceReference(device);
+            device = NULL;
+
+            if ((result != JAVACALL_DIO_OK) ||
+                (result = (javacall_dio_result)(javacall_int32)status) != JAVACALL_DIO_OK ||
+                (env->ExceptionCheck() == JNI_TRUE)) {
+                break;
+            }
+
+            // again, get synchronized, check the handle is valid
+            env->MonitorEnter(obj);
+            device = getDeviceReferenceFromDeviceObject(env, obj);
+            if (device != INVALID_DEVICE_REFERENCE) {
+                javacall_handle handle = getDeviceHandle(device);
+                if (handle != JAVACALL_INVALID_HANDLE) {
+                    result = javacall_uart_generate_break_finish(handle);
+                }
+            }
+            env->MonitorExit(obj);
+        }
+    } while (1);
+
+
+    checkJavacallFailure(env, result);
+    return;
+}
+
+
 /**
  * A callback function to be called for notification of uart events.
  *
--- a/src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java	Fri Mar 27 12:28:09 2015 +0300
+++ b/src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java	Thu Jul 02 20:37:36 2015 +0300
@@ -584,7 +584,11 @@
      */
     @Override
     public synchronized void generateBreak(int duration) throws IOException, UnavailableDeviceException, ClosedDeviceException{
-        throw new UnsupportedOperationException();
+        if(0 > duration){
+            throw new IllegalArgumentException(String.valueOf(duration));
+        }
+        checkPowerState();
+        generateBreak0(duration);
     }
 
     /**
@@ -879,4 +883,11 @@
         "com.oracle.dio.impl.AbstractPeripheral.handle",
     })
     private native int getUartId0();
+
+    @Local(DontRemoveFields = {
+        "com.oracle.dio.impl.Handle.native_handle",
+        "com.oracle.dio.impl.AbstractPeripheral.handle",
+    })
+    private native int generateBreak0(int duration);
+
 }
--- a/src/share/linux/native/com/oracle/dio/uart/uart.c	Fri Mar 27 12:28:09 2015 +0300
+++ b/src/share/linux/native/com/oracle/dio/uart/uart.c	Thu Jul 02 20:37:36 2015 +0300
@@ -595,3 +595,43 @@
     *grp = -1;
     return JAVACALL_DIO_UNSUPPORTED_OPERATION;
 }
+
+struct tuple {
+    uart_handle uart;
+    int duration;
+};
+
+static void* break_thread(void* args) {
+    javacall_dio_result result = JAVACALL_DIO_OK;
+    struct tuple *data = (struct tuple *)args;
+    if (-1 == tcsendbreak(data->uart->serial_descr.fd, data->duration)) {
+        JAVACALL_REPORT_ERROR1(JC_DIO, "tcsendbreak error:%s", strerror(errno));
+        result = JAVACALL_FAIL;
+    }
+    // most safe event at this time
+    javanotify_serial_event(JAVACALL_EVENT_SERIAL_CLOSE, data->uart, result);
+    javacall_free(data);
+    return (void*)result;
+}
+
+javacall_dio_result
+javacall_uart_generate_break_start(javacall_handle handle, javacall_int32 duration) {
+    uart_handle uart = (uart_handle)handle;
+    pthread_t thread_id;
+    struct tuple *data = (struct tuple*) javacall_malloc (sizeof(struct tuple));
+    data->uart = uart;
+    if (pthread_create(&thread_id, NULL, break_thread, data) == 0) {
+        pthread_detach(thread_id);
+    } else {
+        JAVACALL_REPORT_ERROR1(JC_DIO,
+                "[UART] failed to create thread: errno=%d", errno);
+        return JAVACALL_FAIL;
+    }
+    return JAVACALL_DIO_WOULD_BLOCK;
+}
+
+javacall_dio_result
+javacall_uart_generate_break_finish(javacall_handle handle) {
+    return JAVACALL_DIO_OK;
+}
+
--- a/src/share/native/com/oracle/dio/javacall_uart.h	Fri Mar 27 12:28:09 2015 +0300
+++ b/src/share/native/com/oracle/dio/javacall_uart.h	Thu Jul 02 20:37:36 2015 +0300
@@ -406,6 +406,41 @@
 javacall_dio_result /*OPTIONAL*/
 javacall_uart_stop_event_listening(javacall_handle handle, javacall_uart_event_type eventId);
 
+
+
+/**
+ * Generates a line break for the specified duration.
+ *
+ *
+ * @param handle handle serial port handle
+ * @param duration duration of the line break to generate, in
+ *                 milliseconds.
+ *
+ * @return the result of the operation
+ * @retval JAVACALL_DIO_OK if the operation was complete
+ * @retval JAVACALL_DIO_WOULD_BLOCK if this is blocking
+ *         operation and caller need to call {@link #javacall_uart_generate_break_finish()}
+ *         when operation complete
+ * @retval JAVACALL_DIO_FAIL general IO error
+ * @retval JAVACALL_DIO_UNSUPPORTED_OPERATION if operation is
+ *         not supported by the driver
+ */
+javacall_dio_result
+javacall_uart_generate_break_start(javacall_handle handle, javacall_int32 duration);
+
+/**
+ * Cleans up async operation started by {@link javacall_uart_generate_break_start}
+ *
+ * @param handle handle serial port handle
+ *
+ * @return the result of the operation
+ * @retval JAVACALL_DIO_OK if the operation was complete
+ * @retval JAVACALL_DIO_FAIL general IO error
+ */
+javacall_dio_result
+javacall_uart_generate_break_finish(javacall_handle handle);
+
+
 /**
  * Returns power control group of this channel. It is used for
  * power management notification.