From 2a4e2782a1faaf8e7bf5d4123e572007e591d24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 23 Apr 2019 10:07:59 +0200 Subject: [PATCH] Prevent race condition when --update & we have duplicate pkgs (RhBug: 1696808) --- src/createrepo_c.c | 2 ++ src/dumper_thread.c | 12 ++++++++---- src/dumper_thread.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/createrepo_c.c b/src/createrepo_c.c index 444d88f..160789b 100644 --- a/src/createrepo_c.c +++ b/src/createrepo_c.c @@ -995,6 +995,7 @@ main(int argc, char **argv) user_data.id_oth = 0; user_data.buffer = g_queue_new(); user_data.mutex_buffer = g_mutex_new(); + user_data.mutex_old_md = g_mutex_new(); user_data.deltas = cmd_options->deltas; user_data.max_delta_rpm_size= cmd_options->max_delta_rpm_size; user_data.mutex_deltatargetpackages = g_mutex_new(); @@ -1049,6 +1050,7 @@ main(int argc, char **argv) g_queue_free(user_data.buffer); g_mutex_free(user_data.mutex_buffer); + g_mutex_free(user_data.mutex_old_md); g_cond_free(user_data.cond_pri); g_cond_free(user_data.cond_fil); g_cond_free(user_data.cond_oth); diff --git a/src/dumper_thread.c b/src/dumper_thread.c index 27c2493..589ab52 100644 --- a/src/dumper_thread.c +++ b/src/dumper_thread.c @@ -436,9 +436,15 @@ cr_dumper_thread(gpointer data, gpointer user_data) // Update stuff if (udata->old_metadata) { // We have old metadata + g_mutex_lock(udata->mutex_old_md); md = (cr_Package *) g_hash_table_lookup( cr_metadata_hashtable(udata->old_metadata), task->filename); + // Remove the pkg from the hash table of old metadata, so that no other + // thread can use it as CACHE, because later we modify it destructively + g_hash_table_steal(cr_metadata_hashtable(udata->old_metadata), + task->filename); + g_mutex_unlock(udata->mutex_old_md); if (md) { g_debug("CACHE HIT %s", task->filename); @@ -576,8 +582,7 @@ cr_dumper_thread(gpointer data, gpointer user_data) write_pkg(task->id, res, pkg, udata); // Clean up - if (pkg != md) - cr_package_free(pkg); + cr_package_free(pkg); g_free(res.primary); g_free(res.filelists); g_free(res.other); @@ -623,8 +628,7 @@ cr_dumper_thread(gpointer data, gpointer user_data) // Dump XML and SQLite write_pkg(buf_task->id, buf_task->res, buf_task->pkg, udata); // Clean up - if (!buf_task->pkg_from_md) - cr_package_free(buf_task->pkg); + cr_package_free(buf_task->pkg); g_free(buf_task->res.primary); g_free(buf_task->res.filelists); g_free(buf_task->res.other); diff --git a/src/dumper_thread.h b/src/dumper_thread.h index 94a57d8..74d5951 100644 --- a/src/dumper_thread.h +++ b/src/dumper_thread.h @@ -71,6 +71,7 @@ struct UserData { // Update stuff gboolean skip_stat; // Skip stat() while updating cr_Metadata *old_metadata; // Loaded metadata + GMutex *mutex_old_md; // Mutex for accessing old metadata // Thread serialization GMutex *mutex_pri; // Mutex for primary metadata