mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-05 02:38:09 -05:00
[filescanner] Use generic inter thread commands util
This commit is contained in:
parent
4aacf487e8
commit
3823900394
@ -61,6 +61,7 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "artwork.h"
|
#include "artwork.h"
|
||||||
|
#include "commands.h"
|
||||||
|
|
||||||
#ifdef LASTFM
|
#ifdef LASTFM
|
||||||
# include "lastfm.h"
|
# include "lastfm.h"
|
||||||
@ -69,21 +70,6 @@
|
|||||||
# include "spotify.h"
|
# include "spotify.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct filescanner_command;
|
|
||||||
|
|
||||||
typedef int (*cmd_func)(struct filescanner_command *cmd);
|
|
||||||
|
|
||||||
struct filescanner_command
|
|
||||||
{
|
|
||||||
pthread_mutex_t lck;
|
|
||||||
pthread_cond_t cond;
|
|
||||||
|
|
||||||
cmd_func func;
|
|
||||||
|
|
||||||
int nonblock;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define F_SCAN_BULK (1 << 0)
|
#define F_SCAN_BULK (1 << 0)
|
||||||
#define F_SCAN_RESCAN (1 << 1)
|
#define F_SCAN_RESCAN (1 << 1)
|
||||||
@ -118,17 +104,16 @@ struct stacked_dir {
|
|||||||
struct stacked_dir *next;
|
struct stacked_dir *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cmd_pipe[2];
|
|
||||||
static int exit_pipe[2];
|
static int exit_pipe[2];
|
||||||
static int scan_exit;
|
static int scan_exit;
|
||||||
static int inofd;
|
static int inofd;
|
||||||
static struct event_base *evbase_scan;
|
static struct event_base *evbase_scan;
|
||||||
static struct event *inoev;
|
static struct event *inoev;
|
||||||
static struct event *exitev;
|
static struct event *exitev;
|
||||||
static struct event *cmdev;
|
|
||||||
static pthread_t tid_scan;
|
static pthread_t tid_scan;
|
||||||
static struct deferred_pl *playlists;
|
static struct deferred_pl *playlists;
|
||||||
static struct stacked_dir *dirstack;
|
static struct stacked_dir *dirstack;
|
||||||
|
static struct commands_base *cmdbase;
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
struct deferred_file
|
struct deferred_file
|
||||||
@ -167,47 +152,12 @@ static int
|
|||||||
inofd_event_set(void);
|
inofd_event_set(void);
|
||||||
static void
|
static void
|
||||||
inofd_event_unset(void);
|
inofd_event_unset(void);
|
||||||
static int
|
static enum command_state
|
||||||
filescanner_initscan(struct filescanner_command *cmd);
|
filescanner_initscan(void *arg, int *retval);
|
||||||
static int
|
static enum command_state
|
||||||
filescanner_fullrescan(struct filescanner_command *cmd);
|
filescanner_fullrescan(void *arg, int *retval);
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------- COMMAND EXECUTION -------------------------- */
|
|
||||||
|
|
||||||
static int
|
|
||||||
send_command(struct filescanner_command *cmd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!cmd->func)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "BUG: cmd->func is NULL!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = write(cmd_pipe[1], &cmd, sizeof(cmd));
|
|
||||||
if (ret != sizeof(cmd))
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not send command: %s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
nonblock_command(struct filescanner_command *cmd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = send_command(cmd);
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
push_dir(struct stacked_dir **s, char *path, int parent_id)
|
push_dir(struct stacked_dir **s, char *path, int parent_id)
|
||||||
{
|
{
|
||||||
@ -855,6 +805,7 @@ static void
|
|||||||
process_file(char *file, time_t mtime, off_t size, int type, int flags, int dir_id)
|
process_file(char *file, time_t mtime, off_t size, int type, int flags, int dir_id)
|
||||||
{
|
{
|
||||||
int is_bulkscan;
|
int is_bulkscan;
|
||||||
|
int ret;
|
||||||
|
|
||||||
is_bulkscan = (flags & F_SCAN_BULK);
|
is_bulkscan = (flags & F_SCAN_BULK);
|
||||||
|
|
||||||
@ -924,7 +875,7 @@ process_file(char *file, time_t mtime, off_t size, int type, int flags, int dir_
|
|||||||
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Startup rescan triggered, found init-rescan file: %s\n", file);
|
DPRINTF(E_LOG, L_SCAN, "Startup rescan triggered, found init-rescan file: %s\n", file);
|
||||||
|
|
||||||
filescanner_initscan(NULL);
|
filescanner_initscan(NULL, &ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILE_CTRL_FULLSCAN:
|
case FILE_CTRL_FULLSCAN:
|
||||||
@ -933,7 +884,7 @@ process_file(char *file, time_t mtime, off_t size, int type, int flags, int dir_
|
|||||||
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Full rescan triggered, found full-rescan file: %s\n", file);
|
DPRINTF(E_LOG, L_SCAN, "Full rescan triggered, found full-rescan file: %s\n", file);
|
||||||
|
|
||||||
filescanner_fullrescan(NULL);
|
filescanner_fullrescan(NULL, &ret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1968,41 +1919,8 @@ exit_cb(int fd, short event, void *arg)
|
|||||||
scan_exit = 1;
|
scan_exit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static enum command_state
|
||||||
command_cb(int fd, short what, void *arg)
|
filescanner_initscan(void *arg, int *retval)
|
||||||
{
|
|
||||||
struct filescanner_command *cmd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = read(cmd_pipe[0], &cmd, sizeof(cmd));
|
|
||||||
if (ret != sizeof(cmd))
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not read command! (read %d): %s\n", ret, (ret < 0) ? strerror(errno) : "-no error-");
|
|
||||||
goto readd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->nonblock)
|
|
||||||
{
|
|
||||||
cmd->func(cmd);
|
|
||||||
|
|
||||||
free(cmd);
|
|
||||||
goto readd;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&cmd->lck);
|
|
||||||
|
|
||||||
ret = cmd->func(cmd);
|
|
||||||
cmd->ret = ret;
|
|
||||||
|
|
||||||
pthread_cond_signal(&cmd->cond);
|
|
||||||
pthread_mutex_unlock(&cmd->lck);
|
|
||||||
|
|
||||||
readd:
|
|
||||||
event_add(cmdev, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
filescanner_initscan(struct filescanner_command *cmd)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Startup rescan triggered\n");
|
DPRINTF(E_LOG, L_SCAN, "Startup rescan triggered\n");
|
||||||
|
|
||||||
@ -2012,11 +1930,12 @@ filescanner_initscan(struct filescanner_command *cmd)
|
|||||||
inofd_event_set();
|
inofd_event_set();
|
||||||
bulk_scan(F_SCAN_BULK | F_SCAN_RESCAN);
|
bulk_scan(F_SCAN_BULK | F_SCAN_RESCAN);
|
||||||
|
|
||||||
return 0;
|
*retval = 0;
|
||||||
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static enum command_state
|
||||||
filescanner_fullrescan(struct filescanner_command *cmd)
|
filescanner_fullrescan(void *arg, int *retval)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Full rescan triggered\n");
|
DPRINTF(E_LOG, L_SCAN, "Full rescan triggered\n");
|
||||||
|
|
||||||
@ -2028,62 +1947,32 @@ filescanner_fullrescan(struct filescanner_command *cmd)
|
|||||||
inofd_event_set();
|
inofd_event_set();
|
||||||
bulk_scan(F_SCAN_BULK);
|
bulk_scan(F_SCAN_BULK);
|
||||||
|
|
||||||
return 0;
|
*retval = 0;
|
||||||
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
filescanner_trigger_initscan(void)
|
filescanner_trigger_initscan(void)
|
||||||
{
|
{
|
||||||
struct filescanner_command *cmd;
|
|
||||||
|
|
||||||
if (scanning)
|
if (scanning)
|
||||||
{
|
{
|
||||||
DPRINTF(E_INFO, L_SCAN, "Scan already running, ignoring request to trigger a new init scan\n");
|
DPRINTF(E_INFO, L_SCAN, "Scan already running, ignoring request to trigger a new init scan\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commands_exec_async(cmdbase, filescanner_initscan, NULL);
|
||||||
cmd = (struct filescanner_command *)malloc(sizeof(struct filescanner_command));
|
|
||||||
if (!cmd)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not allocate cache_command\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(struct filescanner_command));
|
|
||||||
|
|
||||||
cmd->nonblock = 1;
|
|
||||||
|
|
||||||
cmd->func = filescanner_initscan;
|
|
||||||
|
|
||||||
nonblock_command(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
filescanner_trigger_fullrescan(void)
|
filescanner_trigger_fullrescan(void)
|
||||||
{
|
{
|
||||||
struct filescanner_command *cmd;
|
|
||||||
|
|
||||||
if (scanning)
|
if (scanning)
|
||||||
{
|
{
|
||||||
DPRINTF(E_INFO, L_SCAN, "Scan already running, ignoring request to trigger a new init scan\n");
|
DPRINTF(E_INFO, L_SCAN, "Scan already running, ignoring request to trigger a new init scan\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = (struct filescanner_command *)malloc(sizeof(struct filescanner_command));
|
commands_exec_async(cmdbase, filescanner_fullrescan, NULL);
|
||||||
if (!cmd)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not allocate cache_command\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(struct filescanner_command));
|
|
||||||
|
|
||||||
cmd->nonblock = 1;
|
|
||||||
|
|
||||||
cmd->func = filescanner_fullrescan;
|
|
||||||
|
|
||||||
nonblock_command(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2138,23 +2027,7 @@ filescanner_init(void)
|
|||||||
goto ino_fail;
|
goto ino_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PIPE2
|
cmdbase = commands_base_new(evbase_scan);
|
||||||
ret = pipe2(cmd_pipe, O_CLOEXEC);
|
|
||||||
#else
|
|
||||||
ret = pipe(cmd_pipe);
|
|
||||||
#endif
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not create command pipe: %s\n", strerror(errno));
|
|
||||||
goto cmd_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdev = event_new(evbase_scan, cmd_pipe[0], EV_READ, command_cb, NULL);
|
|
||||||
if (!cmdev || (event_add(cmdev, NULL) < 0))
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not create/add command event\n");
|
|
||||||
goto cmd_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pthread_create(&tid_scan, NULL, filescanner, NULL);
|
ret = pthread_create(&tid_scan, NULL, filescanner, NULL);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
@ -2173,9 +2046,7 @@ filescanner_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
thread_fail:
|
thread_fail:
|
||||||
cmd_fail:
|
commands_base_free(cmdbase);
|
||||||
close(cmd_pipe[0]);
|
|
||||||
close(cmd_pipe[1]);
|
|
||||||
close(inofd);
|
close(inofd);
|
||||||
exitev_fail:
|
exitev_fail:
|
||||||
ino_fail:
|
ino_fail:
|
||||||
@ -2216,7 +2087,6 @@ filescanner_deinit(void)
|
|||||||
|
|
||||||
close(exit_pipe[0]);
|
close(exit_pipe[0]);
|
||||||
close(exit_pipe[1]);
|
close(exit_pipe[1]);
|
||||||
close(cmd_pipe[0]);
|
commands_base_free(cmdbase);
|
||||||
close(cmd_pipe[1]);
|
|
||||||
event_base_free(evbase_scan);
|
event_base_free(evbase_scan);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user