X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/f44ba092651aa75055e109e04b4164ea92ae7fdc..ef5af553d6bb27d88a97f407fcf9f685f7e36e49:/src/pulse/mainloop-signal.c diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index c3cf362d..3dc74398 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -1,18 +1,19 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. - + + Copyright 2004-2008 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + 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, + 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 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 @@ -24,7 +25,6 @@ #endif #include -#include #include #include #include @@ -36,12 +36,14 @@ #include #endif -#include #include +#include +#include +#include #include #include -#include +#include #include "mainloop-signal.h" @@ -52,9 +54,9 @@ struct pa_signal_event { #else void (*saved_handler)(int sig); #endif - void (*callback) (pa_mainloop_api*a, pa_signal_event *e, int sig, void *userdata); void *userdata; - void (*destroy_callback) (pa_mainloop_api*a, pa_signal_event*e, void *userdata); + pa_signal_cb_t callback; + pa_signal_destroy_cb_t destroy_callback; pa_signal_event *previous, *next; }; @@ -64,38 +66,50 @@ static pa_io_event* io_event = NULL; static pa_signal_event *signals = NULL; static void signal_handler(int sig) { + int saved_errno; + + saved_errno = errno; + #ifndef HAVE_SIGACTION signal(sig, signal_handler); #endif - pa_write(signal_pipe[1], &sig, sizeof(sig)); + + pa_write(signal_pipe[1], &sig, sizeof(sig), NULL); + + errno = saved_errno; } static void dispatch(pa_mainloop_api*a, int sig) { - pa_signal_event*s; + pa_signal_event *s; - for (s = signals; s; s = s->next) + for (s = signals; s; s = s->next) if (s->sig == sig) { - assert(s->callback); + pa_assert(s->callback); s->callback(a, s, sig, s->userdata); break; } } -static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, PA_GCC_UNUSED void *userdata) { +static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, void *userdata) { ssize_t r; int sig; - assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]); - if ((r = pa_read(signal_pipe[0], &sig, sizeof(sig))) < 0) { + pa_assert(a); + pa_assert(e); + pa_assert(f == PA_IO_EVENT_INPUT); + pa_assert(e == io_event); + pa_assert(fd == signal_pipe[0]); + + if ((r = pa_read(signal_pipe[0], &sig, sizeof(sig), NULL)) < 0) { if (errno == EAGAIN) return; - pa_log(__FILE__": read(): %s", pa_cstrerror(errno)); + pa_log("read(): %s", pa_cstrerror(errno)); return; } - + if (r != sizeof(sig)) { - pa_log(__FILE__": short read()"); + pa_log("short read()"); return; } @@ -104,56 +118,61 @@ static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags int pa_signal_init(pa_mainloop_api *a) { - assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event); + pa_assert(a); + pa_assert(!api); + pa_assert(signal_pipe[0] == -1); + pa_assert(signal_pipe[1] == -1); + pa_assert(!io_event); if (pipe(signal_pipe) < 0) { - pa_log(__FILE__": pipe(): %s", pa_cstrerror(errno)); + pa_log("pipe(): %s", pa_cstrerror(errno)); return -1; } - pa_make_nonblock_fd(signal_pipe[0]); - pa_make_nonblock_fd(signal_pipe[1]); - pa_fd_set_cloexec(signal_pipe[0], 1); - pa_fd_set_cloexec(signal_pipe[1], 1); + pa_make_fd_nonblock(signal_pipe[0]); + pa_make_fd_nonblock(signal_pipe[1]); + pa_make_fd_cloexec(signal_pipe[0]); + pa_make_fd_cloexec(signal_pipe[1]); api = a; - io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL); - assert(io_event); + pa_assert_se(io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL)); return 0; } void pa_signal_done(void) { - assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event); - while (signals) pa_signal_free(signals); - - api->io_free(io_event); - io_event = NULL; - close(signal_pipe[0]); - close(signal_pipe[1]); - signal_pipe[0] = signal_pipe[1] = -1; + if (io_event) { + pa_assert(api); + api->io_free(io_event); + io_event = NULL; + } + + pa_close_pipe(signal_pipe); api = NULL; } -pa_signal_event* pa_signal_new(int sig, void (*_callback) (pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata), void *userdata) { +pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t _callback, void *userdata) { pa_signal_event *e = NULL; #ifdef HAVE_SIGACTION struct sigaction sa; #endif - assert(sig > 0 && _callback); - + pa_assert(sig > 0); + pa_assert(_callback); + + pa_init_i18n(); + for (e = signals; e; e = e->next) if (e->sig == sig) - goto fail; - - e = pa_xmalloc(sizeof(pa_signal_event)); + return NULL; + + e = pa_xnew(pa_signal_event, 1); e->sig = sig; e->callback = _callback; e->userdata = userdata; @@ -164,7 +183,7 @@ pa_signal_event* pa_signal_new(int sig, void (*_callback) (pa_mainloop_api *api, sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; - + if (sigaction(sig, &sa, &e->saved_sigaction) < 0) #else if ((e->saved_handler = signal(sig, signal_handler)) == SIG_ERR) @@ -177,13 +196,12 @@ pa_signal_event* pa_signal_new(int sig, void (*_callback) (pa_mainloop_api *api, return e; fail: - if (e) - pa_xfree(e); + pa_xfree(e); return NULL; } void pa_signal_free(pa_signal_event *e) { - assert(e); + pa_assert(e); if (e->next) e->next->previous = e->previous; @@ -193,18 +211,19 @@ void pa_signal_free(pa_signal_event *e) { signals = e->next; #ifdef HAVE_SIGACTION - sigaction(e->sig, &e->saved_sigaction, NULL); + pa_assert_se(sigaction(e->sig, &e->saved_sigaction, NULL) == 0); #else - signal(e->sig, e->saved_handler); + pa_assert_se(signal(e->sig, e->saved_handler) == signal_handler); #endif if (e->destroy_callback) e->destroy_callback(api, e, e->userdata); - + pa_xfree(e); } -void pa_signal_set_destroy(pa_signal_event *e, void (*_callback) (pa_mainloop_api *api, pa_signal_event*e, void *userdata)) { - assert(e); +void pa_signal_set_destroy(pa_signal_event *e, pa_signal_destroy_cb_t _callback) { + pa_assert(e); + e->destroy_callback = _callback; }