On 04/17/2013 05:56 PM, David Henningsson wrote: > XDG_RUNTIME_DIR is deleted on logout (according to xdg spec), and > that's where we keep our pid file and native protocol socket. > > When these two files are deleted, it makes no sense to run anymore, > so quit. Hanging around is not only sloppy, but can also be harmful: > e g, if esd compat module is loaded, it will bind to the esd address. > When a new pulseaudio process is created on next login of the same > user, pulseaudio cannot start because the esd address is occupied. > > Buglink: https://bugs.launchpad.net/bugs/1167192 > Signed-off-by: David Henningsson <david.henningsson at canonical.com> > --- > > This patch is probably unfinished, because I don't know how to deal with this > on win32 systems etc. I had to come up with a quick fix for Ubuntu 13.04, and > this is what I came up with. I'm attaching second version of the patch. The below version could cause PA getting stuck in 100% CPU loop due to the event never being read out. > > src/Makefile.am | 1 + > src/daemon/main.c | 20 ++++++++- > src/pulsecore/inotify-wrapper.c | 93 +++++++++++++++++++++++++++++++++++++++ > src/pulsecore/inotify-wrapper.h | 13 ++++++ > src/pulsecore/pid.c | 5 +++ > src/pulsecore/pid.h | 1 + > 6 files changed, 131 insertions(+), 2 deletions(-) > create mode 100644 src/pulsecore/inotify-wrapper.c > create mode 100644 src/pulsecore/inotify-wrapper.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index a621a30..b8fb4b0 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -865,6 +865,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES = \ > pulsecore/core.c pulsecore/core.h \ > pulsecore/fdsem.c pulsecore/fdsem.h \ > pulsecore/hook-list.c pulsecore/hook-list.h \ > + pulsecore/inotify-wrapper.c pulsecore/inotify-wrapper.h \ > pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \ > pulsecore/modargs.c pulsecore/modargs.h \ > pulsecore/modinfo.c pulsecore/modinfo.h \ > diff --git a/src/daemon/main.c b/src/daemon/main.c > index c18524f..3016538 100644 > --- a/src/daemon/main.c > +++ b/src/daemon/main.c > @@ -74,6 +74,7 @@ > #include <pulsecore/core-rtclock.h> > #include <pulsecore/core-scache.h> > #include <pulsecore/core.h> > +#include <pulsecore/inotify-wrapper.h> > #include <pulsecore/module.h> > #include <pulsecore/cli-command.h> > #include <pulsecore/log.h> > @@ -360,6 +361,15 @@ static char *check_configured_address(void) { > return default_server; > } > > +static bool valid_pid_file = false; > +static void pid_file_deleted(void *userdata) > +{ > + pa_core *c = userdata; > + pa_log_info("Our pid file has been deleted (probably due to session logout), quitting..."); > + valid_pid_file = false; > + pa_core_exit(c, true, 0); > +} > + > #ifdef HAVE_DBUS > static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) { > DBusError error; > @@ -402,7 +412,6 @@ int main(int argc, char *argv[]) { > char *s; > char *configured_address; > int r = 0, retval = 1, d = 0; > - pa_bool_t valid_pid_file = FALSE; > pa_bool_t ltdl_init = FALSE; > int passed_fd = -1; > const char *e; > @@ -414,6 +423,7 @@ int main(int argc, char *argv[]) { > pa_time_event *win32_timer; > struct timeval win32_tv; > #endif > + pa_inotify *pid_monitor = NULL; > int autospawn_fd = -1; > pa_bool_t autospawn_locked = FALSE; > #ifdef HAVE_DBUS > @@ -984,7 +994,7 @@ int main(int argc, char *argv[]) { > goto finish; > } > > - valid_pid_file = TRUE; > + valid_pid_file = true; > } > > pa_disable_sigpipe(); > @@ -1014,6 +1024,9 @@ int main(int argc, char *argv[]) { > goto finish; > } > > + if (valid_pid_file) > + pid_monitor = pa_inotify_start(pa_pid_file_name(), c, pid_file_deleted, c); > + > c->default_sample_spec = conf->default_sample_spec; > c->alternate_sample_rate = conf->alternate_sample_rate; > c->default_channel_map = conf->default_channel_map; > @@ -1161,6 +1174,9 @@ finish: > pa_mainloop_get_api(mainloop)->time_free(win32_timer); > #endif > > + if (pid_monitor) > + pa_inotify_stop(pid_monitor); > + > if (c) { > /* Ensure all the modules/samples are unloaded when the core is still ref'ed, > * as unlink callback hooks in modules may need the core to be ref'ed */ > diff --git a/src/pulsecore/inotify-wrapper.c b/src/pulsecore/inotify-wrapper.c > new file mode 100644 > index 0000000..00e36c6 > --- /dev/null > +++ b/src/pulsecore/inotify-wrapper.c > @@ -0,0 +1,93 @@ > +#ifdef HAVE_CONFIG_H > +#include <config.h> > +#endif > + > +#include <fcntl.h> > +#include <sys/inotify.h> > +#include <errno.h> > + > +#include "inotify-wrapper.h" > +#include <pulse/mainloop.h> > +#include <pulsecore/core-util.h> > +#include <pulsecore/core-error.h> > + > +struct pa_inotify { > + char *filename; > + void *callback_data; > + pa_inotify_cb callback; > + int fd; > + pa_io_event *io_event; > + pa_core *core; > +}; > + > + > +static void inotify_cb( > + pa_mainloop_api *a, > + pa_io_event *e, > + int fd, > + pa_io_event_flags_t events, > + void *userdata) { > + > + pa_inotify *i = userdata; > + int pid_fd; > + > + pa_assert(i); > + > + pid_fd = pa_open_cloexec(i->filename, O_RDONLY > +#ifdef O_NOFOLLOW > + |O_NOFOLLOW > +#endif > + , S_IRUSR); > + > + if (pid_fd < 0) { > + if (i->callback) > + i->callback(i->callback_data); > + } else > + pa_close(pid_fd); > +} > + > + > +pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *core) { > + > + pa_inotify *i = pa_xnew0(pa_inotify, 1); > + pa_assert(i); > + > + i->core = core; > + pa_core_ref(core); > + > + i->filename = pa_xstrdup(filename); > + i->callback_data = userdata; > + i->callback = cb; > + i->fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); > + > + if (i->fd < 0) { > + pa_log("inotify_init1() failed: %s", pa_cstrerror(errno)); > + pa_inotify_stop(i); > + return NULL; > + } > + > + if (inotify_add_watch(i->fd, filename, IN_ATTRIB|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF) < 0) { > + pa_log("inotify_add_watch() failed: %s", pa_cstrerror(errno)); > + pa_inotify_stop(i); > + return NULL; > + } > + > + pa_assert_se(i->io_event = core->mainloop->io_new(core->mainloop, i->fd, PA_IO_EVENT_INPUT, inotify_cb, i)); > + > + return i; > +} > + > + > +void pa_inotify_stop(pa_inotify *i) { > + > + pa_assert(i); > + > + if (i->io_event) > + i->core->mainloop->io_free(i->io_event); > + if (i->fd) > + pa_close(i->fd); > + pa_xfree(i->filename); > + if (i->core) > + pa_core_unref(i->core); > + pa_xfree(i); > +} > diff --git a/src/pulsecore/inotify-wrapper.h b/src/pulsecore/inotify-wrapper.h > new file mode 100644 > index 0000000..e3b78d7 > --- /dev/null > +++ b/src/pulsecore/inotify-wrapper.h > @@ -0,0 +1,13 @@ > +#ifndef fooinotifywrapperhfoo > +#define fooinotifywrapperhfoo > + > +#include <pulsecore/core.h> > + > +typedef struct pa_inotify pa_inotify; > + > +typedef void (*pa_inotify_cb)(void *userdata); > + > +pa_inotify *pa_inotify_start(const char *filename, void *userdata, pa_inotify_cb cb, pa_core *c); > +void pa_inotify_stop(pa_inotify *i); > + > +#endif > diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c > index 588349b..3ef3981 100644 > --- a/src/pulsecore/pid.c > +++ b/src/pulsecore/pid.c > @@ -183,6 +183,11 @@ static int proc_name_ours(pid_t pid, const char *procname) { > > } > > +char *pa_pid_file_name() > +{ > + return pa_runtime_path("pid"); > +} > + > /* Create a new PID file for the current process. */ > int pa_pid_file_create(const char *procname) { > int fd = -1; > diff --git a/src/pulsecore/pid.h b/src/pulsecore/pid.h > index d8458bf..507f75e 100644 > --- a/src/pulsecore/pid.h > +++ b/src/pulsecore/pid.h > @@ -22,6 +22,7 @@ > USA. > ***/ > > +char *pa_pid_file_name(void); > int pa_pid_file_create(const char *procname); > int pa_pid_file_remove(void); > int pa_pid_file_check_running(pid_t *pid, const char *procname); > -- David Henningsson, Canonical Ltd. https://launchpad.net/~diwic -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-inotify-wrapper-Quit-daemon-if-pid-file-is-removed.patch Type: text/x-patch Size: 8031 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20130419/3f72b562/attachment.bin>