mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-28 06:56:01 -05:00
Rework user rating updates
This commit is contained in:
parent
bbc5d3787e
commit
ef52f4ddc0
@ -1596,7 +1596,7 @@ cache_init(void)
|
|||||||
|
|
||||||
cmdbase = commands_base_new(evbase_cache, NULL);
|
cmdbase = commands_base_new(evbase_cache, NULL);
|
||||||
|
|
||||||
ret = listener_add(cache_daap_listener_cb, LISTENER_DATABASE);
|
ret = listener_add(cache_daap_listener_cb, LISTENER_DATABASE | LISTENER_STICKER);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_CACHE, "Could not create listener event\n");
|
DPRINTF(E_LOG, L_CACHE, "Could not create listener event\n");
|
||||||
|
68
src/db.c
68
src/db.c
@ -329,7 +329,7 @@ static enum group_type
|
|||||||
db_group_type_bypersistentid(int64_t persistentid);
|
db_group_type_bypersistentid(int64_t persistentid);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
db_query_run(char *query, int free, int cache_update);
|
db_query_run(char *query, int free, short update_events);
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -804,7 +804,7 @@ db_purge_cruft(time_t ref)
|
|||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Running purge query '%s'\n", query);
|
DPRINTF(E_DBG, L_DB, "Running purge query '%s'\n", query);
|
||||||
|
|
||||||
ret = db_query_run(query, 1, 1);
|
ret = db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
DPRINTF(E_DBG, L_DB, "Purged %d rows\n", sqlite3_changes(hdl));
|
DPRINTF(E_DBG, L_DB, "Purged %d rows\n", sqlite3_changes(hdl));
|
||||||
|
|
||||||
@ -1496,7 +1496,7 @@ db_query_end(struct query_params *qp)
|
|||||||
* to update their cache of the library (and of course also of our own cache).
|
* to update their cache of the library (and of course also of our own cache).
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
db_query_run(char *query, int free, int library_update)
|
db_query_run(char *query, int free, short update_events)
|
||||||
{
|
{
|
||||||
char *errmsg;
|
char *errmsg;
|
||||||
int changes = 0;
|
int changes = 0;
|
||||||
@ -1527,8 +1527,8 @@ db_query_run(char *query, int free, int library_update)
|
|||||||
|
|
||||||
cache_daap_resume();
|
cache_daap_resume();
|
||||||
|
|
||||||
if (library_update && changes > 0)
|
if (update_events && changes > 0)
|
||||||
library_update_trigger();
|
library_update_trigger(update_events);
|
||||||
|
|
||||||
return ((ret != SQLITE_OK) ? -1 : 0);
|
return ((ret != SQLITE_OK) ? -1 : 0);
|
||||||
}
|
}
|
||||||
@ -2392,7 +2392,7 @@ db_file_add(struct media_file_info *mfi)
|
|||||||
|
|
||||||
sqlite3_free(query);
|
sqlite3_free(query);
|
||||||
|
|
||||||
library_update_trigger();
|
library_update_trigger(LISTENER_DATABASE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2471,7 +2471,7 @@ db_file_update(struct media_file_info *mfi)
|
|||||||
|
|
||||||
sqlite3_free(query);
|
sqlite3_free(query);
|
||||||
|
|
||||||
library_update_trigger();
|
library_update_trigger(LISTENER_DATABASE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2499,6 +2499,36 @@ db_file_seek_update(int id, uint32_t seek)
|
|||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
db_file_rating_update_byid(uint32_t id, uint32_t rating)
|
||||||
|
{
|
||||||
|
#define Q_TMPL "UPDATE files SET rating = %d WHERE id = %d;"
|
||||||
|
char *query;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
query = sqlite3_mprintf(Q_TMPL, rating, id);
|
||||||
|
|
||||||
|
ret = db_query_run(query, 1, LISTENER_STICKER);
|
||||||
|
|
||||||
|
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
|
||||||
|
#undef Q_TMPL
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
db_file_rating_update_byvirtualpath(const char *virtual_path, uint32_t rating)
|
||||||
|
{
|
||||||
|
#define Q_TMPL "UPDATE files SET rating = %d WHERE virtual_path = %Q;"
|
||||||
|
char *query;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
query = sqlite3_mprintf(Q_TMPL, rating, virtual_path);
|
||||||
|
|
||||||
|
ret = db_query_run(query, 1, LISTENER_STICKER);
|
||||||
|
|
||||||
|
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
|
||||||
|
#undef Q_TMPL
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
db_file_delete_bypath(const char *path)
|
db_file_delete_bypath(const char *path)
|
||||||
{
|
{
|
||||||
@ -2507,7 +2537,7 @@ db_file_delete_bypath(const char *path)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, path);
|
query = sqlite3_mprintf(Q_TMPL, path);
|
||||||
|
|
||||||
db_query_run(query, 1, 1);
|
db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2529,7 +2559,7 @@ db_file_disable_bypath(const char *path, char *strip, uint32_t cookie)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
|
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
|
||||||
|
|
||||||
db_query_run(query, 1, 1);
|
db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2551,7 +2581,7 @@ db_file_disable_bymatch(const char *path, char *strip, uint32_t cookie)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
|
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
|
||||||
|
|
||||||
db_query_run(query, 1, 1);
|
db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3161,7 +3191,7 @@ db_groups_cleanup()
|
|||||||
|
|
||||||
db_transaction_begin();
|
db_transaction_begin();
|
||||||
|
|
||||||
ret = db_query_run(Q_TMPL_ALBUM, 0, 1);
|
ret = db_query_run(Q_TMPL_ALBUM, 0, LISTENER_DATABASE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
db_transaction_rollback();
|
db_transaction_rollback();
|
||||||
@ -3170,7 +3200,7 @@ db_groups_cleanup()
|
|||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Removed album group-entries: %d\n", sqlite3_changes(hdl));
|
DPRINTF(E_DBG, L_DB, "Removed album group-entries: %d\n", sqlite3_changes(hdl));
|
||||||
|
|
||||||
ret = db_query_run(Q_TMPL_ARTIST, 0, 1);
|
ret = db_query_run(Q_TMPL_ARTIST, 0, LISTENER_DATABASE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
db_transaction_rollback();
|
db_transaction_rollback();
|
||||||
@ -3558,7 +3588,7 @@ db_directory_disable_bymatch(char *path, char *strip, uint32_t cookie)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, striplen, disabled, path, path, path);
|
query = sqlite3_mprintf(Q_TMPL, striplen, disabled, path, path, path);
|
||||||
|
|
||||||
db_query_run(query, 1, 1);
|
db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3571,7 +3601,7 @@ db_directory_enable_bycookie(uint32_t cookie, char *path)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, path, (int64_t)cookie);
|
query = sqlite3_mprintf(Q_TMPL, path, (int64_t)cookie);
|
||||||
|
|
||||||
ret = db_query_run(query, 1, 1);
|
ret = db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
|
|
||||||
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
|
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
@ -3586,7 +3616,7 @@ db_directory_enable_bypath(char *path)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, path);
|
query = sqlite3_mprintf(Q_TMPL, path);
|
||||||
|
|
||||||
ret = db_query_run(query, 1, 1);
|
ret = db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
|
|
||||||
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
|
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
@ -3695,7 +3725,7 @@ db_spotify_purge(void)
|
|||||||
|
|
||||||
for (i = 0; i < (sizeof(queries) / sizeof(queries[0])); i++)
|
for (i = 0; i < (sizeof(queries) / sizeof(queries[0])); i++)
|
||||||
{
|
{
|
||||||
ret = db_query_run(queries[i], 0, 1);
|
ret = db_query_run(queries[i], 0, LISTENER_DATABASE);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
DPRINTF(E_DBG, L_DB, "Processed %d rows\n", sqlite3_changes(hdl));
|
DPRINTF(E_DBG, L_DB, "Processed %d rows\n", sqlite3_changes(hdl));
|
||||||
@ -3708,7 +3738,7 @@ db_spotify_purge(void)
|
|||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ret = db_query_run(query, 1, 1);
|
ret = db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
DPRINTF(E_DBG, L_DB, "Disabled spotify directory\n");
|
DPRINTF(E_DBG, L_DB, "Disabled spotify directory\n");
|
||||||
@ -3733,7 +3763,7 @@ db_spotify_pl_delete(int id)
|
|||||||
{
|
{
|
||||||
query = sqlite3_mprintf(queries_tmpl[i], id);
|
query = sqlite3_mprintf(queries_tmpl[i], id);
|
||||||
|
|
||||||
ret = db_query_run(query, 1, 1);
|
ret = db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
DPRINTF(E_DBG, L_DB, "Deleted %d rows\n", sqlite3_changes(hdl));
|
DPRINTF(E_DBG, L_DB, "Deleted %d rows\n", sqlite3_changes(hdl));
|
||||||
@ -3750,7 +3780,7 @@ db_spotify_files_delete(void)
|
|||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL);
|
query = sqlite3_mprintf(Q_TMPL);
|
||||||
|
|
||||||
ret = db_query_run(query, 1, 1);
|
ret = db_query_run(query, 1, LISTENER_DATABASE);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
DPRINTF(E_DBG, L_DB, "Deleted %d rows\n", sqlite3_changes(hdl));
|
DPRINTF(E_DBG, L_DB, "Deleted %d rows\n", sqlite3_changes(hdl));
|
||||||
|
6
src/db.h
6
src/db.h
@ -559,6 +559,12 @@ db_file_update(struct media_file_info *mfi);
|
|||||||
void
|
void
|
||||||
db_file_seek_update(int id, uint32_t seek);
|
db_file_seek_update(int id, uint32_t seek);
|
||||||
|
|
||||||
|
int
|
||||||
|
db_file_rating_update_byid(uint32_t id, uint32_t rating);
|
||||||
|
|
||||||
|
int
|
||||||
|
db_file_rating_update_byvirtualpath(const char *virtual_path, uint32_t rating);
|
||||||
|
|
||||||
void
|
void
|
||||||
db_file_delete_bypath(const char *path);
|
db_file_delete_bypath(const char *path);
|
||||||
|
|
||||||
|
@ -1005,7 +1005,6 @@ dacp_propset_repeatstate(const char *value, struct evkeyvalq *query)
|
|||||||
static void
|
static void
|
||||||
dacp_propset_userrating(const char *value, struct evkeyvalq *query)
|
dacp_propset_userrating(const char *value, struct evkeyvalq *query)
|
||||||
{
|
{
|
||||||
struct media_file_info *mfi;
|
|
||||||
const char *param;
|
const char *param;
|
||||||
uint32_t itemid;
|
uint32_t itemid;
|
||||||
uint32_t rating;
|
uint32_t rating;
|
||||||
@ -1052,35 +1051,31 @@ dacp_propset_userrating(const char *value, struct evkeyvalq *query)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfi = db_file_fetch_byid(itemid);
|
ret = db_file_rating_update_byid(itemid, rating);
|
||||||
|
|
||||||
/* If no mfi, it may be because we sent an invalid nowplaying itemid. In this
|
/* If no mfi, it may be because we sent an invalid nowplaying itemid. In this
|
||||||
* case request the real one from the player and default to that.
|
* case request the real one from the player and default to that.
|
||||||
*/
|
*/
|
||||||
if (!mfi)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_DACP, "Invalid id %d for rating, defaulting to player id\n", itemid);
|
DPRINTF(E_WARN, L_DACP, "Invalid id %d for rating, defaulting to player id\n", itemid);
|
||||||
|
|
||||||
ret = player_now_playing(&itemid);
|
ret = player_now_playing(&itemid);
|
||||||
if ((ret < 0) || !(mfi = db_file_fetch_byid(itemid)))
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_WARN, L_DACP, "Could not find an id for rating\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = db_file_rating_update_byid(itemid, rating);
|
||||||
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_DACP, "Could not find an id for rating\n");
|
DPRINTF(E_WARN, L_DACP, "Could not find an id for rating\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mfi->rating = rating;
|
|
||||||
|
|
||||||
/* rating is shared as MPD sticker `rating` */
|
|
||||||
listener_notify(LISTENER_STICKER);
|
|
||||||
|
|
||||||
/* We're not touching any string field in mfi, so it's safe to
|
|
||||||
* skip unicode_fixup_mfi() before the update
|
|
||||||
*/
|
|
||||||
db_file_update(mfi);
|
|
||||||
|
|
||||||
free_mfi(mfi, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ static struct event *updateev;
|
|||||||
// Counts the number of changes made to the database between to DATABASE
|
// Counts the number of changes made to the database between to DATABASE
|
||||||
// event notifications
|
// event notifications
|
||||||
static unsigned int deferred_update_notifications = 0;
|
static unsigned int deferred_update_notifications = 0;
|
||||||
|
static short deferred_update_events = 0;
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
handle_deferred_update_notifications(void)
|
handle_deferred_update_notifications(void)
|
||||||
@ -654,14 +655,18 @@ update_trigger_cb(int fd, short what, void *arg)
|
|||||||
{
|
{
|
||||||
if (handle_deferred_update_notifications())
|
if (handle_deferred_update_notifications())
|
||||||
{
|
{
|
||||||
listener_notify(LISTENER_DATABASE);
|
listener_notify(deferred_update_events);
|
||||||
|
deferred_update_events = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum command_state
|
static enum command_state
|
||||||
update_trigger(void *arg, int *retval)
|
update_trigger(void *arg, int *retval)
|
||||||
{
|
{
|
||||||
|
short *events = arg;
|
||||||
|
|
||||||
++deferred_update_notifications;
|
++deferred_update_notifications;
|
||||||
|
deferred_update_events |= *events;
|
||||||
|
|
||||||
// Only add the timer event if the update occurred outside a (init-/re-/fullre-) scan.
|
// Only add the timer event if the update occurred outside a (init-/re-/fullre-) scan.
|
||||||
// The scanning functions take care of notifying clients of database changes directly
|
// The scanning functions take care of notifying clients of database changes directly
|
||||||
@ -780,19 +785,22 @@ library_is_exiting()
|
|||||||
* is emitted with the delay 'library_update_wait'. It is safe to call this function from any thread.
|
* is emitted with the delay 'library_update_wait'. It is safe to call this function from any thread.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
library_update_trigger(void)
|
library_update_trigger(short update_events)
|
||||||
{
|
{
|
||||||
|
short *events;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
pthread_t current_thread = pthread_self();
|
pthread_t current_thread = pthread_self();
|
||||||
if (pthread_equal(current_thread, tid_library))
|
if (pthread_equal(current_thread, tid_library))
|
||||||
{
|
{
|
||||||
// We are already running in the library thread, it is safe to directly call update_trigger
|
// We are already running in the library thread, it is safe to directly call update_trigger
|
||||||
update_trigger(NULL, &ret);
|
update_trigger(&update_events, &ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
commands_exec_async(cmdbase, update_trigger, NULL);
|
events = malloc(sizeof(short));
|
||||||
|
*events = update_events;
|
||||||
|
commands_exec_async(cmdbase, update_trigger, events);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ bool
|
|||||||
library_is_exiting();
|
library_is_exiting();
|
||||||
|
|
||||||
void
|
void
|
||||||
library_update_trigger(void);
|
library_update_trigger(short update_events);
|
||||||
|
|
||||||
int
|
int
|
||||||
library_playlist_add(const char *vp_playlist, const char *vp_item);
|
library_playlist_add(const char *vp_playlist, const char *vp_item);
|
||||||
|
42
src/mpd.c
42
src/mpd.c
@ -3423,9 +3423,6 @@ static struct mpd_sticker_command mpd_sticker_handlers[] = {
|
|||||||
{ NULL, NULL, 0, 0, 0 },
|
{ NULL, NULL, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
mpd_add_idle_events(short event_mask);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command handler function for 'sticker'
|
* Command handler function for 'sticker'
|
||||||
*
|
*
|
||||||
@ -3511,12 +3508,7 @@ mpd_command_sticker(struct evbuffer *evbuf, int argc, char **argv, char **errmsg
|
|||||||
|
|
||||||
if (ret == 0 && mfi && set_rating && mfi->rating != rating)
|
if (ret == 0 && mfi && set_rating && mfi->rating != rating)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_MPD, "STICKER notification for changed rating: %d -> %d\n", mfi->rating, rating);
|
db_file_rating_update_byvirtualpath(virtual_path, rating);
|
||||||
mfi->rating = rating;
|
|
||||||
/* Note, that a DATABASE event is triggered, but the
|
|
||||||
* client actually expects a sticker event, so add it here. */
|
|
||||||
mpd_add_idle_events(LISTENER_STICKER);
|
|
||||||
db_file_update(mfi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(virtual_path);
|
free(virtual_path);
|
||||||
@ -5057,28 +5049,6 @@ mpd_accept_error_cb(struct evconnlistener *listener, void *ctx)
|
|||||||
DPRINTF(E_LOG, L_MPD, "Error occured %d (%s) on the listener.\n", err, evutil_socket_error_to_string(err));
|
DPRINTF(E_LOG, L_MPD, "Error occured %d (%s) on the listener.\n", err, evutil_socket_error_to_string(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
mpd_add_idle_events(short event_mask)
|
|
||||||
{
|
|
||||||
struct mpd_client_ctx *client;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MPD, "Add idle events (untriggered): %d\n", event_mask);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
client = mpd_clients;
|
|
||||||
while (client)
|
|
||||||
{
|
|
||||||
client->events |= event_mask;
|
|
||||||
if (client->is_idle)
|
|
||||||
{
|
|
||||||
client->events &= client->idle_events;
|
|
||||||
}
|
|
||||||
client = client->next;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
||||||
{
|
{
|
||||||
@ -5154,22 +5124,12 @@ static void
|
|||||||
mpd_listener_cb(short event_mask)
|
mpd_listener_cb(short event_mask)
|
||||||
{
|
{
|
||||||
short *ptr;
|
short *ptr;
|
||||||
pthread_t current_thread = pthread_self();
|
|
||||||
|
|
||||||
if (pthread_equal(current_thread, tid_mpd))
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
DPRINTF(E_DBG, L_MPD, "Immediate listener callback called with event type %d.\n", event_mask);
|
|
||||||
mpd_notify_idle(&event_mask, &ret);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = (short *)malloc(sizeof(short));
|
ptr = (short *)malloc(sizeof(short));
|
||||||
*ptr = event_mask;
|
*ptr = event_mask;
|
||||||
DPRINTF(E_DBG, L_MPD, "Asynchronous listener callback called with event type %d.\n", event_mask);
|
DPRINTF(E_DBG, L_MPD, "Asynchronous listener callback called with event type %d.\n", event_mask);
|
||||||
commands_exec_async(cmdbase, mpd_notify_idle, ptr);
|
commands_exec_async(cmdbase, mpd_notify_idle, ptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback function that handles http requests for artwork files
|
* Callback function that handles http requests for artwork files
|
||||||
|
Loading…
x
Reference in New Issue
Block a user