Skip to content

Commit eaa410b

Browse files
committed
Fix thread contention in string-cache
Both database.c and callback.c use the hashtree code, so the cache needs to be protected with a lock.
1 parent 2441d3b commit eaa410b

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

string-cache.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef struct
3434
} StringCacheEntry;
3535

3636
static GHashTable *string_cache = NULL;
37+
static pthread_mutex_t string_cache_lock = PTHREAD_MUTEX_INITIALIZER;
3738

3839
/* Function to create a new cache entry. */
3940
static StringCacheEntry *
@@ -68,19 +69,20 @@ string_cache_get (const char *str)
6869
return NULL;
6970
}
7071

72+
pthread_mutex_lock (&string_cache_lock);
7173
StringCacheEntry *entry = g_hash_table_lookup (string_cache, str);
7274
if (entry)
7375
{
7476
entry->refcount++;
75-
return entry->str;
7677
}
7778
else
7879
{
7980
entry = string_cache_entry_new (str);
8081
/* Use entry->str as the key to ensure hash/equal functions operate on the string */
8182
g_hash_table_insert (string_cache, entry->str, entry);
82-
return entry->str;
8383
}
84+
pthread_mutex_unlock (&string_cache_lock);
85+
return entry->str;
8486
}
8587

8688
/* Decrease the reference count of a string and remove it if refcount reaches 0 */
@@ -92,6 +94,7 @@ string_cache_release (const char *str)
9294
return;
9395
}
9496

97+
pthread_mutex_lock (&string_cache_lock);
9598
StringCacheEntry *entry = g_hash_table_lookup (string_cache, str);
9699
if (entry)
97100
{
@@ -101,6 +104,7 @@ string_cache_release (const char *str)
101104
g_hash_table_remove (string_cache, str);
102105
}
103106
}
107+
pthread_mutex_unlock (&string_cache_lock);
104108
}
105109

106110
/* Amount of actual memory used to store this string */
@@ -128,18 +132,22 @@ string_cache_memuse (const char *str, bool pss)
128132
void
129133
string_cache_init ()
130134
{
135+
pthread_mutex_lock (&string_cache_lock);
131136
if (!string_cache)
132137
{
133138
string_cache =
134139
g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
135140
(GDestroyNotify) string_cache_entry_free);
136141
}
142+
pthread_mutex_unlock (&string_cache_lock);
137143
}
138144

139145
/* This function should only be called when *all* strings have been released. */
140146
void
141147
string_cache_deinit ()
142148
{
149+
pthread_mutex_lock (&string_cache_lock);
143150
g_hash_table_destroy (string_cache);
144151
string_cache = NULL;
152+
pthread_mutex_unlock (&string_cache_lock);
145153
}

0 commit comments

Comments
 (0)