[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