Add new functions
[platform/upstream/glib.git] / glib / gthread.h
index 3452af4..2d0170e 100644 (file)
@@ -27,8 +27,9 @@
 #ifndef __G_THREAD_H__
 #define __G_THREAD_H__
 
-#include <gerror.h>
-#include <gtypes.h>
+#include <glib/gerror.h>
+#include <glib/gtypes.h>
+#include <glib/gatomic.h>  /* for g_atomic_pointer_get */
 
 G_BEGIN_DECLS
 
@@ -43,7 +44,7 @@ typedef enum
   G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
 } GThreadError;
 
-typedef void            (*GThreadFunc)          (gpointer       value);
+typedef gpointer (*GThreadFunc) (gpointer data);
 
 typedef enum
 {
@@ -56,9 +57,11 @@ typedef enum
 typedef struct _GThread         GThread;
 struct  _GThread
 {
-  GThreadPriority priority;
-  gboolean bound;
+  /*< private >*/
+  GThreadFunc func;
+  gpointer data;
   gboolean joinable;
+  GThreadPriority priority;
 };
 
 typedef struct _GMutex          GMutex;
@@ -87,8 +90,8 @@ struct _GThreadFunctions
   gpointer  (*private_get)        (GPrivate             *private_key);
   void      (*private_set)        (GPrivate             *private_key,
                                    gpointer              data);
-  void      (*thread_create)      (GThreadFunc           thread_func,
-                                   gpointer              arg,
+  void      (*thread_create)      (GThreadFunc           func,
+                                   gpointer              data,
                                    gulong                stack_size,
                                    gboolean              joinable,
                                    gboolean              bound,
@@ -101,6 +104,8 @@ struct _GThreadFunctions
   void      (*thread_set_priority)(gpointer              thread,
                                    GThreadPriority       priority);
   void      (*thread_self)        (gpointer              thread);
+  gboolean  (*thread_equal)       (gpointer              thread1,
+                                  gpointer              thread2);
 };
 
 GLIB_VAR GThreadFunctions       g_thread_functions_for_glib_use;
@@ -132,6 +137,10 @@ void    g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
 /* internal function for fallback static mutex implementation */
 GMutex* g_static_mutex_get_mutex_impl   (GMutex **mutex);
 
+#define g_static_mutex_get_mutex_impl_shortcut(mutex) \
+  (g_atomic_pointer_get (mutex) ? *(mutex) : \
+   g_static_mutex_get_mutex_impl (mutex))
+
 /* shorthands for conditional and unconditional function calls */
 
 #define G_THREAD_UF(op, arglist)                                       \
@@ -191,19 +200,24 @@ GMutex* g_static_mutex_get_mutex_impl   (GMutex **mutex);
                                                         (GPrivate*) (value)), \
                                                        (private_key, value))
 #define g_thread_yield()              G_THREAD_CF (thread_yield, (void)0, ())
-#define g_thread_exit()               G_THREAD_CF (thread_exit, (void)0, ())
-
-GThread* g_thread_create (GThreadFunc            thread_func,
-                          gpointer               arg,
-                          gulong                 stack_size,
-                          gboolean               joinable,
-                          gboolean               bound,
-                          GThreadPriority        priority,
-                          GError               **error);
-GThread* g_thread_self (void);
-void g_thread_join (GThread *thread);
-void g_thread_set_priority (GThread         *thread,
-                            GThreadPriority  priority);
+
+#define g_thread_create(func, data, joinable, error)                   \
+  (g_thread_create_full (func, data, 0, joinable, FALSE,               \
+                         G_THREAD_PRIORITY_NORMAL, error))
+
+GThread* g_thread_create_full  (GThreadFunc            func,
+                                gpointer               data,
+                                gulong                 stack_size,
+                                gboolean               joinable,
+                                gboolean               bound,
+                                GThreadPriority        priority,
+                                GError               **error);
+GThread* g_thread_self         (void);
+void     g_thread_exit         (gpointer               retval);
+gpointer g_thread_join         (GThread               *thread);
+
+void     g_thread_set_priority (GThread               *thread,
+                                GThreadPriority        priority);
 
 /* GStaticMutexes can be statically initialized with the value
  * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
@@ -221,6 +235,7 @@ void g_static_mutex_free (GStaticMutex *mutex);
 
 struct _GStaticPrivate
 {
+  /*< private >*/
   guint index;
 };
 #define G_STATIC_PRIVATE_INIT { 0 }
@@ -229,19 +244,14 @@ gpointer g_static_private_get            (GStaticPrivate   *private_key);
 void     g_static_private_set            (GStaticPrivate   *private_key,
                                          gpointer          data,
                                          GDestroyNotify    notify);
-gpointer g_static_private_get_for_thread (GStaticPrivate   *private_key,
-                                          GThread          *thread);
-void     g_static_private_set_for_thread (GStaticPrivate   *private_key,
-                                         GThread          *thread,
-                                         gpointer          data,
-                                         GDestroyNotify    notify);
 void     g_static_private_free           (GStaticPrivate   *private_key);
 
 typedef struct _GStaticRecMutex GStaticRecMutex;
 struct _GStaticRecMutex
 {
+  /*< private >*/
   GStaticMutex mutex;
-  unsigned int depth;
+  guint depth;
   GSystemThread owner;
 };
 
@@ -258,15 +268,17 @@ void     g_static_rec_mutex_free        (GStaticRecMutex *mutex);
 typedef struct _GStaticRWLock GStaticRWLock;
 struct _GStaticRWLock
 {
+  /*< private >*/
   GStaticMutex mutex;
   GCond *read_cond;
   GCond *write_cond;
   guint read_counter;
-  gboolean write;
+  gboolean have_writer;
+  guint want_to_read;
   guint want_to_write;
 };
 
-#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, FALSE }
+#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 }
 
 void      g_static_rw_lock_init           (GStaticRWLock* lock);
 void      g_static_rw_lock_reader_lock    (GStaticRWLock* lock);
@@ -277,6 +289,36 @@ gboolean  g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
 void      g_static_rw_lock_writer_unlock  (GStaticRWLock* lock);
 void      g_static_rw_lock_free           (GStaticRWLock* lock);
 
+void     g_thread_foreach                (GFunc          thread_func,
+                                          gpointer       user_data);
+
+typedef enum
+{
+  G_ONCE_STATUS_NOTCALLED,
+  G_ONCE_STATUS_PROGRESS,
+  G_ONCE_STATUS_READY  
+} GOnceStatus;
+
+typedef struct _GOnce GOnce;
+struct _GOnce
+{
+  volatile GOnceStatus status;
+  volatile gpointer retval;
+};
+
+#define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL }
+
+gpointer g_once_impl (GOnce *once, GThreadFunc func, gpointer arg);
+
+#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+# define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
+#else /* !G_ATOMIC_OP_MEMORY_BARRIER_NEEDED*/
+# define g_once(once, func, arg) \
+  (((once)->status == G_ONCE_STATUS_READY) ? \
+   (once)->retval : \
+   g_once_impl ((once), (func), (arg)))
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+    
 /* these are some convenience macros that expand to nothing if GLib
  * was configured with --disable-threads. for using StaticMutexes,
  * you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name)
@@ -328,6 +370,7 @@ extern void glib_dummy_decl (void);
 #  define G_TRYLOCK(name)               (TRUE)
 #endif  /* !G_THREADS_ENABLED */
 
+
 G_END_DECLS
 
 #endif /* __G_THREAD_H__ */