summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-03-24 22:19:14 -0400
committerStef Walter <stefw@gnome.org>2013-11-06 10:30:12 +0100
commitc8fc863bf784c30a6ea1c6ca288177460e699e73 (patch)
tree2d686b6217dd4caa04120298c6bcc77096f3c38a
parentf7247b0d34d9e965e96f8f90d90df1eea5aecc7e (diff)
downloadglib-wip/gcleanup-desrt.tar.gz
GThread posix: add impl structs to cleanup listwip/gcleanup-desrt
There are two ways of using the structs like GMutex, GCond, etc. The first is to explicitly _init() and _clear() them. This is when you use them as part of another structure. This case is not interesting for gcleanup. The other is to have them in static storage (zero-filled) and just use them for the first time. This is the difficult case, because we don't ever free the impl in that case. In the first case, the impl is created and set in the _init() function. We can therfore tell that we are in the second case if we get to the get_impl() function and the impl is not there yet. In that case, add it to the cleanup list. There are probably people that allocate a GMutex as part of a zero-filled structure and use it, then call g_mutex_clear() on it. This is technically a violation of the API and these users will crash with G_DEBUG=cleanup, but that's a good thing because it will cause them to fix their code.
-rw-r--r--glib/gthread-posix.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c
index a09b7a257..bc0da94dd 100644
--- a/glib/gthread-posix.c
+++ b/glib/gthread-posix.c
@@ -47,6 +47,7 @@
#include "gslice.h"
#include "gmessages.h"
#include "gstrfuncs.h"
+#include "gcleanup.h"
#include <stdlib.h>
#include <stdio.h>
@@ -126,7 +127,9 @@ g_mutex_get_impl (GMutex *mutex)
if G_UNLIKELY (impl == NULL)
{
impl = g_mutex_impl_new ();
- if (!g_atomic_pointer_compare_and_exchange (&mutex->p, NULL, impl))
+ if (g_atomic_pointer_compare_and_exchange (&mutex->p, NULL, impl))
+ G_CLEANUP_ADD (impl, g_mutex_impl_free);
+ else
g_mutex_impl_free (impl);
impl = mutex->p;
}
@@ -295,7 +298,9 @@ g_rec_mutex_get_impl (GRecMutex *rec_mutex)
if G_UNLIKELY (impl == NULL)
{
impl = g_rec_mutex_impl_new ();
- if (!g_atomic_pointer_compare_and_exchange (&rec_mutex->p, NULL, impl))
+ if (g_atomic_pointer_compare_and_exchange (&rec_mutex->p, NULL, impl))
+ G_CLEANUP_ADD (impl, g_rec_mutex_impl_free);
+ else
g_rec_mutex_impl_free (impl);
impl = rec_mutex->p;
}
@@ -455,7 +460,9 @@ g_rw_lock_get_impl (GRWLock *lock)
if G_UNLIKELY (impl == NULL)
{
impl = g_rw_lock_impl_new ();
- if (!g_atomic_pointer_compare_and_exchange (&lock->p, NULL, impl))
+ if (g_atomic_pointer_compare_and_exchange (&lock->p, NULL, impl))
+ G_CLEANUP_ADD (impl, g_rw_lock_impl_free);
+ else
g_rw_lock_impl_free (impl);
impl = lock->p;
}
@@ -672,7 +679,9 @@ g_cond_get_impl (GCond *cond)
if G_UNLIKELY (impl == NULL)
{
impl = g_cond_impl_new ();
- if (!g_atomic_pointer_compare_and_exchange (&cond->p, NULL, impl))
+ if (g_atomic_pointer_compare_and_exchange (&cond->p, NULL, impl))
+ G_CLEANUP_ADD (impl, g_cond_impl_free);
+ else
g_cond_impl_free (impl);
impl = cond->p;
}
@@ -990,7 +999,11 @@ g_private_get_impl (GPrivate *key)
if G_UNLIKELY (impl == NULL)
{
impl = g_private_impl_new (key->notify);
- if (!g_atomic_pointer_compare_and_exchange (&key->p, NULL, impl))
+ if (g_atomic_pointer_compare_and_exchange (&key->p, NULL, impl))
+ {
+ G_CLEANUP_ADD (impl, g_private_impl_free);
+ }
+ else
{
g_private_impl_free (impl);
impl = key->p;