summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/once-posix.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-09-14 21:04:08 +0000
committerLennart Poettering <lennart@poettering.net>2007-09-14 21:04:08 +0000
commitbf274cb617d92e55d18fa7e2f6b1cf139b96a413 (patch)
treef09697980f85c24de1bc3d0148d773f97592a43a /src/pulsecore/once-posix.c
parent04ed0f9536f8b211d68d7df381f0fb4dd04dc0ff (diff)
add two new macros PA_ONCE_BEGIN and PA_ONCE_END which allow usage of pa_once without declaring a function to be called
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1820 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/pulsecore/once-posix.c')
-rw-r--r--src/pulsecore/once-posix.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c
index fd6288fe..fba0ddf1 100644
--- a/src/pulsecore/once-posix.c
+++ b/src/pulsecore/once-posix.c
@@ -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 @@ void pa_run_once(pa_once *control, pa_once_func_t func) {
/* 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);
}
+}
+
+void pa_once_end(pa_once *control) {
+ pa_mutex *m;
+
+ pa_assert(control);
- pa_assert(pa_atomic_load(&control->done));
+ 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);
+ }
}
+