changeset 107:42408fd53ee7

8073057: Add wait procedure after GPIO export Summary: Added monitor for /sys/class/gpio folder to catch new files . Reviewed-by: snazarki, jld Contributed-by: alexey.karaksin@oracle.com
author snazarki
date Fri, 20 Feb 2015 13:51:40 +0400
parents 47c1eb709fd4
children e8935edceafa
files src/share/linux/native/com/oracle/dio/gpio/gpio.c
diffstat 1 files changed, 46 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/linux/native/com/oracle/dio/gpio/gpio.c	Thu Feb 19 18:42:52 2015 +0300
+++ b/src/share/linux/native/com/oracle/dio/gpio/gpio.c	Fri Feb 20 13:51:40 2015 +0400
@@ -28,6 +28,7 @@
 #include <pthread.h>
 #include <sys/epoll.h>
 #include <time.h>
+#include <errno.h>
 #include "javanotify_gpio.h"
 #include "javautil_linked_list.h"
 #include "javacall_logging.h"
@@ -493,6 +494,7 @@
     GPIOHandle* handle;
     javacall_dio_result res;
     int directionFD;
+    int count;
 
     JAVACALL_REPORT_INFO3(JC_DIO, "Try to open pin %d on port %d with direction %d", pin, port, direction);
 
@@ -524,26 +526,53 @@
         return res;
     }
 
-    res = enable_gpio_pin(pin);
-    if (JAVACALL_DIO_OK != res) {
-        unlock_pin_list();
-        // error is printed at enable_gpio_pin
-        return res;
-    }
-
     snprintf(bufForDirectionFilename, DIRECTION_FILENAME_MAX_LENGTH, GPIO_DIRECTION_FILENAME_TEMPLATE, pin);
 
-    // restore root priviladges temporary
+    // restore root privileges temporary
     restore_privileges();
     directionFD = open(bufForDirectionFilename, O_WRONLY);
     drop_privileges();
 
+    if(-1 == directionFD  && errno == ENOENT) {
+        //file does not exist, need to enable GPIOPin
+        if (enable_gpio_pin(pin) != JAVACALL_DIO_OK) {
+            unlock_pin_list();
+            // error is printed at enable_gpio_pin
+            return JAVACALL_DIO_FAIL;
+        }else{
+            count = 0;
+            /*
+                after pin number is written to the export file, corresponding gpioN dir is
+                creating very fast.
+                if the runtime runs as root - the direction file is accessible for writing.
+                if the runtime runs as a non priviledged user - the direction file become writable
+                after the udev script changed the file permission, it takes up to 150 millisec.
+            */
+            while (count < 200){
+                // restore root privileges temporary
+                restore_privileges();
+                directionFD = open(bufForDirectionFilename, O_WRONLY);
+                drop_privileges();
+                /*
+                    wait only if file is not created or udev has not changed the file permission
+                */
+                if(-1 == directionFD && ( errno == ENOENT || errno == EACCES)) {
+                    usleep(1000);
+                    count++;
+                }else{
+                    break;
+                }
+            }//while count
+            JAVACALL_REPORT_INFO1(JC_DIO,
+                                "There are %d attempts (millisec) to open the direction file.", count);
+        }
+    }
     if(-1 == directionFD) {
-            JAVACALL_REPORT_ERROR1(JC_DIO,
-                                    "Can not open %s file to configure GPIO pin direction",
-                                    directionFD);
-            unlock_pin_list();
-            return JAVACALL_DIO_FAIL;
+        JAVACALL_REPORT_ERROR1(JC_DIO,
+                                "Can not open %s file to configure GPIO pin direction",
+                                bufForDirectionFilename);
+        unlock_pin_list();
+        return JAVACALL_DIO_FAIL;
     }
 
     if(JAVACALL_DIO_OK != write_direction_to_file(directionFD, direction, initValue)) {
@@ -705,7 +734,7 @@
 
     char pinNameBuffer[4];
 
-    // restore root priviladges temporary
+    // restore root privileges temporary
     restore_privileges();
     int expordFD = open(EXPORT_FILE_NAME, O_WRONLY);
     drop_privileges();
@@ -731,7 +760,7 @@
 
     javacall_int8 nameOfPinBuffer[4];
 
-    // restore root priviladges temporary
+    // restore root privileges temporary
     restore_privileges();
     int unexportFD = open(UNEXPORT_FILE_NAME, O_WRONLY);
     drop_privileges();
@@ -938,7 +967,7 @@
         return JAVACALL_DIO_FAIL;
     }
 
-    // restore root priviladges temporary
+    // restore root privileges temporary
     restore_privileges();
     handle->valueFD = open(nameBuffer, O_RDWR);
     drop_privileges();
@@ -1040,7 +1069,7 @@
 
     snprintf(bufferForEdgeFileName, EDGE_FILENAME_MAX_LENGTH, GPIO_EDGE_FILENAME_TEMPLATE, pin->number);
 
-    // restore root priviladges temporary
+    // restore root privileges temporary
     restore_privileges();
     edgeFD = open(bufferForEdgeFileName, O_WRONLY);
     drop_privileges();