protocol-pulse: implement readiness notification

Write a newline to the fd in the PIPEWIRE_PULSE_NOTIFICATION_FD env
variable when set.

This is to implement readiness notification as suggested in
https://skarnet.org/software/s6/notifywhenup.html

Fixes #4347
This commit is contained in:
Wim Taymans 2024-10-22 09:50:27 +02:00
parent 7af43d87b3
commit 0dfd6d997f
4 changed files with 50 additions and 1 deletions

View file

@ -346,6 +346,13 @@
* Takes an object with the properties to update on the client. Common actions are to * Takes an object with the properties to update on the client. Common actions are to
* tweak the quantum values. * tweak the quantum values.
* *
* ### startup notification
*
* A newline will be written into the notification file descriptor when the server has
* started if the following environment variable is set:
*
* - PIPEWIRE_PULSE_NOTIFICATION_FD
*
* ## Example configuration * ## Example configuration
* *
*\code{.unparsed} *\code{.unparsed}

View file

@ -5559,6 +5559,8 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
cmd_run(impl); cmd_run(impl);
notify_startup();
return (struct pw_protocol_pulse *) impl; return (struct pw_protocol_pulse *) impl;
error_free: error_free:

View file

@ -159,7 +159,8 @@ const char *get_server_name(struct pw_context *context)
return name; return name;
} }
int create_pid_file(void) { int create_pid_file(void)
{
char pid_file[PATH_MAX]; char pid_file[PATH_MAX];
FILE *f; FILE *f;
int res; int res;
@ -185,3 +186,41 @@ int create_pid_file(void) {
return 0; return 0;
} }
int notify_startup(void)
{
long v;
int fd, res = 0;
char *endptr;
const char *env = getenv("PIPEWIRE_PULSE_NOTIFICATION_FD");
if (env == NULL || env[0] == '\0')
return 0;
errno = 0;
v = strtol(env, &endptr, 10);
if (endptr[0] != '\0')
errno = EINVAL;
if (errno != 0) {
res = -errno;
pw_log_error("can't parse PIPEWIRE_PULSE_NOTIFICATION_FD env: %m");
goto error;
}
fd = (int)v;
if (v != fd) {
res = -ERANGE;
pw_log_error("invalid PIPEWIRE_PULSE_NOTIFICATION_FD %ld: %s", v, spa_strerror(res));
goto error;
}
if (dprintf(fd, "\n") < 0) {
res = -errno;
pw_log_error("can't signal PIPEWIRE_PULSE_NOTIFICATION_FD: %m");
goto error;
}
close(fd);
unsetenv("PIPEWIRE_PULSE_NOTIFICATION_FD");
return 0;
error:
return res;
}

View file

@ -16,5 +16,6 @@ int check_flatpak(struct client *client, pid_t pid);
pid_t get_client_pid(struct client *client, int client_fd); pid_t get_client_pid(struct client *client, int client_fd);
const char *get_server_name(struct pw_context *context); const char *get_server_name(struct pw_context *context);
int create_pid_file(void); int create_pid_file(void);
int notify_startup(void);
#endif /* PULSE_SERVER_UTILS_H */ #endif /* PULSE_SERVER_UTILS_H */