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.
This commit is contained in:
Gleb Smirnoff 2018-01-24 22:24:45 -08:00
parent ee912576b3
commit cad8c922f0
4 changed files with 71 additions and 55 deletions

View File

@ -64,7 +64,6 @@
#include <time.h> #include <time.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include <limits.h> #include <limits.h>
#include <libgen.h> #include <libgen.h>
#include <pwd.h> #include <pwd.h>
@ -1088,6 +1087,19 @@ init(int argc, char **argv)
return 0; return 0;
} }
#ifdef HAVE_WATCH
void
start_monitor()
{
if (!GETFLAG(INOTIFY_MASK))
return;
lav_register_all();
monitor_start();
}
#endif
/* === main === */ /* === main === */
/* process HTTP or SSDP requests */ /* process HTTP or SSDP requests */
int int
@ -1103,7 +1115,6 @@ main(int argc, char **argv)
u_long timeout; /* in milliseconds */ u_long timeout; /* in milliseconds */
int last_changecnt = 0; int last_changecnt = 0;
pid_t scanner_pid = 0; pid_t scanner_pid = 0;
pthread_t inotify_thread = 0;
struct event ssdpev, httpev, monev; struct event ssdpev, httpev, monev;
#ifdef TIVO_SUPPORT #ifdef TIVO_SUPPORT
uint8_t beacon_interval = 5; uint8_t beacon_interval = 5;
@ -1138,23 +1149,11 @@ main(int argc, char **argv)
} }
check_db(db, ret, &scanner_pid); check_db(db, ret, &scanner_pid);
lastdbtime = _get_dbtime(); 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 #ifdef HAVE_WATCH
if (!GETFLAG(SCANNING_MASK)) { if (!GETFLAG(SCANNING_MASK))
lav_register_all(); start_monitor();
kqueue_monitor_start(); #endif
}
#endif /* HAVE_KQUEUE */
smonitor = OpenAndConfMonitorSocket(); smonitor = OpenAndConfMonitorSocket();
if (smonitor > 0) if (smonitor > 0)
@ -1272,14 +1271,18 @@ main(int argc, char **argv)
} }
#endif #endif
if (GETFLAG(SCANNING_MASK) && kill(scanner_pid, 0) != 0) { if (GETFLAG(SCANNING_MASK)) {
CLEARFLAG(SCANNING_MASK); if (kill(scanner_pid, 0) != 0) {
if (_get_dbtime() != lastdbtime) DPRINTF(E_INFO, L_GENERAL, "Scanner exited\n");
updateID++; CLEARFLAG(SCANNING_MASK);
#ifdef HAVE_KQUEUE if (_get_dbtime() != lastdbtime)
lav_register_all(); updateID++;
kqueue_monitor_start(); #ifdef HAVE_WATCH
#endif /* HAVE_KQUEUE */ start_monitor();
#endif
} else
/* Keep checking for the scanner every sec. */
timeout = 1000;
} }
event_module.process(timeout); event_module.process(timeout);
@ -1351,11 +1354,9 @@ shutdown:
close(lan_addr[i].snotify); close(lan_addr[i].snotify);
} }
if (inotify_thread) #ifdef HAVE_WATCH
{ monitor_stop();
pthread_kill(inotify_thread, SIGCHLD); #endif
pthread_join(inotify_thread, NULL);
}
/* kill other child processes */ /* kill other child processes */
process_reap_children(); process_reap_children();

View File

@ -7,13 +7,6 @@ int monitor_remove_directory(int fd, const char * path);
#define HAVE_WATCH 1 #define HAVE_WATCH 1
int monitor_add_watch(int, const char *); int monitor_add_watch(int, const char *);
int monitor_remove_watch(int, const char *); int monitor_remove_watch(int, const char *);
#endif void monitor_start();
void monitor_stop();
#ifdef HAVE_INOTIFY
void *
start_inotify();
#endif
#ifdef HAVE_KQUEUE
void kqueue_monitor_start();
#endif #endif

View File

@ -22,6 +22,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <libgen.h> #include <libgen.h>
@ -69,6 +70,7 @@ struct watch
static struct watch *watches; static struct watch *watches;
static struct watch *lastwatch = NULL; static struct watch *lastwatch = NULL;
static pthread_t thread_id;
static char * static char *
get_path_from_wd(int wd) get_path_from_wd(int wd)
@ -253,8 +255,8 @@ inotify_remove_watches(int fd)
return rm_watches; return rm_watches;
} }
void * static void *
start_inotify(void) inotify_thread(void *arg)
{ {
struct pollfd pollfds[1]; struct pollfd pollfds[1];
char buffer[BUF_LEN]; char buffer[BUF_LEN];
@ -274,17 +276,10 @@ start_inotify(void)
if ( pollfds[0].fd < 0 ) if ( pollfds[0].fd < 0 )
DPRINTF(E_ERROR, L_INOTIFY, "inotify_init() failed!\n"); 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); inotify_create_watches(pollfds[0].fd);
if (setpriority(PRIO_PROCESS, 0, 19) == -1) if (setpriority(PRIO_PROCESS, 0, 19) == -1)
DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread priority\n"); DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread priority\n");
sqlite3_release_memory(1<<31); sqlite3_release_memory(1<<31);
lav_register_all();
while( !quitting ) while( !quitting )
{ {
@ -379,8 +374,31 @@ start_inotify(void)
} }
} }
inotify_remove_watches(pollfds[0].fd); inotify_remove_watches(pollfds[0].fd);
quitting:
close(pollfds[0].fd); close(pollfds[0].fd);
return 0; 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);
}
}

View File

@ -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(). * XXXGL: this function has some copypaste with inotify_create_watches().
* We need to split out inotify stuff from monitor.c into monitor_inotify.c, * We need to push more code to platform independent start_monitor()
* compile the latter on Linux and this file on FreeBSD, and keep monitor.c * in minidlna.c.
* itself platform independent.
*/ */
void void
kqueue_monitor_start() monitor_start()
{ {
struct media_dir_s *media_path; struct media_dir_s *media_path;
char **result; char **result;
@ -280,3 +279,8 @@ kqueue_monitor_start()
monitor_add_watch(0, result[i]); monitor_add_watch(0, result[i]);
sqlite3_free_table(result); sqlite3_free_table(result);
} }
void
monitor_stop()
{
}