diff options
author | wm4 <wm4@nowhere> | 2014-06-07 15:08:45 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-06-07 15:57:54 +0200 |
commit | 500ce69a06be2cb2b79f310e638e4c4ceabe447e (patch) | |
tree | a855d9bc2c2be7deaa9db06c787d61ffd1f33136 /player/client.c | |
parent | d64bd9efa13c5e1fc71cfc565950b4afe6e53c8a (diff) | |
download | mpv-500ce69a06be2cb2b79f310e638e4c4ceabe447e.tar.bz2 mpv-500ce69a06be2cb2b79f310e638e4c4ceabe447e.tar.xz |
client API: add API function that ensures total destruction
mpv_destroy() should perhaps better be called mpv_detach(), because it
destroys only the handle, not necessarily the player. The player is only
terminated if a quit command is sent.
This function quits automatically, and additionally waits until the
player is completely destroyed. It removes the possibility that the
player core is still uninitializing, while all client handles are
already destroyed. (Although in practice, the difference is usually not
important.)
Diffstat (limited to 'player/client.c')
-rw-r--r-- | player/client.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/player/client.c b/player/client.c index be8cbc5d88..9a984052b1 100644 --- a/player/client.c +++ b/player/client.c @@ -77,6 +77,7 @@ struct observe_property { struct mpv_handle { // -- immmutable char *name; + bool owner; struct mp_log *log; struct MPContext *mpctx; struct mp_client_api *clients; @@ -299,11 +300,41 @@ void mpv_destroy(mpv_handle *ctx) assert(!ctx); } +static void get_thread(void *ptr) +{ + *(pthread_t *)ptr = pthread_self(); +} + +void mpv_terminate_destroy(mpv_handle *ctx) +{ + mpv_command(ctx, (const char*[]){"quit", NULL}); + + if (!ctx->owner) { + mpv_destroy(ctx); + return; + } + + mp_dispatch_lock(ctx->mpctx->dispatch); + assert(ctx->mpctx->autodetach); + ctx->mpctx->autodetach = false; + mp_dispatch_unlock(ctx->mpctx->dispatch); + + pthread_t playthread; + mp_dispatch_run(ctx->mpctx->dispatch, get_thread, &playthread); + + mpv_destroy(ctx); + + // And this is also the reason why we only allow 1 thread (the owner) to + // call this function. + pthread_join(playthread, NULL); +} + mpv_handle *mpv_create(void) { struct MPContext *mpctx = mp_create(); mpv_handle *ctx = mp_new_client(mpctx->clients, "main"); if (ctx) { + ctx->owner = true; // Set some defaults. mpv_set_option_string(ctx, "config", "no"); mpv_set_option_string(ctx, "idle", "yes"); @@ -319,8 +350,7 @@ mpv_handle *mpv_create(void) static void *playback_thread(void *p) { struct MPContext *mpctx = p; - - pthread_detach(pthread_self()); + mpctx->autodetach = true; mp_play_files(mpctx); |