[gegl] buffer: fix race condition when disconnecting cache during trimming
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: fix race condition when disconnecting cache during trimming
- Date: Thu, 3 Jan 2019 19:06:57 +0000 (UTC)
commit b628f459d5924517524b8776a1698ad2c989e404
Author: Ell <ell_se yahoo com>
Date: Thu Jan 3 13:57:39 2019 -0500
buffer: fix race condition when disconnecting cache during trimming
Since commit 26583900327bf4cff3c8e9461d918889a103b317, we no longer
hold the global cache mutex throughout cache trimming, which
introduces a race condition when the currently-trimmed cache is
being disconnected in another thread, since we rely on the global
cache mutex for serialization. Fix this, by acquiring the local
cache tile-storage mutex, in addition to the global cache mutex,
when disconnecting a cache.
Additionally, use one of the cache's fields to indicate that the
cache is being disconnected before acquiring any of the mutexes, so
that the trimming thread can quickly release them in response,
instead of keeping trimming the cache.
gegl/buffer/gegl-tile-handler-cache.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
---
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index b7f9d75d5..4a13895c4 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -323,6 +323,10 @@ gegl_tile_handler_cache_find_oldest_cache (GeglTileHandlerCache *prev_cache)
if (! time)
continue;
+ /* the cache is being disconnected */
+ if (! cache->link.data)
+ continue;
+
if (time == stamp)
{
oldest_cache = cache;
@@ -624,6 +628,10 @@ gegl_tile_handler_cache_trim (GeglTileHandlerCache *cache)
break;
}
+ /* the cache is being disconnected */
+ if (! cache->link.data)
+ link = NULL;
+
if (! link)
continue;
@@ -947,11 +955,15 @@ gegl_tile_handler_cache_disconnect (GeglTileHandlerCache *cache)
/* leave the global cache queue */
if (cache->link.data)
{
+ cache->link.data = NULL;
+
+ g_rec_mutex_lock (&cache->tile_storage->mutex);
+
g_mutex_lock (&mutex);
g_queue_unlink (&cache_queue, &cache->link);
g_mutex_unlock (&mutex);
- cache->link.data = NULL;
+ g_rec_mutex_unlock (&cache->tile_storage->mutex);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]