drop g_thread_new_full()
[platform/upstream/glib.git] / glib / deprecated / gthread-deprecated.c
index 861a599..c6aa3ef 100644 (file)
 
 #include "config.h"
 
-#include "gmacros.h"
-
 /* we know we are deprecated here, no need for warnings */
-#undef G_GNUC_DEPRECATED
-#define G_GNUC_DEPRECATED
-#undef G_GNUC_DEPRECATED_FOR
-#define G_GNUC_DEPRECATED_FOR(f)
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
 
 #include "gmessages.h"
 #include "gslice.h"
@@ -153,8 +148,6 @@ guint64 (*g_thread_gettime) (void) = gettime;
 
 /* Initialisation {{{1 ---------------------------------------------------- */
 gboolean         g_threads_got_initialized = TRUE;
-GSystemThread    zero_thread; /* This is initialized to all zero */
-
 
 /**
  * g_thread_init:
@@ -202,10 +195,11 @@ void g_thread_init_glib (void) { }
 
 /* Internal variables {{{1 */
 
-static GRealThread *g_thread_all_threads = NULL;
+static GSList      *g_thread_all_threads = NULL;
 static GSList      *g_thread_free_indices = NULL;
 
 /* Protects g_thread_all_threads and g_thread_free_indices */
+G_LOCK_DEFINE_STATIC (g_static_mutex);
 G_LOCK_DEFINE_STATIC (g_thread);
 
 /* Misc. GThread functions {{{1 */
@@ -226,66 +220,6 @@ g_thread_set_priority (GThread         *thread,
 }
 
 /**
- * g_thread_create:
- * @func: a function to execute in the new thread
- * @data: an argument to supply to the new thread
- * @joinable: should this thread be joinable?
- * @error: return location for error, or %NULL
- *
- * This function creates a new thread.
- *
- * If @joinable is %TRUE, you can wait for this threads termination
- * calling g_thread_join(). Otherwise the thread will just disappear
- * when it terminates.
- *
- * The new thread executes the function @func with the argument @data.
- * If the thread was created successfully, it is returned.
- *
- * @error can be %NULL to ignore errors, or non-%NULL to report errors.
- * The error is set, if and only if the function returns %NULL.
- *
- * Returns: the new #GThread on success
- *
- * Deprecated:2.32: Use g_thread_new() instead
- */
-GThread *
-g_thread_create (GThreadFunc   func,
-                 gpointer      data,
-                 gboolean      joinable,
-                 GError      **error)
-{
-  return g_thread_new_internal (NULL, func, data, joinable, 0, TRUE, error);
-}
-
-/**
- * g_thread_create_full:
- * @func: a function to execute in the new thread.
- * @data: an argument to supply to the new thread.
- * @stack_size: a stack size for the new thread.
- * @joinable: should this thread be joinable?
- * @bound: ignored
- * @priority: ignored
- * @error: return location for error.
- * @Returns: the new #GThread on success.
- *
- * This function creates a new thread.
- *
- * Deprecated:2.32: The @bound and @priority arguments are now ignored.
- * Use g_thread_new() or g_thread_new_full() instead.
- */
-GThread *
-g_thread_create_full (GThreadFunc       func,
-                      gpointer          data,
-                      gulong            stack_size,
-                      gboolean          joinable,
-                      gboolean          bound,
-                      GThreadPriority   priority,
-                      GError          **error)
-{
-  return g_thread_new_internal (NULL, func, data, joinable, stack_size, TRUE, error);
-}
-
-/**
  * g_thread_foreach:
  * @thread_func: function to call for all #GThread structures
  * @user_data: second argument to @thread_func
@@ -317,8 +251,7 @@ g_thread_foreach (GFunc    thread_func,
   g_return_if_fail (thread_func != NULL);
   /* snapshot the list of threads for iteration */
   G_LOCK (g_thread);
-  for (thread = g_thread_all_threads; thread; thread = thread->next)
-    slist = g_slist_prepend (slist, thread);
+  slist = g_slist_copy (g_thread_all_threads);
   G_UNLOCK (g_thread);
   /* walk the list, skipping non-existent threads */
   while (slist)
