summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-06-11 17:38:50 +0000
committerLennart Poettering <lennart@poettering.net>2008-06-11 17:38:50 +0000
commitac0f5275c5cbe72d5c81d9bb4aed4b9c2a5f5802 (patch)
tree7992890250cc83a91ad030768c8e54aa5c16bfb0 /src
parentc33db3ce68197cfe93f1fdf1b6459b1c7afb9057 (diff)
add new switch --start to the PA binary which allows starting PA if it is not running yet. In contrast to normal startup an already running PA will not be considered an error. Also, take the autospawn lock so we can guarantee that after this call returns PA is ralive and running
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2513 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src')
-rw-r--r--src/daemon/cmdline.c10
-rw-r--r--src/daemon/daemon-conf.h1
-rw-r--r--src/daemon/main.c56
-rw-r--r--src/pulsecore/pid.c1
4 files changed, 61 insertions, 7 deletions
diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c
index 97c75f37..03b1ac78 100644
--- a/src/daemon/cmdline.c
+++ b/src/daemon/cmdline.c
@@ -66,7 +66,8 @@ enum {
ARG_DISABLE_SHM,
ARG_DUMP_RESAMPLE_METHODS,
ARG_SYSTEM,
- ARG_CLEANUP_SHM
+ ARG_CLEANUP_SHM,
+ ARG_START
};
/* Tabel for getopt_long() */
@@ -91,6 +92,7 @@ static const struct option long_options[] = {
{"dl-search-path", 1, 0, ARG_DL_SEARCH_PATH},
{"resample-method", 1, 0, ARG_RESAMPLE_METHOD},
{"kill", 0, 0, ARG_KILL},
+ {"start", 0, 0, ARG_START},
{"use-pid-file", 2, 0, ARG_USE_PID_FILE},
{"check", 0, 0, ARG_CHECK},
{"system", 2, 0, ARG_SYSTEM},
@@ -119,6 +121,7 @@ void pa_cmdline_help(const char *argv0) {
" --dump-modules Dump list of available modules\n"
" --dump-resample-methods Dump available resample methods\n"
" --cleanup-shm Cleanup stale shared memory segments\n"
+ " --start Start the daemon if it is not running\n"
" -k --kill Kill a running daemon\n"
" --check Check for a running daemon\n\n"
@@ -207,6 +210,11 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
conf->cmd = PA_CMD_KILL;
break;
+ case ARG_START:
+ conf->cmd = PA_CMD_START;
+ conf->daemonize = TRUE;
+ break;
+
case ARG_CHECK:
conf->cmd = PA_CMD_CHECK;
break;
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index 03a75661..373924ac 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -37,6 +37,7 @@
/* The actual command to execute */
typedef enum pa_daemon_conf_cmd {
PA_CMD_DAEMON, /* the default */
+ PA_CMD_START,
PA_CMD_HELP,
PA_CMD_VERSION,
PA_CMD_DUMP_CONF,
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 6e5997cf..d4c16fef 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -96,6 +96,8 @@
#include "ltdl-bind-now.h"
#include "polkit.h"
+#define AUTOSPAWN_LOCK "autospawn.lock"
+
#ifdef HAVE_LIBWRAP
/* Only one instance of these variables */
int allow_severity = LOG_INFO;
@@ -344,6 +346,8 @@ int main(int argc, char *argv[]) {
pa_time_event *win32_timer;
struct timeval win32_tv;
#endif
+ char *lf = NULL;
+ int autospawn_lock_fd = -1;
#if defined(__linux__) && defined(__OPTIMIZE__)
/*
@@ -486,13 +490,13 @@ int main(int argc, char *argv[]) {
if (conf->high_priority && !pa_can_high_priority())
pa_log_warn("High-priority scheduling enabled in configuration but not allowed by policy.");
- if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
+ if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
pa_raise_priority(conf->nice_level);
if (suid_root) {
pa_bool_t drop;
- drop = conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling;
+ drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
#ifdef RLIMIT_RTPRIO
if (!drop) {
@@ -608,7 +612,7 @@ int main(int argc, char *argv[]) {
goto finish;
default:
- pa_assert(conf->cmd == PA_CMD_DAEMON);
+ pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
}
if (real_root && !conf->system_instance)
@@ -618,6 +622,15 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ if (conf->cmd == PA_CMD_START) {
+ /* If we shall start PA only when it is not running yet, we
+ * first take the autospawn lock to make things
+ * synchronous. */
+
+ lf = pa_runtime_path(AUTOSPAWN_LOCK);
+ autospawn_lock_fd = pa_lock_lockfile(lf);
+ }
+
if (conf->daemonize) {
pid_t child;
int tty_fd;
@@ -661,6 +674,14 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ if (autospawn_lock_fd >= 0) {
+ /* The lock file is unlocked from the parent, so we need
+ * to close it in the child */
+
+ pa_close(autospawn_lock_fd);
+ autospawn_lock_fd = -1;
+ }
+
pa_assert_se(pa_close(daemon_pipe[0]) == 0);
daemon_pipe[0] = -1;
#endif
@@ -728,7 +749,20 @@ int main(int argc, char *argv[]) {
pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode()));
if (conf->use_pid_file) {
- if (pa_pid_file_create("pulseaudio") < 0) {
+ int z;
+
+ if ((z = pa_pid_file_create("pulseaudio")) != 0) {
+
+ if (conf->cmd == PA_CMD_START && z > 0) {
+ /* If we are already running and with are run in
+ * --start mode, then let's return this as success. */
+
+ pa_log_info("z=%i rock!", z);
+
+ retval = 0;
+ goto finish;
+ }
+
pa_log("pa_pid_file_create() failed.");
goto finish;
}
@@ -826,11 +860,12 @@ int main(int argc, char *argv[]) {
goto finish;
}
-
#ifdef HAVE_FORK
- if (conf->daemonize) {
+ if (daemon_pipe[1] >= 0) {
int ok = 0;
pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
+ pa_close(daemon_pipe[1]);
+ daemon_pipe[1] = -1;
}
#endif
@@ -844,6 +879,12 @@ int main(int argc, char *argv[]) {
finish:
+ if (autospawn_lock_fd >= 0)
+ pa_unlock_lockfile(lf, autospawn_lock_fd);
+
+ if (lf)
+ pa_xfree(lf);
+
#ifdef OS_IS_WIN32
if (win32_timer)
pa_mainloop_get_api(mainloop)->time_free(win32_timer);
@@ -860,6 +901,9 @@ finish:
pa_signal_done();
#ifdef HAVE_FORK
+ if (daemon_pipe[1] >= 0)
+ pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
+
pa_close_pipe(daemon_pipe);
#endif
diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c
index 9e93234f..dd2e699d 100644
--- a/src/pulsecore/pid.c
+++ b/src/pulsecore/pid.c
@@ -220,6 +220,7 @@ int pa_pid_file_create(const char *procname) {
if (ours) {
pa_log("Daemon already running.");
+ ret = 1;
goto fail;
}
}