]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvr inotify: fix case where IN_MOVED_TO comes in subsequent read after read contaning...
authorjoeuser <joeusercz@goglemail.co>
Sun, 2 Sep 2018 20:26:00 +0000 (22:26 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 3 Sep 2018 13:33:06 +0000 (15:33 +0200)
src/dvr/dvr_inotify.c

index 71137df20646eff4adc3444cf158d7a5781f1b44..a8db57c09fee1490291a5411bf3251767da7fec4 100644 (file)
@@ -33,7 +33,7 @@
 /* inotify limits */
 #define EVENT_SIZE    ( sizeof (struct inotify_event) )
 #define EVENT_BUF_LEN ( 10 * ( EVENT_SIZE + 16 ) )
-#define EVENT_MASK    IN_CREATE    | IN_DELETE     | IN_DELETE_SELF |\
+#define EVENT_MASK    IN_DELETE     | IN_DELETE_SELF |\
                       IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO
                       
 static int                         _inot_fd;
@@ -378,6 +378,11 @@ void* _dvr_inotify_thread ( void *p )
   const char *from;
   int fromfd;
   int cookie;
+  char from_prev[50];
+  int fromfd_prev =0;
+  int cookie_prev =0;
+
+  from_prev[0] = '\0';
 
   while (tvheadend_is_running()) {
 
@@ -397,6 +402,7 @@ void* _dvr_inotify_thread ( void *p )
     pthread_mutex_lock(&global_lock);
     while ( i < len ) {
       struct inotify_event *ev = (struct inotify_event*)&buf[i];
+    tvhdebug(LS_DVR, "inotify: i= %d   len= %d   ", i, len);
       i += EVENT_SIZE + ev->len;
       if (i > len)
         break;
@@ -406,12 +412,21 @@ void* _dvr_inotify_thread ( void *p )
         from   = ev->name;
         fromfd = ev->wd;
         cookie = ev->cookie;
+      tvhdebug(LS_DVR, "inotify: i= %d   len= %d   from = %s   cookie = %d ", i, len, from, cookie);
         continue;
 
-      } else if ((ev->mask & IN_MOVED_TO) && from && ev->cookie == cookie) {
-        _dvr_inotify_moved(fromfd, from, ev->name, ev->wd);
-        from = NULL;
-      
+      } else if (ev->mask & IN_MOVED_TO) {
+    tvhdebug(LS_DVR, "inotify: i= %d   len= %d    to_cookie= %d   from_cookie = %d   cookie_prev = %d", i, len, ev->cookie,cookie,cookie_prev);
+          if ( from && ev->cookie == cookie) {
+            _dvr_inotify_moved(fromfd, from, ev->name, ev->wd);
+            from = NULL;
+           cookie = 0;
+          } else if (from_prev[0] != '\0' && ev->cookie == cookie_prev) {
+             _dvr_inotify_moved(fromfd_prev, from_prev, ev->name, ev->wd);
+             from_prev[0] = '\0';
+            cookie_prev = 0;
+         }
+
       /* Removed */
       } else if (ev->mask & IN_DELETE) {
         _dvr_inotify_delete(ev->wd, ev->name);
@@ -424,15 +439,26 @@ void* _dvr_inotify_thread ( void *p )
       } else if (ev->mask & IN_DELETE_SELF) {
         _dvr_inotify_delete_all(ev->wd);
       }
-
+/*
       if (from) {
         _dvr_inotify_moved(fromfd, from, NULL, -1);
         from   = NULL;
         cookie = 0;
       }
+*/
+    }
+    //  if still old "from", assume matching "to" is not coming
+    if (from_prev[0] != '\0') {
+      _dvr_inotify_moved(fromfd_prev, from_prev, NULL, -1);
+      from_prev[0] = '\0';
+      cookie_prev = 0;
     }
+    //  if unmatched "from", save in case matching "to" is coming in next read
     if (from) {
-      _dvr_inotify_moved(fromfd, from, NULL, -1);
+      strcpy ( from_prev, from);
+      fromfd_prev = fromfd;
+      cookie_prev = cookie;
+      tvhdebug(LS_DVR, "inotify: i= %d   len= %d      cookie_prev = %d   from_prev = %s  fd = %d   END OF READ", i, len, cookie_prev, from_prev, fromfd_prev);
     }
     pthread_mutex_unlock(&global_lock);
   }