summaryrefslogtreecommitdiffstats
path: root/src/pulse
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-09-08 17:22:27 +0300
committerLennart Poettering <lennart@poettering.net>2008-09-08 17:22:27 +0300
commit821dc1797faa903618c7585d3c053fd7ae6e93db (patch)
tree7bf2d978d04440fccb17a59fd0a42a1bb2379112 /src/pulse
parentf2164023fd0fda8c1a456c5c2f144f8943c24db9 (diff)
move autospawn lock to pulsecore/ since we don't need it in the client anymore
Diffstat (limited to 'src/pulse')
-rw-r--r--src/pulse/lock-autospawn.c330
-rw-r--r--src/pulse/lock-autospawn.h32
2 files changed, 0 insertions, 362 deletions
diff --git a/src/pulse/lock-autospawn.c b/src/pulse/lock-autospawn.c
deleted file mode 100644
index d36b669e..00000000
--- a/src/pulse/lock-autospawn.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/***
- This file is part of PulseAudio.
-
- Copyright 2008 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 License,
- or (at your option) any later version.
-
- PulseAudio is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with PulseAudio; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <signal.h>
-#include <pthread.h>
-
-#include <pulse/i18n.h>
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/mutex.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/core-util.h>
-
-#include "lock-autospawn.h"
-
-/* So, why do we have this complex code here with threads and pipes
- * and stuff? For two reasons: POSIX file locks are per-process, not
- * per-file descriptor. That means that two contexts within the same
- * process that try to create the autospawn lock might end up assuming
- * they both managed to lock the file. And then, POSIX locking
- * operations are synchronous. If two contexts run from the same event
- * loop it must be made sure that they do not block each other, but
- * that the locking operation can happen asynchronously. */
-
-#define AUTOSPAWN_LOCK "autospawn.lock"
-
-static pa_mutex *mutex;
-
-static unsigned n_ref = 0;
-static int lock_fd = -1;
-static pa_mutex *lock_fd_mutex = NULL;
-static pa_bool_t taken = FALSE;
-static pa_thread *thread;
-static int pipe_fd[2] = { -1, -1 };
-
-static void destroy_mutex(void) PA_GCC_DESTRUCTOR;
-
-static int ref(void) {
-
- if (n_ref > 0) {
-
- pa_assert(pipe_fd[0] >= 0);
- pa_assert(pipe_fd[1] >= 0);
-
- n_ref++;
-
- return 0;
- }
-
- pa_assert(lock_fd < 0);
- pa_assert(!lock_fd_mutex);
- pa_assert(!taken);
- pa_assert(!thread);
- pa_assert(pipe_fd[0] < 0);
- pa_assert(pipe_fd[1] < 0);
-
- if (pipe(pipe_fd) < 0)
- return -1;
-
- lock_fd_mutex = pa_mutex_new(FALSE, FALSE);
-
- pa_make_fd_cloexec(pipe_fd[0]);
- pa_make_fd_cloexec(pipe_fd[1]);
-
- pa_make_fd_nonblock(pipe_fd[1]);
- pa_make_fd_nonblock(pipe_fd[0]);
-
- n_ref = 1;
- return 0;
-}
-
-static void unref(pa_bool_t after_fork) {
-
- pa_assert(n_ref > 0);
- pa_assert(pipe_fd[0] >= 0);
- pa_assert(pipe_fd[1] >= 0);
- pa_assert(lock_fd_mutex);
-
- n_ref--;
-
- if (n_ref > 0)
- return;
-
- pa_assert(!taken);
-
- if (thread) {
- pa_thread_free(thread);
- thread = NULL;
- }
-
- pa_mutex_lock(lock_fd_mutex);
- if (lock_fd >= 0) {
-
- if (after_fork)
- pa_close(lock_fd);
- else {
- char *lf;
-
- if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
- pa_log_warn(_("Cannot access autospawn lock."));
-
- pa_unlock_lockfile(lf, lock_fd);
- pa_xfree(lf);
-
- lock_fd = -1;
- }
- }
- pa_mutex_unlock(lock_fd_mutex);
-
- pa_mutex_free(lock_fd_mutex);
- lock_fd_mutex = NULL;
-
- pa_close(pipe_fd[0]);
- pa_close(pipe_fd[1]);
- pipe_fd[0] = pipe_fd[1] = -1;
-}
-
-static void ping(void) {
- ssize_t s;
-
- pa_assert(pipe_fd[1] >= 0);
-
- for (;;) {
- char x = 'x';
-
- if ((s = write(pipe_fd[1], &x, 1)) == 1)
- break;
-
- pa_assert(s < 0);
-
- if (errno == EAGAIN)
- break;
-
- pa_assert(errno == EINTR);
- }
-}
-
-static void wait_for_ping(void) {
- ssize_t s;
- char x;
- struct pollfd pfd;
- int k;
-
- pa_assert(pipe_fd[0] >= 0);
-
- memset(&pfd, 0, sizeof(pfd));
- pfd.fd = pipe_fd[0];
- pfd.events = POLLIN;
-
- if ((k = poll(&pfd, 1, -1)) != 1) {
- pa_assert(k < 0);
- pa_assert(errno == EINTR);
- } else if ((s = read(pipe_fd[0], &x, 1)) != 1) {
- pa_assert(s < 0);
- pa_assert(errno == EAGAIN);
- }
-}
-
-static void empty_pipe(void) {
- char x[16];
- ssize_t s;
-
- pa_assert(pipe_fd[0] >= 0);
-
- if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) {
- pa_assert(s < 0);
- pa_assert(errno == EAGAIN);
- }
-}
-
-static void thread_func(void *u) {
- int fd;
- char *lf;
- sigset_t fullset;
-
- /* No signals in this thread please */
- sigfillset(&fullset);
- pthread_sigmask(SIG_BLOCK, &fullset, NULL);
-
- if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
- pa_log_warn(_("Cannot access autospawn lock."));
- goto finish;
- }
-
- if ((fd = pa_lock_lockfile(lf)) < 0)
- goto finish;
-
- pa_mutex_lock(lock_fd_mutex);
- pa_assert(lock_fd < 0);
- lock_fd = fd;
- pa_mutex_unlock(lock_fd_mutex);
-
-finish:
- pa_xfree(lf);
-
- ping();
-}
-
-static int start_thread(void) {
-
- if (!thread)
- if (!(thread = pa_thread_new(thread_func, NULL)))
- return -1;
-
- return 0;
-}
-
-static void create_mutex(void) {
- PA_ONCE_BEGIN {
- mutex = pa_mutex_new(FALSE, FALSE);
- } PA_ONCE_END;
-}
-
-static void destroy_mutex(void) {
-
- if (mutex)
- pa_mutex_free(mutex);
-}
-
-
-int pa_autospawn_lock_init(void) {
- int ret = -1;
-
- create_mutex();
- pa_mutex_lock(mutex);
-
- if (ref() < 0)
- ret = -1;
- else
- ret = pipe_fd[0];
-
- pa_mutex_unlock(mutex);
-
- return ret;
-}
-
-int pa_autospawn_lock_acquire(pa_bool_t block) {
- int ret = -1;
-
- create_mutex();
- pa_mutex_lock(mutex);
- pa_assert(n_ref >= 1);
-
- pa_mutex_lock(lock_fd_mutex);
-
- for (;;) {
-
- empty_pipe();
-
- if (lock_fd >= 0 && !taken) {
- taken = TRUE;
- ret = 1;
- break;
- }
-
- if (lock_fd < 0)
- if (start_thread() < 0)
- break;
-
- if (!block) {
- ret = 0;
- break;
- }
-
- pa_mutex_unlock(lock_fd_mutex);
- pa_mutex_unlock(mutex);
-
- wait_for_ping();
-
- pa_mutex_lock(mutex);
- pa_mutex_lock(lock_fd_mutex);
- }
-
- pa_mutex_unlock(lock_fd_mutex);
-
- pa_mutex_unlock(mutex);
-
- return ret;
-}
-
-void pa_autospawn_lock_release(void) {
-
- create_mutex();
- pa_mutex_lock(mutex);
- pa_assert(n_ref >= 1);
-
- pa_assert(taken);
- taken = FALSE;
-
- ping();
-
- pa_mutex_unlock(mutex);
-}
-
-void pa_autospawn_lock_done(pa_bool_t after_fork) {
-
- create_mutex();
- pa_mutex_lock(mutex);
- pa_assert(n_ref >= 1);
-
- unref(after_fork);
-
- pa_mutex_unlock(mutex);
-}
diff --git a/src/pulse/lock-autospawn.h b/src/pulse/lock-autospawn.h
deleted file mode 100644
index c04c4bd1..00000000
--- a/src/pulse/lock-autospawn.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef foopulselockautospawnhfoo
-#define foopulselockautospawnhfoo
-
-/***
- This file is part of PulseAudio.
-
- Copyright 2008 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.1 of the
- License, or (at your option) any later version.
-
- PulseAudio is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with PulseAudio; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- USA.
-***/
-
-#include <pulsecore/macro.h>
-
-int pa_autospawn_lock_init(void);
-int pa_autospawn_lock_acquire(pa_bool_t block);
-void pa_autospawn_lock_release(void);
-void pa_autospawn_lock_done(pa_bool_t after_fork);
-
-#endif