@@ -327,9 +260,10 @@ g_thread_foreach (GFunc    thread_func,
       slist = node->next;
       /* check whether the current thread still exists */
       G_LOCK (g_thread);
-      for (thread = g_thread_all_threads; thread; thread = thread->next)
-        if (thread == node->data)
-          break;
+      if (g_slist_find (g_thread_all_threads, node->data))
+        thread = node->data;
+      else
+        thread = NULL;
       G_UNLOCK (g_thread);
       if (thread)
         thread_func (thread, user_data);
@@ -337,33 +271,108 @@ g_thread_foreach (GFunc    thread_func,
     }
 }
 
-void
+static void
+g_enumerable_thread_remove (gpointer data)
+{
+  GRealThread *thread = data;
+
+  G_LOCK (g_thread);
+  g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
+  G_UNLOCK (g_thread);
+}
+
+GPrivate enumerable_thread_private = G_PRIVATE_INIT (g_enumerable_thread_remove);
+
+static void
 g_enumerable_thread_add (GRealThread *thread)
 {
   G_LOCK (g_thread);
-  thread->next = g_thread_all_threads;
-  g_thread_all_threads = thread;
+  g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread);
   G_UNLOCK (g_thread);
+
+  g_private_set (&enumerable_thread_private, thread);
 }
 
-void
-g_enumerable_thread_remove (GRealThread *thread)
+static gpointer
+g_deprecated_thread_proxy (gpointer data)
 {
-  GRealThread *t, *p;
+  GRealThread *real = data;
 
-  G_LOCK (g_thread);
-  for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
+  g_enumerable_thread_add (real);
+
+  return g_thread_proxy (data);
+}
+
+/**
+ * g_thread_create:
+ * @func: a function to execute in the new thread
+ * @data: an argument to supply to the new thread
+ * @joinable: should this thread be joinable?
+ * @error: return location for error, or %NULL
+ *
+ * This function creates a new thread.
+ *
+ * The new thread executes the function @func with the argument @data.
+ * If the thread was created successfully, it is returned.
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report errors.
+ * The error is set, if and only if the function returns %NULL.
+ *
+ * This function returns a reference to the created thread only if
+ * @joinable is %TRUE.  In that case, you must free this reference by
+ * calling g_thread_unref() or g_thread_join().  If @joinable is %FALSE
+ * then you should probably not touch the return value.
+ *
+ * Returns: the new #GThread on success
+ *
+ * Deprecated:2.32: Use g_thread_new() instead
+ */
+GThread *
+g_thread_create (GThreadFunc   func,
+                 gpointer      data,
+                 gboolean      joinable,
+                 GError      **error)
+{
+  return g_thread_create_full (func, data, 0, joinable, 0, 0, error);
+}
+
+/**
+ * g_thread_create_full:
+ * @func: a function to execute in the new thread.
+ * @data: an argument to supply to the new thread.
+ * @stack_size: a stack size for the new thread.
+ * @joinable: should this thread be joinable?
+ * @bound: ignored
+ * @priority: ignored
+ * @error: return location for error.
+ * @Returns: the new #GThread on success.
+ *
+ * This function creates a new thread.
+ *
+ * Deprecated:2.32: The @bound and @priority arguments are now ignored.
+ * Use g_thread_new().
+ */
+GThread *
+g_thread_create_full (GThreadFunc       func,
+                      gpointer          data,
+                      gulong            stack_size,
+                      gboolean          joinable,
+                      gboolean          bound,
+                      GThreadPriority   priority,
+                      GError          **error)
+{
+  GThread *thread;
+
+  thread = g_thread_new_internal (NULL, g_deprecated_thread_proxy,
+                                  func, data, stack_size, error);
+
+  if (!joinable)
     {
-      if (t == thread)
-        {
-          if (p)
-            p->next = t->next;
-          else
-            g_thread_all_threads = t->next;
-          break;
-        }
+      thread->joinable = FALSE;
+      g_thread_unref (thread);
     }
-  G_UNLOCK (g_thread);
+
+  return thread;
 }
 
 /* GOnce {{{1 ------------------------------------------------------------- */
