-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Fix crash while quitting in AutoFileMatcher, #5056 #5102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
iina/PlayerState.swift
Outdated
@@ -58,7 +58,7 @@ enum PlayerState: Int { | |||
/// | |||
/// These are the states in which the player normally interacts with the mpv core. The mpv core **must not** be accessed when the | |||
/// player is in the `shuttingDown` or `shutDown` states. Accessing the core in these states can trigger a crash. | |||
@inlinable var active: Bool { self.rawValue <= PlayerState.stopping.rawValue } | |||
@inlinable var active: Bool { self.rawValue < PlayerState.stopping.rawValue } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this line since it's already fixed in dev.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will rebase with dev.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased with develop
so this change is no longer in the commit. I amended the commit comment and removed the statement about changing active
.
@@ -1024,18 +1028,23 @@ class MPVController: NSObject { | |||
private func readEvents() { | |||
queue.async { | |||
while ((self.mpv) != nil) { | |||
let event = mpv_wait_event(self.mpv, 0) | |||
let event = mpv_wait_event(self.mpv, 0)! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it safe to force unwarp here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change here is that the code was treating the return as option in readEvents
, but then passed it to handleEvent
which declared the type as UnsafePointer<mpv_event>!
. So readEvents
went to the trouble of treating it as optional only for it to be forced when handleEvent
was called. Thus the forcing just got moved to an earlier time. I don't think there is a change as far as risking a crash due to force unwrapping.
If this is ever nil
then mpv is seriously broken as the doc for mpv_wait_event
says:
The return value is never NULL.
guard currentTicket == self.backgroundQueueTicket else { return } | ||
self.loadExternalSubFile(sub) | ||
backgroundTaskInUse = true | ||
backgroundQueue.async { [self] in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider to use [unowned self]
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We never free players until shutdown so I don't see an advantage to the background task not having a strong reference.
log("Background task stopping due to error \(err.localizedDescription)", level: .error) | ||
} | ||
// This code must be queued to the main thread to avoid thread data races. | ||
DispatchQueue.main.async { [self] in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
This commit will: - Change the PlaybackInfo.state computed property to prevent additional inappropriate state transitions - Change PlayerCore.sendOSD to not show messages unless the player is active to prevent an unreported crash - Change MPVController.readEvents to stop once a MPV_EVENT_SHUTDOWN has been processed - Change the fileLoaded and fileStarted PlayerCore methods to do nothing if the player state is not active - Change the logger subsystem for AutoFileMatcher to include the player identifier - Change the names of the PlayerCore dispatch queues to include the player identifier - Move TicketExpiredError from AutoFileMatcher to PlayerCore - Add a checkTicket method to PlayerCore - Change more AutoFileMatcher methods to check the ticket and throw errors - Change AutoFileMatcher.startMatching to rethrow errors - Change PlayerCore.fileStarted to check the background queue ticket and catch errors - Change PlayerCore.fileStarted to have the background task queue a main thread task that will continue the process of stopping the player if it was waiting for the background task to finish - Change PlayerCore.findIdlePlayerCore to not choose an idle core if it's background task is still running These changes cause the player to not send a stop command to mpv until the background task has stopped. A mpv core will stop on its own when the end of a video is reached. For that reason these changes also cause the player to not send a quit command to mpv until the background task has stopped. These changes correct crashes that happens when the background task is still running when the mpv core is quitting. This can occur for example, when a user starts playing the wrong video and immediately quits IINA before the background task has a chance to finish.
0f18254
to
f72d224
Compare
This commit will: - Change the PlaybackInfo.state computed property to prevent additional inappropriate state transitions - Change PlayerCore.sendOSD to not show messages unless the player is active to prevent an unreported crash - Change MPVController.readEvents to stop once a MPV_EVENT_SHUTDOWN has been processed - Change the fileLoaded and fileStarted PlayerCore methods to do nothing if the player state is not active - Change the logger subsystem for AutoFileMatcher to include the player identifier - Change the names of the PlayerCore dispatch queues to include the player identifier - Move TicketExpiredError from AutoFileMatcher to PlayerCore - Add a checkTicket method to PlayerCore - Change more AutoFileMatcher methods to check the ticket and throw errors - Change AutoFileMatcher.startMatching to rethrow errors - Change PlayerCore.fileStarted to check the background queue ticket and catch errors - Change PlayerCore.fileStarted to have the background task queue a main thread task that will continue the process of stopping the player if it was waiting for the background task to finish - Change PlayerCore.findIdlePlayerCore to not choose an idle core if it's background task is still running These changes cause the player to not send a stop command to mpv until the background task has stopped. A mpv core will stop on its own when the end of a video is reached. For that reason these changes also cause the player to not send a quit command to mpv until the background task has stopped. These changes correct crashes that happens when the background task is still running when the mpv core is quitting. This can occur for example, when a user starts playing the wrong video and immediately quits IINA before the background task has a chance to finish.
This commit will:
active
computed property inPlayerState
to not consider the stopping state as activePlaybackInfo.state
computed property to prevent additional inappropriate state transitionsPlayerCore.sendOSD
to not show messages unless the player is active to prevent an unreported crashMPVController.readEvents
to stop once aMPV_EVENT_SHUTDOWN
has been processedfileLoaded
andfileStarted
PlayerCore
methods to do nothing if the player state is not activeAutoFileMatcher
to include the player identifierPlayerCore
dispatch queues to include the player identifierTicketExpiredError
fromAutoFileMatcher
toPlayerCore
checkTicket
method toPlayerCore
AutoFileMatcher
methods to check the ticket and throw errorsAutoFileMatcher.startMatching
to rethrow errorsPlayerCore.fileStarted
to check the background queue ticket and catch errorsPlayerCore.fileStarted
to have the background task queue a main thread task that will continue the process of stopping the player if it was waiting for the background task to finishPlayerCore.findIdlePlayerCore
to not choose an idle core if it's background task is still runningThese changes cause the player to not send a stop command to mpv until the background task has stopped. A mpv core will stop on its own when the end of a video is reached. For that reason these changes also cause the player to not send a quit command to mpv until the background task has stopped. These changes correct crashes that happens when the background task is still running when the mpv core is quitting. This can occur for example, when a user starts playing the wrong video and immediately quits IINA before the background task has a chance to finish.
Description: