mac/common: fix usage of vo struct after vo uninit race

we keep track of the current vo struct to flag for events that are
initiated async by various thread from different system notifications.
the problem here is the usage of that vo struct after uninit.

make accessing of that vo struct atomic and clear it on uninit, so it
can't be used afterwards by concurrent threads from system
notifications or events.

Fixes #15088
This commit is contained in:
der richter 2024-10-14 21:47:37 +02:00
parent 3172186226
commit ff64d87bb4
3 changed files with 16 additions and 18 deletions

View File

@ -40,7 +40,7 @@ class CocoaCB: Common, EventSubscriber {
}
func preinit(_ vo: UnsafeMutablePointer<vo>) {
self.vo = vo
eventsLock.withLock { self.vo = vo }
input = InputHelper(vo.pointee.input_ctx, option)
if backendState == .uninitialized {
@ -57,12 +57,13 @@ class CocoaCB: Common, EventSubscriber {
}
func uninit() {
eventsLock.withLock { self.vo = nil }
window?.orderOut(nil)
window?.close()
}
func reconfig(_ vo: UnsafeMutablePointer<vo>) {
self.vo = vo
eventsLock.withLock { self.vo = vo }
if backendState == .needsInit {
DispatchQueue.main.sync { self.initBackend(vo) }
} else if option.vo.auto_window_resize {

View File

@ -22,7 +22,6 @@ class Common: NSObject {
var option: OptionHelper
var input: InputHelper?
var log: LogHelper
var vo: UnsafeMutablePointer<vo>?
let queue: DispatchQueue = DispatchQueue(label: "io.mpv.queue")
@objc var window: Window?
@ -32,6 +31,7 @@ class Common: NSObject {
var link: CVDisplayLink?
let eventsLock = NSLock()
var vo: UnsafeMutablePointer<vo>?
var events: Int = 0
var lightSensor: io_connect_t = 0
@ -145,6 +145,7 @@ class Common: NSObject {
}
func uninitCommon() {
eventsLock.withLock { self.vo = nil }
setCursorVisibility(true)
stopDisplaylink()
uninitLightSensor()
@ -455,23 +456,19 @@ class Common: NSObject {
}
func flagEvents(_ ev: Int) {
eventsLock.lock()
events |= ev
eventsLock.unlock()
guard let vo = vo else {
log.warning("vo nil in flagEvents")
return
eventsLock.withLock {
events |= ev
guard let vo = vo else { return }
vo_wakeup(vo)
}
vo_wakeup(vo)
}
func checkEvents() -> Int {
eventsLock.lock()
let ev = events
events = 0
eventsLock.unlock()
return ev
eventsLock.withLock {
let ev = events
events = 0
return ev
}
}
func windowDidEndAnimation() {}

View File

@ -29,7 +29,7 @@ class MacCommon: Common {
let log = LogHelper(mp_log_new(vo, vo.pointee.log, "mac"))
let option = OptionHelper(vo, vo.pointee.global)
super.init(option, log)
self.vo = vo
eventsLock.withLock { self.vo = vo }
input = InputHelper(vo.pointee.input_ctx, option)
presentation = Presentation(common: self)
timer = PreciseTimer(common: self)
@ -41,7 +41,7 @@ class MacCommon: Common {
}
@objc func config(_ vo: UnsafeMutablePointer<vo>) -> Bool {
self.vo = vo
eventsLock.withLock { self.vo = vo }
DispatchQueue.main.sync {
let previousActiveApp = getActiveApp()