@@ -506,7 +515,7 @@ g_static_mutex_get_mutex_impl (GStaticMutex* mutex)
 
   if (!result)
     {
-      g_mutex_lock (&g_once_mutex);
+      G_LOCK (g_static_mutex);
 
       result = mutex->mutex;
       if (!result)
@@ -515,7 +524,7 @@ g_static_mutex_get_mutex_impl (GStaticMutex* mutex)
           g_atomic_pointer_set (&mutex->mutex, result);
         }
 
-      g_mutex_unlock (&g_once_mutex);
+      G_UNLOCK (g_static_mutex);
     }
 
   return result;
@@ -650,6 +659,34 @@ g_static_rec_mutex_init (GStaticRecMutex *mutex)
   *mutex = init_mutex;
 }
 
+static GRecMutex *
+g_static_rec_mutex_get_rec_mutex_impl (GStaticRecMutex* mutex)
+{
+  GRecMutex *result;
+
+  if (!g_thread_supported ())
+    return NULL;
+
+  result = g_atomic_pointer_get (&mutex->mutex.mutex);
+
+  if (!result)
+    {
+      G_LOCK (g_static_mutex);
+
+      result = (GRecMutex *) mutex->mutex.mutex;
+      if (!result)
+        {
+          result = g_slice_new (GRecMutex);
+          g_rec_mutex_init (result);
+          g_atomic_pointer_set (&mutex->mutex.mutex, result);
+        }
+
+      G_UNLOCK (g_static_mutex);
+    }
+
+  return result;
+}
+
 /**
  * g_static_rec_mutex_lock:
  * @mutex: a #GStaticRecMutex to lock.
@@ -664,23 +701,10 @@ g_static_rec_mutex_init (GStaticRecMutex *mutex)
 void
 g_static_rec_mutex_lock (GStaticRecMutex* mutex)
 {
-  GSystemThread self;
-
-  g_return_if_fail (mutex);
-
-  if (!g_thread_supported ())
-    return;
-
-  g_system_thread_self (&self);
-
-  if (g_system_thread_equal (&self, &mutex->owner))
-    {
-      mutex->depth++;
-      return;
-    }
-  g_static_mutex_lock (&mutex->mutex);
-  g_system_thread_assign (mutex->owner, self);
-  mutex->depth = 1;
+  GRecMutex *rm;
+  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
+  g_rec_mutex_lock (rm);
+  mutex->depth++;
 }
 
 /**
@@ -699,27 +723,16 @@ g_static_rec_mutex_lock (GStaticRecMutex* mutex)
 gboolean
 g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
 {
-  GSystemThread self;
+  GRecMutex *rm;
+  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
 
-  g_return_val_if_fail (mutex, FALSE);
-
-  if (!g_thread_supported ())
-    return TRUE;
-
-  g_system_thread_self (&self);
-
-  if (g_system_thread_equal (&self, &mutex->owner))
+  if (g_rec_mutex_trylock (rm))
     {
       mutex->depth++;
       return TRUE;
     }
-
-  if (!g_static_mutex_trylock (&mutex->mutex))
+  else
     return FALSE;
-
-  g_system_thread_assign (mutex->owner, self);
-  mutex->depth = 1;
-  return TRUE;
 }
 
 /**
@@ -737,18 +750,10 @@ g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
 void
 g_static_rec_mutex_unlock (GStaticRecMutex* mutex)
 {
-  g_return_if_fail (mutex);
-
-  if (!g_thread_supported ())
-    return;
-
-  if (mutex->depth > 1)
-    {
-      mutex->depth--;
-      return;
-    }
-  g_system_thread_assign (mutex->owner, zero_thread);
-  g_static_mutex_unlock (&mutex->mutex);
+  GRecMutex *rm;
+  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
+  mutex->depth--;
+  g_rec_mutex_unlock (rm);
 }
 
 /**
@@ -765,25 +770,14 @@ void
 g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
                               guint            depth)
 {
-  GSystemThread self;
-  g_return_if_fail (mutex);
-
-  if (!g_thread_supported ())
-    return;
-
-  if (depth == 0)
-    return;
+  GRecMutex *rm;
 
-  g_system_thread_self (&self);
-
-  if (g_system_thread_equal (&self, &mutex->owner))
+  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
+  while (depth--)
     {
-      mutex->depth += depth;
-      return;
+      g_rec_mutex_lock (rm);
+      mutex->depth++;
     }
-  g_static_mutex_lock (&mutex->mutex);
-  g_system_thread_assign (mutex->owner, self);
-  mutex->depth = depth;
 }
 
 /**
@@ -805,18 +799,13 @@ g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
 guint
 g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
 {
-  guint depth;
-
-  g_return_val_if_fail (mutex, 0);
-
-  if (!g_thread_supported ())
-    return 1;
+  GRecMutex *rm;
+  gint depth;
 
+  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
   depth = mutex->depth;
-
-  g_system_thread_assign (mutex->owner, zero_thread);
-  mutex->depth = 0;
-  g_static_mutex_unlock (&mutex->mutex);
+  while (mutex->depth--)
+    g_rec_mutex_unlock (rm);
 
   return depth;
 }
@@ -839,7 +828,13 @@ g_static_rec_mutex_free (GStaticRecMutex *mutex)
 {
   g_return_if_fail (mutex);
 
-  g_static_mutex_free (&mutex->mutex);
+  if (mutex->mutex.mutex)
+    {
+      GRecMutex *rm = (GRecMutex *) mutex->mutex.mutex;
+
+      g_rec_mutex_clear (rm);
+      g_slice_free (GRecMutex, rm);
+    }
 }
 
 /* GStaticRWLock {{{1 ----------------------------------------------------- */
