From cad8c922f00bff82b7e5262238fa5fd2a7c3be3a Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Wed, 24 Jan 2018 22:24:45 -0800 Subject: [PATCH] Consolidate start/finish of monitor on different platforms into one API. Monitor is started either before main loop, if scanner isn't running, or in the main loop once we finished waiting for the scanner. --- minidlna.c | 63 ++++++++++++++++++++++++----------------------- monitor.h | 11 ++------- monitor_inotify.c | 38 ++++++++++++++++++++-------- monitor_kqueue.c | 14 +++++++---- 4 files changed, 71 insertions(+), 55 deletions(-) diff --git a/minidlna.c b/minidlna.c index b2769ae..aff7f79 100644 --- a/minidlna.c +++ b/minidlna.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -1088,6 +1087,19 @@ init(int argc, char **argv) return 0; } +#ifdef HAVE_WATCH +void +start_monitor() +{ + + if (!GETFLAG(INOTIFY_MASK)) + return; + + lav_register_all(); + monitor_start(); +} +#endif + /* === main === */ /* process HTTP or SSDP requests */ int @@ -1103,7 +1115,6 @@ main(int argc, char **argv) u_long timeout; /* in milliseconds */ int last_changecnt = 0; pid_t scanner_pid = 0; - pthread_t inotify_thread = 0; struct event ssdpev, httpev, monev; #ifdef TIVO_SUPPORT uint8_t beacon_interval = 5; @@ -1138,23 +1149,11 @@ main(int argc, char **argv) } check_db(db, ret, &scanner_pid); lastdbtime = _get_dbtime(); -#ifdef HAVE_INOTIFY - if( GETFLAG(INOTIFY_MASK) ) - { - if (!sqlite3_threadsafe() || sqlite3_libversion_number() < 3005001) - DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not threadsafe! " - "Inotify will be disabled.\n"); - else if (pthread_create(&inotify_thread, NULL, start_inotify, NULL) != 0) - DPRINTF(E_FATAL, L_GENERAL, "ERROR: pthread_create() failed for start_inotify. EXITING\n"); - } -#endif /* HAVE_INOTIFY */ -#ifdef HAVE_KQUEUE - if (!GETFLAG(SCANNING_MASK)) { - lav_register_all(); - kqueue_monitor_start(); - } -#endif /* HAVE_KQUEUE */ +#ifdef HAVE_WATCH + if (!GETFLAG(SCANNING_MASK)) + start_monitor(); +#endif smonitor = OpenAndConfMonitorSocket(); if (smonitor > 0) @@ -1272,14 +1271,18 @@ main(int argc, char **argv) } #endif - if (GETFLAG(SCANNING_MASK) && kill(scanner_pid, 0) != 0) { - CLEARFLAG(SCANNING_MASK); - if (_get_dbtime() != lastdbtime) - updateID++; -#ifdef HAVE_KQUEUE - lav_register_all(); - kqueue_monitor_start(); -#endif /* HAVE_KQUEUE */ + if (GETFLAG(SCANNING_MASK)) { + if (kill(scanner_pid, 0) != 0) { + DPRINTF(E_INFO, L_GENERAL, "Scanner exited\n"); + CLEARFLAG(SCANNING_MASK); + if (_get_dbtime() != lastdbtime) + updateID++; +#ifdef HAVE_WATCH + start_monitor(); +#endif + } else + /* Keep checking for the scanner every sec. */ + timeout = 1000; } event_module.process(timeout); @@ -1351,11 +1354,9 @@ shutdown: close(lan_addr[i].snotify); } - if (inotify_thread) - { - pthread_kill(inotify_thread, SIGCHLD); - pthread_join(inotify_thread, NULL); - } +#ifdef HAVE_WATCH + monitor_stop(); +#endif /* kill other child processes */ process_reap_children(); diff --git a/monitor.h b/monitor.h index af30670..1040df5 100644 --- a/monitor.h +++ b/monitor.h @@ -7,13 +7,6 @@ int monitor_remove_directory(int fd, const char * path); #define HAVE_WATCH 1 int monitor_add_watch(int, const char *); int monitor_remove_watch(int, const char *); -#endif - -#ifdef HAVE_INOTIFY -void * -start_inotify(); -#endif - -#ifdef HAVE_KQUEUE -void kqueue_monitor_start(); +void monitor_start(); +void monitor_stop(); #endif diff --git a/monitor_inotify.c b/monitor_inotify.c index cfc20e8..6e4276c 100644 --- a/monitor_inotify.c +++ b/monitor_inotify.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ struct watch static struct watch *watches; static struct watch *lastwatch = NULL; +static pthread_t thread_id; static char * get_path_from_wd(int wd) @@ -253,8 +255,8 @@ inotify_remove_watches(int fd) return rm_watches; } -void * -start_inotify(void) +static void * +inotify_thread(void *arg) { struct pollfd pollfds[1]; char buffer[BUF_LEN]; @@ -274,17 +276,10 @@ start_inotify(void) if ( pollfds[0].fd < 0 ) DPRINTF(E_ERROR, L_INOTIFY, "inotify_init() failed!\n"); - while( GETFLAG(SCANNING_MASK) ) - { - if( quitting ) - goto quitting; - sleep(1); - } inotify_create_watches(pollfds[0].fd); if (setpriority(PRIO_PROCESS, 0, 19) == -1) DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread priority\n"); sqlite3_release_memory(1<<31); - lav_register_all(); while( !quitting ) { @@ -379,8 +374,31 @@ start_inotify(void) } } inotify_remove_watches(pollfds[0].fd); -quitting: close(pollfds[0].fd); return 0; } + +void +monitor_start(void) +{ + + if (!sqlite3_threadsafe() || sqlite3_libversion_number() < 3005001) { + DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not threadsafe!" + "Inotify will be disabled.\n"); + return; + } + if (pthread_create(&thread_id, NULL, inotify_thread, NULL) != 0) + DPRINTF(E_FATAL, L_GENERAL, "pthread_create() failed [%s]\n", + strerror(errno)); +} + +void +monitor_stop(void) +{ + + if (thread_id != 0) { + pthread_kill(thread_id, SIGCHLD); + pthread_join(thread_id, NULL); + } +} diff --git a/monitor_kqueue.c b/monitor_kqueue.c index eba34a7..b16e40f 100644 --- a/monitor_kqueue.c +++ b/monitor_kqueue.c @@ -259,13 +259,12 @@ monitor_remove_watch(int fd __unused, const char *path __unused) } /* - * XXXGL: this function has too much copypaste of inotify_create_watches(). - * We need to split out inotify stuff from monitor.c into monitor_inotify.c, - * compile the latter on Linux and this file on FreeBSD, and keep monitor.c - * itself platform independent. + * XXXGL: this function has some copypaste with inotify_create_watches(). + * We need to push more code to platform independent start_monitor() + * in minidlna.c. */ void -kqueue_monitor_start() +monitor_start() { struct media_dir_s *media_path; char **result; @@ -280,3 +279,8 @@ kqueue_monitor_start() monitor_add_watch(0, result[i]); sqlite3_free_table(result); } + +void +monitor_stop() +{ +}