]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/once.h
merge 'lennart' branch back into trunk.
[pulseaudio] / src / pulsecore / once.h
index 3c475a1d0af1fe5dc324698215081f79f3686357..c9fe6d0a4942a726384de853bd4c7ce9ac53118d 100644 (file)
@@ -6,6 +6,8 @@
 /***
   This file is part of PulseAudio.
 
+  Copyright 2006 Lennart Poettering
+
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2 of the
 ***/
 
 #include <pulsecore/mutex.h>
+#include <pulsecore/atomic.h>
 
 typedef struct pa_once {
-    unsigned int once_value;
-    pa_mutex *mutex;
-} pa_once_t;
+    pa_atomic_ptr_t mutex;
+    pa_atomic_t ref, done;
+} pa_once;
 
-#define PA_ONCE_INIT { .once_value = 0, .mutex = NULL }
+#define PA_ONCE_INIT                                                    \
+    {                                                                   \
+        .mutex = PA_ATOMIC_PTR_INIT(NULL),                              \
+        .ref = PA_ATOMIC_INIT(0),                                       \
+        .done = PA_ATOMIC_INIT(0)                                       \
+    }
 
-typedef void (*pa_once_func_t) (void);
+/* Not to be called directly, use the macros defined below instead */
+int pa_once_begin(pa_once *o);
+void pa_once_end(pa_once *o);
+
+#define PA_ONCE_BEGIN                                                   \
+    do {                                                                \
+        static pa_once _once = PA_ONCE_INIT;                            \
+        if (pa_once_begin(&_once)) {{
+
+#define PA_ONCE_END                                                     \
+            }                                                           \
+            pa_once_end(&_once);                                        \
+        }                                                               \
+    } while(0)
+
+/*
+
+  Usage of these macros is like this:
 
-void pa_once(pa_once_t *o, pa_once_func_t f);
+  void foo() {
+
+      PA_ONCE_BEGIN {
+
+          ... stuff to be called just once ...
+
+      } PA_ONCE_END;
+  }
+
+*/
+
+/* Same API but calls a function */
+typedef void (*pa_once_func_t) (void);
+void pa_run_once(pa_once *o, pa_once_func_t f);
 
 #endif