]> git.sesse.net Git - kdenlive/commitdiff
clean thread shutdown implemented in ShuttleThread
authorEd Rogalsky <ed.rogalsky@googlemail.com>
Tue, 20 Nov 2012 12:34:18 +0000 (13:34 +0100)
committerEd Rogalsky <ed.rogalsky@googlemail.com>
Tue, 20 Nov 2012 12:34:18 +0000 (13:34 +0100)
src/jogshuttle.cpp

index f9049511dceefcc568ecf037e33c2fdec5b3ea0c..8c9d845f8bd16d1c5fcc649fedc85ab5bda19de0 100644 (file)
@@ -85,31 +85,75 @@ bool ShuttleThread::isWorking()
 void ShuttleThread::run()
 {
     kDebug() << "-------  STARTING SHUTTLE: " << m_device;
-
+    /* open file descriptor */
     const int fd = KDE_open((char *) m_device.toUtf8().data(), O_RDONLY);
     if (fd < 0) {
         fprintf(stderr, "Can't open Jog Shuttle FILE DESCRIPTOR\n");
-        return;;
+        return;
     }
-    EV ev;
 
+    EV ev;
     if (ioctl(fd, EVIOCGRAB, 1) < 0) {
         fprintf(stderr, "Can't get exclusive access on  Jog Shuttle FILE DESCRIPTOR\n");
         close(fd);
-        return;;
+        return;
     }
 
+    fd_set         readset;
+    struct timeval timeout;
+
     int num_warnings = 0;
+    int result, iof = -1;
+
+    /* enter thread loop */
     while (!stop_me) {
-        if (read(fd, &ev, sizeof(ev)) < 0) {
-            if (num_warnings % 10000 == 0)
-                fprintf(stderr, "Failed to read event from Jog Shuttle FILE DESCRIPTOR (repeated %d times)\n", num_warnings + 1);
-            num_warnings++;
-        }
-        handle_event(ev);
+       /* reset the read set */
+       FD_ZERO(&readset);
+       FD_SET(fd, &readset);
+
+        /* reinit the timeout structure */
+        timeout.tv_sec  = 0;
+        timeout.tv_usec = 300000; /* 300 ms */
+
+        /* do the select */
+       result = select(fd+1, &readset, NULL, NULL, &timeout);
+
+       /* see if there was an error or timeout */
+       if (result < 0) {
+//         perror("select failed");
+       } else if (result == 0) {
+//         puts("TIMEOUT");
+       } else {
+           /* we have input */
+           if (FD_ISSET(fd, &readset)) {
+               /* get fd settings */
+               if ((iof = fcntl(fd, F_GETFL, 0)) != -1) {
+                       /* set fd non blocking */
+                       fcntl(fd, F_SETFL, iof | O_NONBLOCK);
+                       /* read input */
+                                       if (read(fd, &ev, sizeof(ev)) < 0) {
+                                               if (num_warnings % 10000 == 0)
+                                                       /* should not happen cause select called before */
+                                                       fprintf(stderr, "Failed to read event from Jog Shuttle FILE DESCRIPTOR (repeated %d times)\n", num_warnings + 1);
+                                               num_warnings++;
+                                       }
+
+                                       /* restore settings */
+                                       if (iof != -1) {
+                                               fcntl(fd, F_SETFL, iof);
+                                       }
+                                       /* process event */
+                                       handle_event(ev);
+               } else {
+                   fprintf(stderr, "Can't set Jog Shuttle FILE DESCRIPTOR to O_NONBLOCK\n");
+                   stop_me = true;
+               }
+           }
+       }
     }
-    close(fd);
 
+    /* close the handle and return thread */
+    close(fd);
 }
 
 void ShuttleThread::handle_event(EV ev)
@@ -226,8 +270,8 @@ void JogShuttle::stopDevice()
        /* the read fd is in blocking mode => stop_me is broken at the moment */
         m_shuttleProcess.stop_me = true;
         m_shuttleProcess.exit();
-        /* give the thread some time to shutdown */
-        m_shuttleProcess.wait(100);
+        /* give the thread some time (ms) to shutdown */
+        m_shuttleProcess.wait(600);
 
         /* if still running - do it in the hardcore way */
         if (m_shuttleProcess.isRunning()) {