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:
Thomas Adamcik 2015-10-06 22:45:06 +02:00
parent 1ca548ece7
commit 0169ce7cad
2 changed files with 19 additions and 1 deletions

View File

@ -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())

View File

@ -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)