@@ -1226,6 +1221,24 @@ struct _GStaticPrivateNode
   GStaticPrivate *owner;
 };
 
+static void
+g_static_private_cleanup (gpointer data)
+{
+  GArray *array = data;
+  guint i;
+
+  for (i = 0; i < array->len; i++ )
+    {
+      GStaticPrivateNode *node = &g_array_index (array, GStaticPrivateNode, i);
+      if (node->destroy)
+        node->destroy (node->data);
+    }
+
+  g_array_free (array, TRUE);
+}
+
+GPrivate static_private_private = G_PRIVATE_INIT (g_static_private_cleanup);
+
 /**
  * GStaticPrivate:
  *
@@ -1297,10 +1310,10 @@ g_static_private_init (GStaticPrivate *private_key)
 gpointer
 g_static_private_get (GStaticPrivate *private_key)
 {
-  GRealThread *self = (GRealThread*) g_thread_self ();
   GArray *array;
   gpointer ret = NULL;
-  array = self->private_data;
+
+  array = g_private_get (&static_private_private);
 
   if (array && private_key->index != 0 && private_key->index <= array->len)
     {
@@ -1352,7 +1365,6 @@ g_static_private_set (GStaticPrivate *private_key,
                       gpointer        data,
                       GDestroyNotify  notify)
 {
-  GRealThread *self = (GRealThread*) g_thread_self ();
   GArray *array;
   static guint next_index = 0;
   GStaticPrivateNode *node;
@@ -1376,11 +1388,11 @@ g_static_private_set (GStaticPrivate *private_key,
       G_UNLOCK (g_thread);
     }
 
-  array = self->private_data;
+  array = g_private_get (&static_private_private);
   if (!array)
     {
       array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode));
-      self->private_data = array;
+      g_private_set (&static_private_private, array);
     }
   if (private_key->index > array->len)
     g_array_set_size (array, private_key->index);
@@ -1426,28 +1438,6 @@ g_static_private_free (GStaticPrivate *private_key)
   G_UNLOCK (g_thread);
 }
 
-void
-g_static_private_cleanup (GRealThread *thread)
-{
-  GArray *array;
-
-  array = thread->private_data;
-  thread->private_data = NULL;
-
-  if (array)
-    {
-      guint i;
-
-      for (i = 0; i < array->len; i++ )
-        {
-          GStaticPrivateNode *node = &g_array_index (array, GStaticPrivateNode, i);
-          if (node->destroy)
-            node->destroy (node->data);
-        }
-      g_array_free (array, TRUE);
-    }
-}
-
 /* GMutex {{{1 ------------------------------------------------------ */
 
 /**