Prevent this database deadlock:

1. bulk scan begins transaction, locking the db
2. cache regeneration is triggered, but waits for db to unlock
3. bulk scan calls cache_artwork_ping, which can't return because cache thread is waiting
-> scan thread is waiting for cache thread, which is waiting for scan thread
This commit is contained in:
ejurgensen 2015-06-08 22:24:33 +02:00
parent 4fffc057b6
commit 335517a2e8
2 changed files with 29 additions and 19 deletions

View File

@ -965,9 +965,7 @@ cache_artwork_ping_impl(struct cache_command *cmd)
{ {
DPRINTF(E_LOG, L_CACHE, "Query error: %s\n", errmsg); DPRINTF(E_LOG, L_CACHE, "Query error: %s\n", errmsg);
sqlite3_free(errmsg); goto error_ping;
sqlite3_free(query);
return -1;
} }
sqlite3_free(query); sqlite3_free(query);
@ -983,16 +981,24 @@ cache_artwork_ping_impl(struct cache_command *cmd)
{ {
DPRINTF(E_LOG, L_CACHE, "Query error: %s\n", errmsg); DPRINTF(E_LOG, L_CACHE, "Query error: %s\n", errmsg);
sqlite3_free(errmsg); goto error_ping;
sqlite3_free(query);
return -1;
} }
sqlite3_free(query); sqlite3_free(query);
} }
free(cmd->arg.path);
return 0; return 0;
error_ping:
sqlite3_free(errmsg);
sqlite3_free(query);
free(cmd->arg.path);
return -1;
#undef Q_TMPL_PING #undef Q_TMPL_PING
#undef Q_TMPL_DEL #undef Q_TMPL_DEL
} }
@ -1468,27 +1474,31 @@ cache_daap_threshold(void)
* @param del if > 0 cached entries for the given path are deleted if the cached timestamp (db_timestamp) is older than mtime * @param del if > 0 cached entries for the given path are deleted if the cached timestamp (db_timestamp) is older than mtime
* @return 0 if successful, -1 if an error occurred * @return 0 if successful, -1 if an error occurred
*/ */
int void
cache_artwork_ping(char *path, time_t mtime, int del) cache_artwork_ping(char *path, time_t mtime, int del)
{ {
struct cache_command cmd; struct cache_command *cmd;
int ret;
if (!g_initialized) if (!g_initialized)
return -1; return;
command_init(&cmd); cmd = (struct cache_command *)malloc(sizeof(struct cache_command));
if (!cmd)
{
DPRINTF(E_LOG, L_CACHE, "Could not allocate cache_command\n");
return;
}
cmd.func = cache_artwork_ping_impl; memset(cmd, 0, sizeof(struct cache_command));
cmd.arg.path = strdup(path);
cmd.arg.mtime = mtime;
cmd.arg.del = del;
ret = sync_command(&cmd); cmd->nonblock = 1;
command_deinit(&cmd); cmd->func = cache_artwork_ping_impl;
cmd->arg.path = strdup(path);
cmd->arg.mtime = mtime;
cmd->arg.del = del;
return ret; nonblock_command(cmd);
} }
/* /*

View File

@ -30,7 +30,7 @@ cache_daap_threshold(void);
#define CACHE_ARTWORK_GROUP 0 #define CACHE_ARTWORK_GROUP 0
#define CACHE_ARTWORK_INDIVIDUAL 1 #define CACHE_ARTWORK_INDIVIDUAL 1
int void
cache_artwork_ping(char *path, time_t mtime, int del); cache_artwork_ping(char *path, time_t mtime, int del);
int int