core: Make sure the about-to-finish callback gets run in the actor.
When about to finish gets called we are running in some GStreamer thread. Our audio code then calls the shim core callback which is responsible for transferring our execution to the core actor thread and waiting for the response. From this point we do normal actor calls to the backend(s) which in turn call into the audio actor. Since the initial audio code that was called is outside the actor this should never deadlock due to this loop.
This commit is contained in:
parent
1ca548ece7
commit
0169ce7cad
@ -27,7 +27,8 @@ class PlaybackController(object):
|
||||
self._pending_tl_track = None
|
||||
|
||||
if self._audio:
|
||||
self._audio.set_about_to_finish_callback(self._on_about_to_finish)
|
||||
self._audio.set_about_to_finish_callback(
|
||||
self._on_about_to_finish_callback)
|
||||
|
||||
def _get_backend(self, tl_track):
|
||||
if tl_track is None:
|
||||
@ -206,6 +207,19 @@ class PlaybackController(object):
|
||||
self._pending_tl_track = None
|
||||
self._trigger_track_playback_started()
|
||||
|
||||
def _on_about_to_finish_callback(self):
|
||||
"""Callback that performs a blocking actor call to the real callback.
|
||||
|
||||
This is passed to audio, which is allowed to call this code from the
|
||||
audio thread. We pass execution into the core actor to ensure that
|
||||
there is no unsafe access of state in core. This must block until
|
||||
we get a response.
|
||||
"""
|
||||
self.core.actor_ref.ask({
|
||||
'command': 'pykka_call', 'args': tuple(), 'kwargs': {},
|
||||
'attr_path': ('playback', '_on_about_to_finish'),
|
||||
})
|
||||
|
||||
def _on_about_to_finish(self):
|
||||
self._trigger_track_playback_ended(self.get_time_position())
|
||||
|
||||
|
||||
@ -40,6 +40,10 @@ class BaseTest(unittest.TestCase):
|
||||
audio=self.audio, backends=[self.backend], config=self.config)
|
||||
self.playback = self.core.playback
|
||||
|
||||
# We don't have a core actor running, so call about to finish directly.
|
||||
self.audio.set_about_to_finish_callback(
|
||||
self.playback._on_about_to_finish)
|
||||
|
||||
with deprecation.ignore('core.tracklist.add:tracks_arg'):
|
||||
self.core.tracklist.add(self.tracks)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user