mirror of
https://github.com/mpv-player/mpv
synced 2025-02-19 14:26:57 +00:00
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
This commit is contained in:
parent
ddbecd09b0
commit
c66b51dab0
@ -54,7 +54,7 @@
|
|||||||
#define cocoa_unlock(s) pthread_mutex_unlock(&s->mutex)
|
#define cocoa_unlock(s) pthread_mutex_unlock(&s->mutex)
|
||||||
|
|
||||||
static void vo_cocoa_fullscreen(struct vo *vo);
|
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 {
|
struct vo_cocoa_state {
|
||||||
NSWindow *window;
|
NSWindow *window;
|
||||||
@ -117,17 +117,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;
|
if (!s->power_mgmt_assertion) return;
|
||||||
IOPMAssertionRelease(s->power_mgmt_assertion);
|
IOPMAssertionRelease(s->power_mgmt_assertion);
|
||||||
s->power_mgmt_assertion = kIOPMNullAssertionID;
|
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;
|
if (s->power_mgmt_assertion) return;
|
||||||
IOPMAssertionCreateWithName(
|
IOPMAssertionCreateWithName(
|
||||||
kIOPMAssertionTypePreventUserIdleDisplaySleep,
|
kIOPMAssertionTypePreventUserIdleDisplaySleep,
|
||||||
@ -226,16 +224,15 @@ static void cocoa_init_light_sensor(struct vo *vo)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cocoa_uninit_light_sensor(struct vo *vo)
|
static void cocoa_uninit_light_sensor(struct vo_cocoa_state *s)
|
||||||
{
|
{
|
||||||
struct vo_cocoa_state *s = vo->cocoa;
|
|
||||||
IONotificationPortDestroy(s->light_sensor_io_port);
|
IONotificationPortDestroy(s->light_sensor_io_port);
|
||||||
IOObjectRelease(s->light_sensor);
|
IOObjectRelease(s->light_sensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vo_cocoa_init(struct vo *vo)
|
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){
|
*s = (struct vo_cocoa_state){
|
||||||
.waiting_frame = false,
|
.waiting_frame = false,
|
||||||
.power_mgmt_assertion = kIOPMNullAssertionID,
|
.power_mgmt_assertion = kIOPMNullAssertionID,
|
||||||
@ -278,17 +275,11 @@ void vo_cocoa_register_resize_callback(struct vo *vo,
|
|||||||
void vo_cocoa_uninit(struct vo *vo)
|
void vo_cocoa_uninit(struct vo *vo)
|
||||||
{
|
{
|
||||||
struct vo_cocoa_state *s = vo->cocoa;
|
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, ^{
|
with_cocoa_lock_on_main_thread(vo, ^{
|
||||||
enable_power_management(vo);
|
enable_power_management(s);
|
||||||
cocoa_uninit_light_sensor(vo);
|
cocoa_uninit_light_sensor(s);
|
||||||
cocoa_rm_fs_screen_profile_observer(vo);
|
cocoa_rm_fs_screen_profile_observer(s);
|
||||||
|
|
||||||
[s->gl_ctx release];
|
[s->gl_ctx release];
|
||||||
|
|
||||||
@ -297,21 +288,15 @@ void vo_cocoa_uninit(struct vo *vo)
|
|||||||
[s->video removeFromSuperview];
|
[s->video removeFromSuperview];
|
||||||
|
|
||||||
[s->view removeFromSuperview];
|
[s->view removeFromSuperview];
|
||||||
|
[(MpvEventsView *)s->view clear];
|
||||||
[s->view release];
|
[s->view release];
|
||||||
|
|
||||||
// if using --wid + libmpv there's no window to release
|
// if using --wid + libmpv there's no window to release
|
||||||
if (s->window)
|
if (s->window)
|
||||||
[s->window release];
|
[s->window release];
|
||||||
});
|
|
||||||
|
|
||||||
// don't use the mutex, because at that point it could have been destroyed
|
talloc_free(s);
|
||||||
// and no one is accessing the events view anyway
|
});
|
||||||
if (!s->embedded) {
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[(MpvEventsView *)ev clear];
|
|
||||||
[ev release];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_screen_handle(struct vo *vo, int identifier, NSWindow *window,
|
static int get_screen_handle(struct vo *vo, int identifier, NSWindow *window,
|
||||||
@ -512,9 +497,8 @@ static int cocoa_set_window_title(struct vo *vo, const char *title)
|
|||||||
return VO_TRUE;
|
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]
|
[[NSNotificationCenter defaultCenter]
|
||||||
removeObserver:s->fs_icc_changed_ns_observer];
|
removeObserver:s->fs_icc_changed_ns_observer];
|
||||||
}
|
}
|
||||||
@ -524,7 +508,7 @@ static void cocoa_add_fs_screen_profile_observer(struct vo *vo)
|
|||||||
struct vo_cocoa_state *s = vo->cocoa;
|
struct vo_cocoa_state *s = vo->cocoa;
|
||||||
|
|
||||||
if (s->fs_icc_changed_ns_observer)
|
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)
|
if (vo->opts->fsscreen_id < 0)
|
||||||
return;
|
return;
|
||||||
@ -752,10 +736,10 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg)
|
|||||||
case VOCTRL_UPDATE_WINDOW_TITLE:
|
case VOCTRL_UPDATE_WINDOW_TITLE:
|
||||||
return cocoa_set_window_title(vo, (const char *) arg);
|
return cocoa_set_window_title(vo, (const char *) arg);
|
||||||
case VOCTRL_RESTORE_SCREENSAVER:
|
case VOCTRL_RESTORE_SCREENSAVER:
|
||||||
enable_power_management(vo);
|
enable_power_management(vo->cocoa);
|
||||||
return VO_TRUE;
|
return VO_TRUE;
|
||||||
case VOCTRL_KILL_SCREENSAVER:
|
case VOCTRL_KILL_SCREENSAVER:
|
||||||
disable_power_management(vo);
|
disable_power_management(vo->cocoa);
|
||||||
return VO_TRUE;
|
return VO_TRUE;
|
||||||
case VOCTRL_GET_ICC_PROFILE:
|
case VOCTRL_GET_ICC_PROFILE:
|
||||||
vo_cocoa_control_get_icc_profile(vo, arg);
|
vo_cocoa_control_get_icc_profile(vo, arg);
|
||||||
|
Loading…
Reference in New Issue
Block a user