summaryrefslogtreecommitdiffstats
path: root/input/ipc-unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'input/ipc-unix.c')
-rw-r--r--input/ipc-unix.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/input/ipc-unix.c b/input/ipc-unix.c
index e047c30145..a416b54e1e 100644
--- a/input/ipc-unix.c
+++ b/input/ipc-unix.c
@@ -15,10 +15,9 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <pthread.h>
#include <errno.h>
#include <unistd.h>
-
+#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
@@ -26,8 +25,6 @@
#include <sys/stat.h>
#include <sys/un.h>
-#include "config.h"
-
#include "osdep/io.h"
#include "osdep/threads.h"
@@ -50,7 +47,7 @@ struct mp_ipc_ctx {
struct mp_client_api *client_api;
const char *path;
- pthread_t thread;
+ mp_thread thread;
int death_pipe[2];
};
@@ -61,6 +58,7 @@ struct client_arg {
const char *client_name;
int client_fd;
bool close_client_fd;
+ bool quit_on_close;
bool writable;
};
@@ -92,10 +90,8 @@ static int ipc_write_str(struct client_arg *client, const char *buf)
return 0;
}
-static void *client_thread(void *p)
+static MP_THREAD_VOID client_thread(void *p)
{
- pthread_detach(pthread_self());
-
// We don't use MSG_NOSIGNAL because the moldy fruit OS doesn't support it.
struct sigaction sa = { .sa_handler = SIG_IGN, .sa_flags = SA_RESTART };
sigfillset(&sa.sa_mask);
@@ -106,7 +102,9 @@ static void *client_thread(void *p)
struct client_arg *arg = p;
bstr client_msg = { talloc_strdup(NULL, ""), 0 };
- mpthread_set_name(arg->client_name);
+ char *tname = talloc_asprintf(NULL, "ipc/%s", arg->client_name);
+ mp_thread_set_name(tname);
+ talloc_free(tname);
int pipe_fd = mpv_get_wakeup_pipe(arg->client);
if (pipe_fd < 0) {
@@ -162,7 +160,7 @@ static void *client_thread(void *p)
}
}
- if (fds[1].revents & (POLLIN | POLLHUP)) {
+ if (fds[1].revents & (POLLIN | POLLHUP | POLLNVAL)) {
while (1) {
char buf[128];
bstr append = { buf, 0 };
@@ -210,9 +208,15 @@ done:
talloc_free(client_msg.start);
if (arg->close_client_fd)
close(arg->client_fd);
- mpv_destroy(arg->client);
+ struct mpv_handle *h = arg->client;
+ bool quit = arg->quit_on_close;
talloc_free(arg);
- return NULL;
+ if (quit) {
+ mpv_terminate_destroy(h);
+ } else {
+ mpv_destroy(h);
+ }
+ MP_THREAD_RETURN();
}
static bool ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client,
@@ -225,9 +229,10 @@ static bool ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client,
client->log = mp_client_get_log(client->client);
- pthread_t client_thr;
- if (pthread_create(&client_thr, NULL, client_thread, client))
+ mp_thread client_thr;
+ if (mp_thread_create(&client_thr, client_thread, client))
goto err;
+ mp_thread_detach(client_thr);
return true;
@@ -248,9 +253,11 @@ static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, int fd)
{
struct client_arg *client = talloc_ptrtype(NULL, client);
*client = (struct client_arg){
- .client_name = talloc_asprintf(client, "ipc-%d", id),
- .client_fd = fd,
- .close_client_fd = true,
+ .client_name =
+ id >= 0 ? talloc_asprintf(client, "ipc-%d", id) : "ipc",
+ .client_fd = fd,
+ .close_client_fd = id >= 0,
+ .quit_on_close = id < 0,
.writable = true,
};
@@ -263,6 +270,8 @@ bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
int pair[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair))
return false;
+ mp_set_cloexec(pair[0]);
+ mp_set_cloexec(pair[1]);
struct client_arg *client = talloc_ptrtype(NULL, client);
*client = (struct client_arg){
@@ -284,7 +293,7 @@ bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
return true;
}
-static void *ipc_thread(void *p)
+static MP_THREAD_VOID ipc_thread(void *p)
{
int rc;
@@ -293,7 +302,7 @@ static void *ipc_thread(void *p)
struct mp_ipc_ctx *arg = p;
- mpthread_set_name("ipc socket listener");
+ mp_thread_set_name("ipc/socket");
MP_VERBOSE(arg, "Starting IPC master\n");
@@ -368,7 +377,7 @@ done:
if (ipc_fd >= 0)
close(ipc_fd);
- return NULL;
+ MP_THREAD_RETURN();
}
struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
@@ -384,6 +393,21 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
.death_pipe = {-1, -1},
};
+ if (opts->ipc_client && opts->ipc_client[0]) {
+ int fd = -1;
+ if (strncmp(opts->ipc_client, "fd://", 5) == 0) {
+ char *end;
+ unsigned long l = strtoul(opts->ipc_client + 5, &end, 0);
+ if (!end[0] && l <= INT_MAX)
+ fd = l;
+ }
+ if (fd < 0) {
+ MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
+ } else {
+ ipc_start_client_json(arg, -1, fd);
+ }
+ }
+
talloc_free(opts);
if (!arg->path || !arg->path[0])
@@ -392,7 +416,7 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
if (mp_make_wakeup_pipe(arg->death_pipe) < 0)
goto out;
- if (pthread_create(&arg->thread, NULL, ipc_thread, arg))
+ if (mp_thread_create(&arg->thread, ipc_thread, arg))
goto out;
return arg;
@@ -412,7 +436,7 @@ void mp_uninit_ipc(struct mp_ipc_ctx *arg)
return;
(void)write(arg->death_pipe[1], &(char){0}, 1);
- pthread_join(arg->thread, NULL);
+ mp_thread_join(arg->thread);
close(arg->death_pipe[0]);
close(arg->death_pipe[1]);