diff options
| author | Andre Noll <maan@tuebingen.mpg.de> | 2026-10-26 22:03:22 +0100 |
|---|---|---|
| committer | Andre Noll <maan@tuebingen.mpg.de> | 2026-10-26 22:03:22 +0100 |
| commit | b4ad90d96ccdda29627f09fe0ee3cc3de716294b (patch) | |
| tree | 46f26dd23ece106307a9ec862d5de488d967b756 /mixer.c | |
| parent | 6a870fb2d464045cbc64d55e7c4bf1d88155063a (diff) | |
| parent | ed2248c9c56358e896965ad6310abe11bbdb309f (diff) | |
Merge topic branch t/mixer into pupu
para_mixer improvements
-----------------------
Link para_mixer with audioc_common.o to make it single threaded.
* t/mixer:
Make para_mixer single-threaded.
mixer: Introduce die().
crypt: use {con,de}structor to init/shutdown the library.
client: Use a named enumeration for the client status.
Introduce struct client_config to hide context from public API.
mixer: Link with audioc_common.o
Move recv_buffer() and recv_bin_buffer() from net.c to fd.c.
mixer: Rename client_cmd() -> run_client_cmd().
mixer: Rename audioc_cmd() -> run_audioc_cmd().
Diffstat (limited to 'mixer.c')
| -rw-r--r-- | mixer.c | 164 |
1 files changed, 88 insertions, 76 deletions
@@ -24,11 +24,14 @@ #include "mixer.lsg.h" #include "para.h" +#include "audioc.h" #include "lsu.h" #include "fd.h" #include "string.h" #include "mix.h" #include "error.h" +#include "sideband.h" +#include "client.h" DEFINE_PARA_ERRLIST; @@ -59,6 +62,12 @@ typedef int (*mixer_subcommand_handler_t)(const struct mixer *); #define EXPORT_CMD(_cmd) const mixer_subcommand_handler_t \ lsg_mixer_com_ ## _cmd ## _user_data = &com_ ## _cmd; + +#define die(f,...) { \ + para_log(LL_EMERG, "%s: " f, __func__, ## __VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } + static int loglevel; static __printf_2_3 void date_log(int ll, const char *fmt, ...) { @@ -202,80 +211,83 @@ static int com_fade(const struct mixer *m) } EXPORT_CMD(fade); -static void run(const char *exe, const char *cmd) +static void run_client_cmd_argv(int argc, char **argv) { - int ret, status, fds[3] = {0, 0, 0}; - pid_t pid; - char *cmdline = make_message("%s %s", exe, cmd); + char *result = NULL; + int ret = client_run(argc, argv, &result); - PARA_INFO_LOG("%s\n", cmdline); - ret = xexec(&pid, cmdline, fds); - free(cmdline); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - goto fail; - } - do - ret = waitpid(pid, &status, 0); - while (ret == -1 && errno == EINTR); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", strerror(errno)); - goto fail; - } - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - goto fail; - return; -fail: - PARA_EMERG_LOG("command \"%s\" failed\n", cmd); - exit(EXIT_FAILURE); + PARA_INFO_LOG("cmd: %s\n", argv[0]); + if (ret < 0) + die("client_run(%s): %s\n", argv[0], para_strerror(-ret)); + if (result && *result) + PARA_INFO_LOG("result: %s\n", result); + free(result); } -static char *get_status_item(const char *status_item_name) +static void run_client_cmd(char *cmd) { - pid_t pid; - int ret, fds[3] = {0, 1, 0}; - char *buf, *p, *item = NULL, *cmdline; - - cmdline = make_message("para_audioc -- stat --one-shot %s", - status_item_name); - ret = xexec(&pid, cmdline, fds); - free(cmdline); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - return para_strdup(NULL); - } - buf = alloc(100); - ret = read(fds[1], buf, 99); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", strerror(errno)); - goto free_buf; + char *argv[] = {cmd}; + run_client_cmd_argv(1, argv); +} + +static char *get_status_item(char *status_item_name) +{ + char *argv[] = {"stat", "--one-shot", status_item_name}; + int argc = ARRAY_SIZE(argv), ret, fd; + char *p; + struct iovec iov; + struct sb_buffer sbb; + struct sb_context *ctx; + + ret = connect_audiod(OPT_STRING_VAL(PARA_MIXER, SOCKET), argc, argv); + if (ret < 0) + die("connect_audiod stat %s: %s\n", status_item_name, + para_strerror(-ret)); + fd = ret; + ctx = sb_new_recv(100, NULL, NULL); + for (;;) { + sb_get_recv_buffer(ctx, &iov); + ret = recv_bin_buffer(fd, iov.iov_base, iov.iov_len); + if (ret < 0) + die("recv_bin_buffer: %s\n", para_strerror(-ret)); + if (ret == 0) + die("unexpected eof\n"); + ret = sb_received(ctx, ret, &sbb); + if (ret < 0) + die("sb_received: %s\n", para_strerror(-ret)); + if (ret > 0) + break; } - buf[ret] = '\0'; - p = strrchr(buf, '\n'); + + p = strrchr(sbb.iov.iov_base, '\n'); if (!p) - goto free_buf; + goto parse_error; *p = '\0'; - p = strchr(buf, ':'); + p = strchr(sbb.iov.iov_base, ':'); if (!p || p[1] == '\0') - goto free_buf; - item = para_strdup(p + 2); -free_buf: - free(buf); - close(fds[1]); - do - ret = waitpid(pid, NULL, 0); - while (ret == -1 && errno == EINTR); - return item? item : para_strdup(NULL); + goto parse_error; + p = para_strdup(p + 2); + free(sbb.iov.iov_base); + return p; +parse_error: + die("parse error for item %s, buf=%s\n", status_item_name, + (char *)sbb.iov.iov_base); } -static void client_cmd(const char *cmd) +static void run_audioc_cmd(const char *cmd) { - run("para_client", cmd); -} + char **argv; + int argc, ret; -static void audioc_cmd(const char *cmd) -{ - run("para_audioc", cmd); + ret = create_argv(cmd, " ", &argv); + if (ret < 0) + die("create_argv %s: %s\n", cmd, para_strerror(-ret)); + argc = ret; + ret = connect_audiod(OPT_STRING_VAL(PARA_MIXER, SOCKET), argc, argv); + free_argv(argv); + if (ret < 0) + die("connect_audiod %s: %s\n", cmd, para_strerror(-ret)); + close(ret); } static int set_initial_volume(const struct mixer *m, struct mixer_handle *h) @@ -321,7 +333,7 @@ static int change_mop(const char *mop, const struct mixer *m, struct mixer_handle *h) { int ret; - char *current_mop, *status, *cmd; + char *current_mop, *status; static bool initial_volume_set, playing; if (!mop || !*mop) @@ -331,6 +343,7 @@ static int change_mop(const char *mop, const struct mixer *m, PARA_INFO_LOG("afs_mode: %s, status: %s\n", current_mop, status); playing = !strcmp(status, "playing"); if (strcmp(current_mop, mop)) { + char *argv[2] = {"select"}; if (playing) { uint32_t old_vol; ret = m->get(h); @@ -340,19 +353,19 @@ static int change_mop(const char *mop, const struct mixer *m, ret = fade(m, h, 0, 3, false); if (ret < 0) goto free_status; - audioc_cmd("off"); - client_cmd("stop"); + run_audioc_cmd("off"); + run_client_cmd("stop"); playing = false; - audioc_cmd("on"); + run_audioc_cmd("on"); ret = m->set(h, old_vol); if (ret < 0) goto free_status; } else if (!strcmp(status, "paused")) - client_cmd("next"); + run_client_cmd("next"); PARA_NOTICE_LOG("switching to %s\n", mop); - cmd = make_message("select %s", mop); - client_cmd(cmd); - free(cmd); + argv[1] = para_strdup(mop); + run_client_cmd_argv(2, argv); + free(argv[1]); } if (!initial_volume_set) { initial_volume_set = true; @@ -361,7 +374,7 @@ static int change_mop(const char *mop, const struct mixer *m, goto free_status; } if (!playing) - client_cmd("play"); + run_client_cmd("play"); ret = 1; free_status: free(status); @@ -425,7 +438,7 @@ static int com_sleep(const struct mixer *m) ret = change_mop(initial_mood, m, h); if (ret < 0) goto close_mixer; - audioc_cmd("on"); + run_audioc_cmd("on"); if (ret > 0) /* playing initial mood */ sleep(OPT_UINT32_VAL(SLEEP, INITIAL_DELAY)); ret = change_mop(fo_mood, m, h); @@ -438,7 +451,7 @@ static int com_sleep(const struct mixer *m) if (ret < 0) goto close_mixer; if (ret == 0) /* no sleep mood */ - client_cmd("stop"); + run_client_cmd("stop"); time(&t1); if (wake_time_epoch > t1 + fit) sleep(wake_time_epoch - t1 - fit); @@ -467,10 +480,10 @@ static int com_snooze(const struct mixer *m) ret = fade(m, h, sovol, sotime, true); if (ret < 0) goto close_mixer; - client_cmd("pause"); + run_client_cmd("pause"); PARA_NOTICE_LOG("%" PRIu32 " seconds snooze time...\n", stime); sleep(stime); - client_cmd("play"); + run_client_cmd("play"); ret = fade(m, h, sivol, sitime, true); close_mixer: m->close(h); @@ -654,6 +667,5 @@ fail: if (errctx) PARA_ERROR_LOG("%s\n", errctx); free(errctx); - PARA_EMERG_LOG("%s\n", para_strerror(-ret)); - return EXIT_FAILURE; + die("%s\n", para_strerror(-ret)); } |
