changeset 49:4062e137c8f2

8058510: race condition in UART write Summary: store signal instead of drop it if no threads are waiting on it yet Reviewed-by: alkonsta
author jld
date Wed, 17 Sep 2014 16:01:44 -0400
parents 1b480a94749a
children be1bc081b865
files .hgignore src/se/native/com/oracle/dio/dio_common.cpp
diffstat 2 files changed, 20 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Sep 16 14:26:11 2014 -0400
+++ b/.hgignore	Wed Sep 17 16:01:44 2014 -0400
@@ -1,1 +1,1 @@
-./build
+build
--- a/src/se/native/com/oracle/dio/dio_common.cpp	Tue Sep 16 14:26:11 2014 -0400
+++ b/src/se/native/com/oracle/dio/dio_common.cpp	Wed Sep 17 16:01:44 2014 -0400
@@ -208,7 +208,7 @@
     }
 }
 
-/* Returns an exisiting reference to the device identified by handle. */
+/* Returns an existing reference to the device identified by handle. */
 device_reference getDeviceReference(javacall_handle handle) {
     device_reference device = INVALID_DEVICE_REFERENCE;
     javacall_os_mutex_lock(devlistMutex);
@@ -274,19 +274,22 @@
     signal* sig = NULL;
 
     javacall_os_mutex_lock(signalMutex);
-    javacall_dio_result result = JAVACALL_DIO_BUSY;
-    if (findTarget(signalType, signalTarget) == NULL) {
-        result = JAVACALL_DIO_OUT_OF_MEMORY;
+    if ((sig = findTarget(signalType, signalTarget)) == NULL) {
         sig = createSignal(signalType, signalTarget);
         if (sig != NULL) {
-            result = JAVACALL_DIO_OK;
             javautil_list_add(signals, sig);
+
+            javacall_os_mutex_unlock(signalMutex);
+            javacall_os_cond_wait(sig->condition, timeout);
         }
+    } else {
+        javacall_os_mutex_unlock(signalMutex);
     }
-    javacall_os_mutex_unlock(signalMutex);
 
-    if (result == JAVACALL_DIO_OK) {
-        javacall_os_cond_wait(sig->condition, timeout);
+    javacall_dio_result result = JAVACALL_DIO_OUT_OF_MEMORY;
+
+    if (sig) {
+        result = JAVACALL_DIO_OK;
 
         javacall_os_mutex_lock(signalMutex);
         javautil_list_remove(signals, sig);
@@ -311,6 +314,14 @@
     if (sig != NULL) {
         sig->parameter = signalParameter;
         javacall_os_cond_signal(sig->condition);
+    } else {
+        // signal is being sent before wait started
+        // create the signal and add it to the list
+        sig = createSignal(signalType, signalTarget);
+        if (sig != NULL) {
+            sig->parameter = signalParameter;
+            javautil_list_add(signals, sig);
+        }
     }
 
     javacall_os_mutex_unlock(signalMutex);