mopidy
mopidy copied to clipboard
Make sure GStreamer callbacks to audio actors are race free
Sometimes the following is written to stdout/stderr of Mopidy:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/mopidy/audio/actor.py", line 234, in on_message
self.on_playbin_state_changed(*msg.parse_state_changed())
File "/usr/local/lib/python2.7/dist-packages/mopidy/audio/actor.py", line 283, in on_playbin_state_changed
target_state = _GST_STATE_MAPPING[self._audio._target_state]
KeyError: <enum GST_STATE_READY of type GstState>
Probably this has no noticeable effect on playback (at least I have not correlated it to any issues). May be this error makes sense to @jodal or somebody else who is maintaining Mopidy.
Could you try running with mopidy -o loglevels/mopidy.audio.gst=DEBUG
to get some more logs. I have a fairly good idea of what is happening, but can't seem to reproduce it.
Oh and what type of URI was this, web stream, local file, spotify, ...?
Never mind, I think I've understood what is happening here. Short version is that I think we have a race condition, but as you noted it should be mostly harmless.
- Target state is for instance
PLAYING
-
on_playbin_state_changed(PAUSED, PLAYING, None)
gets called indicating that we are done with the switch. - Something else comes along and changes the track, which triggers
prepare_change()
which in turn causes_target_state
to be set toREADY
- We get a traceback when line 283 gets excuted
Reason this happens is that the on_playbin_state_changed
is running from a GStreamer thread so it can be interleaved with the audio actor. So we need to look at all the callbacks we get from GStreamer and make sure that we use instance attributes safely.