summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2015-03-07 08:48:07 +0100
committerDiogo Franco (Kovensky) <diogomfranco@gmail.com>2015-03-11 12:39:56 +0900
commit83e98d3adaa4da3fcea817c3fbbb29d8c975e351 (patch)
tree9df4af8b9f77e754c1b170fb38a9abbc420bbedb
parenta424fe1296eb3284834fad0649272db9a3da56aa (diff)
downloadmpv-83e98d3adaa4da3fcea817c3fbbb29d8c975e351.tar.bz2
mpv-83e98d3adaa4da3fcea817c3fbbb29d8c975e351.tar.xz
cocoa: fix some crashes caused by async uninit
Always keep around our private state and destroy it when we are really done in the async uninit callback. Fixes #1657 (cherry picked from commit c66b51dab02d9eb0629dc87612459436cd1a882e)
-rw-r--r--video/out/cocoa_common.m41
1 files changed, 13 insertions, 28 deletions
diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m
index 4e3c461eaa..172f973cf1 100644
--- a/video/out/cocoa_common.m
+++ b/video/out/cocoa_common.m
@@ -52,7 +52,7 @@
#define cocoa_unlock(s) pthread_mutex_unlock(&s->mutex)
static void vo_cocoa_fullscreen(struct vo *vo);
-static void cocoa_rm_fs_screen_profile_observer(struct vo *vo);
+static void cocoa_rm_fs_screen_profile_observer(struct vo_cocoa_state *s);
struct vo_cocoa_state {
NSWindow *window;
@@ -111,17 +111,15 @@ static void queue_new_video_size(struct vo *vo, int w, int h)
}
}
-static void enable_power_management(struct vo *vo)
+static void enable_power_management(struct vo_cocoa_state *s)
{
- struct vo_cocoa_state *s = vo->cocoa;
if (!s->power_mgmt_assertion) return;
IOPMAssertionRelease(s->power_mgmt_assertion);
s->power_mgmt_assertion = kIOPMNullAssertionID;
}
-static void disable_power_management(struct vo *vo)
+static void disable_power_management(struct vo_cocoa_state *s)
{
- struct vo_cocoa_state *s = vo->cocoa;
if (s->power_mgmt_assertion) return;
IOPMAssertionCreateWithName(
kIOPMAssertionTypePreventUserIdleDisplaySleep,
@@ -148,7 +146,7 @@ static void set_application_icon(NSApplication *app)
int vo_cocoa_init(struct vo *vo)
{
- struct vo_cocoa_state *s = talloc_zero(vo, struct vo_cocoa_state);
+ struct vo_cocoa_state *s = talloc_zero(NULL, struct vo_cocoa_state);
*s = (struct vo_cocoa_state){
.waiting_frame = false,
.power_mgmt_assertion = kIOPMNullAssertionID,
@@ -190,16 +188,10 @@ void vo_cocoa_register_resize_callback(struct vo *vo,
void vo_cocoa_uninit(struct vo *vo)
{
struct vo_cocoa_state *s = vo->cocoa;
- NSView *ev = s->view;
-
- // keep the event view around for later in order to call -clear
- if (!s->embedded) {
- [ev retain];
- }
with_cocoa_lock_on_main_thread(vo, ^{
- enable_power_management(vo);
- cocoa_rm_fs_screen_profile_observer(vo);
+ enable_power_management(s);
+ cocoa_rm_fs_screen_profile_observer(s);
[s->gl_ctx release];
@@ -208,21 +200,15 @@ void vo_cocoa_uninit(struct vo *vo)
[s->video removeFromSuperview];
[s->view removeFromSuperview];
+ [(MpvEventsView *)s->view clear];
[s->view release];
// if using --wid + libmpv there's no window to release
if (s->window)
[s->window release];
- });
- // don't use the mutex, because at that point it could have been destroyed
- // and no one is accessing the events view anyway
- if (!s->embedded) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [(MpvEventsView *)ev clear];
- [ev release];
- });
- }
+ talloc_free(s);
+ });
}
static int get_screen_handle(struct vo *vo, int identifier, NSWindow *window,
@@ -423,9 +409,8 @@ static int cocoa_set_window_title(struct vo *vo, const char *title)
return VO_TRUE;
}
-static void cocoa_rm_fs_screen_profile_observer(struct vo *vo)
+static void cocoa_rm_fs_screen_profile_observer(struct vo_cocoa_state *s)
{
- struct vo_cocoa_state *s = vo->cocoa;
[[NSNotificationCenter defaultCenter]
removeObserver:s->fs_icc_changed_ns_observer];
}
@@ -435,7 +420,7 @@ static void cocoa_add_fs_screen_profile_observer(struct vo *vo)
struct vo_cocoa_state *s = vo->cocoa;
if (s->fs_icc_changed_ns_observer)
- cocoa_rm_fs_screen_profile_observer(vo);
+ cocoa_rm_fs_screen_profile_observer(s);
if (vo->opts->fsscreen_id < 0)
return;
@@ -663,10 +648,10 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg)
case VOCTRL_UPDATE_WINDOW_TITLE:
return cocoa_set_window_title(vo, (const char *) arg);
case VOCTRL_RESTORE_SCREENSAVER:
- enable_power_management(vo);
+ enable_power_management(vo->cocoa);
return VO_TRUE;
case VOCTRL_KILL_SCREENSAVER:
- disable_power_management(vo);
+ disable_power_management(vo->cocoa);
return VO_TRUE;
case VOCTRL_GET_ICC_PROFILE:
vo_cocoa_control_get_icc_profile(vo, arg);