From 821dc1797faa903618c7585d3c053fd7ae6e93db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 8 Sep 2008 17:22:27 +0300 Subject: move autospawn lock to pulsecore/ since we don't need it in the client anymore --- src/pulse/lock-autospawn.c | 330 --------------------------------------------- src/pulse/lock-autospawn.h | 32 ----- 2 files changed, 362 deletions(-) delete mode 100644 src/pulse/lock-autospawn.c delete mode 100644 src/pulse/lock-autospawn.h (limited to 'src/pulse') 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 -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#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 - -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 -- cgit