[pulseaudio-commits] r1820 - in /branches/lennart/src/pulsecore: once-posix.c once.h

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Fri Sep 14 14:04:08 PDT 2007


Author: lennart
Date: Fri Sep 14 23:04:08 2007
New Revision: 1820

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=1820&root=pulseaudio&view=rev
Log:
add two new macros PA_ONCE_BEGIN and PA_ONCE_END which allow usage of pa_once without declaring a function to be called

Modified:
    branches/lennart/src/pulsecore/once-posix.c
    branches/lennart/src/pulsecore/once.h

Modified: branches/lennart/src/pulsecore/once-posix.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/once-posix.c?rev=1820&root=pulseaudio&r1=1819&r2=1820&view=diff
==============================================================================
--- branches/lennart/src/pulsecore/once-posix.c (original)
+++ branches/lennart/src/pulsecore/once-posix.c Fri Sep 14 23:04:08 2007
@@ -32,18 +32,20 @@
 
 #include "once.h"
 
-/* Not reentrant -- how could it be? */
-void pa_run_once(pa_once *control, pa_once_func_t func) {
+int pa_once_begin(pa_once *control) {
     pa_mutex *m;
 
     pa_assert(control);
-    pa_assert(func);
 
     if (pa_atomic_load(&control->done))
-        return;
+        return 0;
 
     pa_atomic_inc(&control->ref);
 
+    /* Caveat: We have to make sure that the once func has completed
+     * before returning, even if the once func is not actually
+     * executed by us. Hence the awkward locking. */
+    
     for (;;) {
 
         if ((m = pa_atomic_ptr_load(&control->mutex))) {
@@ -51,33 +53,46 @@
             /* The mutex is stored in locked state, hence let's just
              * wait until it is unlocked */
             pa_mutex_lock(m);
-            pa_mutex_unlock(m);
-            break;
+
+            pa_once_end(control);
+            return 0;
         }
 
         pa_assert_se(m = pa_mutex_new(0));
         pa_mutex_lock(m);
 
-        if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) {
-            func();
-            pa_atomic_store(&control->done, 1);
-            pa_mutex_unlock(m);
-
-            break;
-        }
+        if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m))
+            return 1;
 
         pa_mutex_unlock(m);
         pa_mutex_free(m);
     }
+}
 
-    pa_assert(pa_atomic_load(&control->done));
+void pa_once_end(pa_once *control) {
+    pa_mutex *m;
+    
+    pa_assert(control);
+
+    pa_atomic_store(&control->done, 1);
+
+    pa_assert_se(m = pa_atomic_ptr_load(&control->mutex));
+    pa_mutex_unlock(m);
 
     if (pa_atomic_dec(&control->ref) <= 1) {
-        pa_assert(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL));
+        pa_assert_se(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL));
         pa_mutex_free(m);
     }
+}
 
-    /* Caveat: We have to make sure that the once func has completed
-     * before returning, even if the once func is not actually
-     * executed by us. Hence the awkward locking. */
+/* Not reentrant -- how could it be? */
+void pa_run_once(pa_once *control, pa_once_func_t func) {
+    pa_assert(control);
+    pa_assert(func);
+
+    if (pa_once_begin(control)) {
+        func();
+        pa_once_end(control);
+    }
 }
+

Modified: branches/lennart/src/pulsecore/once.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/once.h?rev=1820&root=pulseaudio&r1=1819&r2=1820&view=diff
==============================================================================
--- branches/lennart/src/pulsecore/once.h (original)
+++ branches/lennart/src/pulsecore/once.h Fri Sep 14 23:04:08 2007
@@ -39,8 +39,38 @@
         .done = PA_ATOMIC_INIT(0)                                       \
     }
 
+/* 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 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




More information about the pulseaudio-commits mailing list