summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-03-09 06:00:51 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-03-15 00:00:04 -0700
commita7f3cf473707b19bff9ea80b227490c8b305b601 (patch)
treeb094e1b8237d9ee09770e76809895b5d0e2eceaa
parent410a1b49edfbbf7d528fd7dd06b73d06e2f9fce4 (diff)
downloadmpv-a7f3cf473707b19bff9ea80b227490c8b305b601.tar.bz2
mpv-a7f3cf473707b19bff9ea80b227490c8b305b601.tar.xz
client API: add mpv_create_weak_client()
-rw-r--r--DOCS/client-api-changes.rst1
-rw-r--r--libmpv/client.h22
-rw-r--r--libmpv/mpv.def1
-rw-r--r--player/client.c23
-rw-r--r--player/client.h1
-rw-r--r--player/scripting.c1
6 files changed, 44 insertions, 5 deletions
diff --git a/DOCS/client-api-changes.rst b/DOCS/client-api-changes.rst
index 49964f5071..9b964da59a 100644
--- a/DOCS/client-api-changes.rst
+++ b/DOCS/client-api-changes.rst
@@ -37,6 +37,7 @@ API changes
changes subtly (see documentation in the header file). In particular,
mpv_detach_destroy() will not leave the player running in all
situations anymore (it gets closer to refcounting).
+ - add mpv_create_weak_client(), which makes use of above changes
1.28 - deprecate the render opengl_cb API, and replace it with render.h
and render_gl.h. The goal is allowing support for APIs other than
OpenGL. The old API is emulated with the new API.
diff --git a/libmpv/client.h b/libmpv/client.h
index 536000229e..335e1417bc 100644
--- a/libmpv/client.h
+++ b/libmpv/client.h
@@ -452,9 +452,11 @@ int mpv_initialize(mpv_handle *ctx);
* API call.
*
* Since mpv client API version 1.29:
- * If the last mpv_handle is detached, the core player is destroyed. Note that
- * internal mpv_handles created due to scripts (e.g. the OSC) will keep the
- * player running. (To be fixed in the following commit.)
+ * If the last mpv_handle is detached, the core player is destroyed. In
+ * addition, if there are only weak mpv_handles (such as created by
+ * mpv_create_weak_client() or internal scripts), these mpv_handles will
+ * be sent MPV_EVENT_SHUTDOWN. This function may block until these clients
+ * have responded to the shutdown event, and the core is finally destroyed.
*
* Before mpv client API version 1.29:
* This left the player running. If you want to be sure that the
@@ -517,6 +519,20 @@ void mpv_terminate_destroy(mpv_handle *ctx);
mpv_handle *mpv_create_client(mpv_handle *ctx, const char *name);
/**
+ * This is the same as mpv_create_client(), but the created mpv_handle is
+ * treated as a weak reference. If all mpv_handles referencing a core are
+ * weak references, the core is automatically destroyed. (This still goes
+ * through normal uninit of course. Effectively, if the last non-weak mpv_handle
+ * is destroyed, then the weak mpv_handles receive MPV_EVENT_SHUTDOWN and are
+ * asked to terminate as well.)
+ *
+ * Note if you want to use this like refcounting: you have to be aware that
+ * mpv_terminate_destroy() _and_ mpv_detach_destroy() for the last non-weak
+ * mpv_handle will block until all weak mpv_handles are destroyed.
+ */
+mpv_handle *mpv_create_weak_client(mpv_handle *ctx, const char *name);
+
+/**
* Load a config file. This loads and parses the file, and sets every entry in
* the config file's default section as if mpv_set_option_string() is called.
*
diff --git a/libmpv/mpv.def b/libmpv/mpv.def
index 5299f69c9a..202f2071f0 100644
--- a/libmpv/mpv.def
+++ b/libmpv/mpv.def
@@ -7,6 +7,7 @@ mpv_command_node_async
mpv_command_string
mpv_create
mpv_create_client
+mpv_create_weak_client
mpv_detach_destroy
mpv_error_string
mpv_event_name
diff --git a/player/client.c b/player/client.c
index a887a16d2a..d347033fe5 100644
--- a/player/client.c
+++ b/player/client.c
@@ -136,6 +136,7 @@ struct mpv_handle {
uint64_t property_event_masks; // or-ed together event masks of all properties
bool fuzzy_initialized; // see scripting.c wait_loaded()
+ bool is_weak; // can not keep core alive on its own
struct mp_log_buffer *messages;
};
@@ -269,6 +270,13 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name
return client;
}
+void mp_client_set_weak(struct mpv_handle *ctx)
+{
+ pthread_mutex_lock(&ctx->lock);
+ ctx->is_weak = true;
+ pthread_mutex_unlock(&ctx->lock);
+}
+
const char *mpv_client_name(mpv_handle *ctx)
{
return ctx->name;
@@ -416,8 +424,11 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate)
if (mpctx->is_cli) {
terminate = false;
} else {
- // If the last mpv_handle got destroyed, destroy the core.
- if (clients->num_clients == 0)
+ // If the last strong mpv_handle got destroyed, destroy the core.
+ bool has_strong_ref = false;
+ for (int n = 0; n < clients->num_clients; n++)
+ has_strong_ref |= !clients->clients[n]->is_weak;
+ if (!has_strong_ref)
terminate = true;
// Reserve the right to destroy mpctx for us.
@@ -550,6 +561,14 @@ mpv_handle *mpv_create_client(mpv_handle *ctx, const char *name)
return new;
}
+mpv_handle *mpv_create_weak_client(mpv_handle *ctx, const char *name)
+{
+ mpv_handle *new = mpv_create_client(ctx, name);
+ if (new)
+ mp_client_set_weak(new);
+ return new;
+}
+
int mpv_initialize(mpv_handle *ctx)
{
lock_core(ctx);
diff --git a/player/client.h b/player/client.h
index deec3c793b..9ecbe2ed35 100644
--- a/player/client.h
+++ b/player/client.h
@@ -32,6 +32,7 @@ bool mp_client_event_is_registered(struct MPContext *mpctx, int event);
void mp_client_property_change(struct MPContext *mpctx, const char *name);
struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name);
+void mp_client_set_weak(struct mpv_handle *ctx);
struct mp_log *mp_client_get_log(struct mpv_handle *ctx);
struct mpv_global *mp_client_get_global(struct mpv_handle *ctx);
struct MPContext *mp_client_get_core(struct mpv_handle *ctx);
diff --git a/player/scripting.c b/player/scripting.c
index db622f0fe8..0838630bed 100644
--- a/player/scripting.c
+++ b/player/scripting.c
@@ -138,6 +138,7 @@ static int mp_load_script(struct MPContext *mpctx, const char *fname)
talloc_free(arg);
return -1;
}
+ mp_client_set_weak(arg->client);
arg->log = mp_client_get_log(arg->client);
MP_DBG(arg, "Loading %s %s...\n", backend->name, fname);