From: Jaroslav Kysela Date: Fri, 11 Mar 2016 10:31:27 +0000 (+0100) Subject: inotify routines: recode the shutdown sequence X-Git-Tag: v4.2.1~882 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58b91af588d5bfa541d927d55f5fbb9acef711ce;p=thirdparty%2Ftvheadend.git inotify routines: recode the shutdown sequence --- diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index 8f0a9c2ca..4ead008a6 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -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 */ diff --git a/src/fsmonitor.c b/src/fsmonitor.c index ad6b1c089..bf2f3a6a8 100644 --- a/src/fsmonitor.c +++ b/src/fsmonitor.c @@ -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); }