]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
inotify routines: recode the shutdown sequence
authorJaroslav Kysela <perex@perex.cz>
Fri, 11 Mar 2016 10:31:27 +0000 (11:31 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 11 Mar 2016 10:31:27 +0000 (11:31 +0100)
src/dvr/dvr_inotify.c
src/fsmonitor.c

index 8f0a9c2cae21ac8710365d6ba469377f7218d4d9..4ead008a6ee5e10ccc6289e7c6517a90517a6581 100644 (file)
@@ -70,8 +70,8 @@ pthread_t dvr_inotify_tid;
 
 void dvr_inotify_init ( void )
 {
-  _inot_fd = inotify_init1(IN_CLOEXEC);
-  if (_inot_fd < 0) {
+  atomic_set(&_inot_fd, inotify_init1(IN_CLOEXEC));
+  if (atomic_get(&_inot_fd) < 0) {
     tvhlog(LOG_ERR, "dvr", "failed to initialise inotify (err=%s)",
            strerror(errno));
     return;
@@ -85,11 +85,10 @@ void dvr_inotify_init ( void )
  */
 void dvr_inotify_done ( void )
 {
-  shutdown(_inot_fd, SHUT_RDWR);
+  int fd = atomic_exchange(&_inot_fd, -1);
+  if (fd >= 0) close(fd);
   pthread_kill(dvr_inotify_tid, SIGTERM);
   pthread_join(dvr_inotify_tid, NULL);
-  close(_inot_fd);
-  _inot_fd = -1;
   SKEL_FREE(dvr_inotify_entry_skel);
 }
 
@@ -115,9 +114,10 @@ static void dvr_inotify_add_one ( dvr_entry_t *de, htsmsg_t *m )
   dvr_inotify_entry_t *e;
   const char *filename;
   char *path;
+  int fd = atomic_get(&_inot_fd);
 
   filename = htsmsg_get_str(m, "filename");
-  if (filename == NULL)
+  if (filename == NULL || fd < 0)
     return;
 
   path = strdupa(filename);
@@ -130,7 +130,7 @@ static void dvr_inotify_add_one ( dvr_entry_t *de, htsmsg_t *m )
     e       = dvr_inotify_entry_skel;
     SKEL_USED(dvr_inotify_entry_skel);
     e->path = strdup(e->path);
-    e->fd   = inotify_add_watch(_inot_fd, e->path, EVENT_MASK);
+    e->fd   = inotify_add_watch(fd, e->path, EVENT_MASK);
   }
 
   if (!dvr_inotify_exists(e, de)) {
@@ -154,7 +154,7 @@ void dvr_inotify_add ( dvr_entry_t *de )
   htsmsg_field_t *f;
   htsmsg_t *m;
 
-  if (_inot_fd < 0 || de->de_files == NULL)
+  if (atomic_get(&_inot_fd) < 0 || de->de_files == NULL)
     return;
 
   HTSMSG_FOREACH(f, de->de_files)
@@ -169,6 +169,8 @@ void dvr_inotify_del ( dvr_entry_t *de )
 {
   dvr_inotify_filename_t *f = NULL, *f_next;
   dvr_inotify_entry_t *e, *e_next;
+  int fd;
+
   lock_assert(&global_lock);
 
   for (e = RB_FIRST(&_inot_tree); e; e = e_next) {
@@ -180,8 +182,9 @@ void dvr_inotify_del ( dvr_entry_t *de )
         free(f);
         if (LIST_FIRST(&e->entries) == NULL) {
           RB_REMOVE(&_inot_tree, e, link);
-          if (e->fd >= 0)
-            inotify_rm_watch(_inot_fd, e->fd);
+          fd = atomic_get(&_inot_fd);
+          if (e->fd >= 0 && fd >= 0)
+            inotify_rm_watch(fd, e->fd);
           free(e->path);
           free(e);
         }
@@ -321,7 +324,7 @@ _dvr_inotify_delete_all
  */
 void* _dvr_inotify_thread ( void *p )
 {
-  int i, len;
+  int fd, i, len;
   char buf[EVENT_BUF_LEN];
   const char *from;
   int fromfd;
@@ -334,8 +337,11 @@ void* _dvr_inotify_thread ( void *p )
     cookie = 0;
     from   = NULL;
     i      = 0;
-    len    = read(_inot_fd, buf, EVENT_BUF_LEN);
-    if (_inot_fd < 0)
+    fd     = atomic_get(&_inot_fd);
+    if (fd < 0)
+      break;
+    len    = read(fd, buf, EVENT_BUF_LEN);
+    if (len < 0)
       break;
 
     /* Process */
index ad6b1c089da260fb72394e64eb0a5d6c5cc280f3..bf2f3a6a8108d381b92ff72e4a958dd8ab6cfd29 100644 (file)
@@ -45,7 +45,7 @@ fmp_cmp ( fsmonitor_path_t *a, fsmonitor_path_t *b )
 static void *
 fsmonitor_thread ( void* p )
 {
-  int c, i;
+  int fd, c, i;
   uint8_t buf[sizeof(struct inotify_event) * 10];
   char path[1024];
   struct inotify_event *ev;
@@ -55,9 +55,13 @@ fsmonitor_thread ( void* p )
 
   while (atomic_get(&tvheadend_running)) {
 
+    fd = atomic_get(&fsmonitor_fd);
+    if (fd < 0)
+      break;
+
     /* Wait for event */
-    c = read(fsmonitor_fd, buf, sizeof(buf));
-    if (fsmonitor_fd < 0)
+    c = read(fd, buf, sizeof(buf));
+    if (c < 0)
       break;
 
     /* Process */
@@ -105,7 +109,7 @@ void
 fsmonitor_init ( void )
 {
   /* Intialise inotify */
-  fsmonitor_fd = inotify_init1(IN_CLOEXEC);
+  atomic_set(&fsmonitor_fd, inotify_init1(IN_CLOEXEC));
   tvhthread_create(&fsmonitor_tid, NULL, fsmonitor_thread, NULL, "fsmonitor");
 }
 
@@ -115,11 +119,10 @@ fsmonitor_init ( void )
 void
 fsmonitor_done ( void )
 {
-  shutdown(fsmonitor_fd, SHUT_RDWR);
+  int fd = atomic_exchange(&fsmonitor_fd, -1);
+  if (fd >= 0) close(fd);
   pthread_kill(fsmonitor_tid, SIGTERM);
   pthread_join(fsmonitor_tid, NULL);
-  close(fsmonitor_fd);
-  fsmonitor_fd = -1;
 }
 
 /*
@@ -128,7 +131,7 @@ fsmonitor_done ( void )
 int
 fsmonitor_add ( const char *path, fsmonitor_t *fsm )
 {
-  int mask;
+  int fd, mask;
   fsmonitor_path_t *skel;
   fsmonitor_path_t *fmp;
   fsmonitor_link_t *fml;
@@ -145,7 +148,11 @@ fsmonitor_add ( const char *path, fsmonitor_t *fsm )
   fmp = RB_INSERT_SORTED(&fsmonitor_paths, skel, fmp_link, fmp_cmp);
   if (!fmp) {
     fmp = skel;
-    fmp->fmp_fd = inotify_add_watch(fsmonitor_fd, path, mask);
+    fd  = atomic_get(&fsmonitor_fd);
+    if (fd >= 0)
+      fmp->fmp_fd = inotify_add_watch(fd, path, mask);
+    else
+      fmp->fmp_fd = -1;
 
     /* Failed */
     if (fmp->fmp_fd <= 0) {
@@ -187,6 +194,7 @@ fsmonitor_del ( const char *path, fsmonitor_t *fsm )
   static fsmonitor_path_t skel;
   fsmonitor_path_t *fmp;
   fsmonitor_link_t *fml;
+  int fd;
 
   lock_assert(&global_lock);
 
@@ -212,7 +220,9 @@ fsmonitor_del ( const char *path, fsmonitor_t *fsm )
     if (LIST_EMPTY(&fmp->fmp_monitors)) {
       tvhdebug("fsmonitor", "unwatch %s", fmp->fmp_path);
       RB_REMOVE(&fsmonitor_paths, fmp, fmp_link);
-      inotify_rm_watch(fsmonitor_fd, fmp->fmp_fd);
+      fd = atomic_get(&fsmonitor_fd);
+      if (fd >= 0)
+        inotify_rm_watch(fd, fmp->fmp_fd);
       free(fmp->fmp_path);
       free(fmp);
     }