From: Christer P. <pa...@no...> - 2001-12-24 04:19:26
|
Christer Palm wrote: > Hello! > Has anyone else experienced problems with X hanging after a while when > seeking? > I have now debugged this for (quite) a while, and it appears that there are several conditions under which xine can hang when pounding it with seek requests. The situation that occurs most often in my test case (just playing a simple mp3 file), however, seems to be a race condition related to the audio output thread. 1) When fiddling with the seek "knob", xine_play() is called repedeately. 2) xine_play() shuts down the whole thing by calling the demuxers stop() method. The demuxer stop() method immediately shuts down the demuxer thread, and then posts an asyncronous request to the decoder to stop its output driver. This is done by allocating a buffer off the decoder buffer pool, fill it in with a BUF_CONTROL_END request and then post it on the decoders fifo. If there are no buffers available in the decoders buffer pool, the demuxer blocks until one is available. Otherwise, the stop() method immediately returns control to xine_play() without waiting for the output drivers to actually shut down. 3) xine_play() now restarts the demuxer by calling its start() method. Eventually, this will cause the decoder plugin to re-open the output driver by calling its open() method. 4) The output driver open() method checks to see if the output driver thread is already running. If it is, it just prints a warning message and returns. Now, sometimes, step 4 is reached before the output driver has actually shut down. So the output driver open() method will just return thinking that the output driver thread is already running. This is evident from "audio_out: pthread already running!" messages on stdout. This causes audio to disappear. However, it also causes a domino effect on the whole thing; Since there is now no driver thread, there is no one to pick up the decoded frames from the output fifo. This will eventually cause the output fifo to fill up, which appears to cause the decoder to block. If the decoder blocks, there is no one to pick up stuff on the decoder fifo, so eventually that will also fill up. This will probably cause the demuxer to block, but even worse, it will also cause xine_play() to block in the demuxer stop() method. Since xine_play() is called from the GUI event handler, this will cause the GUI to hang! My problem right now is how to fix this properly... IMHO, this whole thing is a big mess that perhaps should be cleaned up a bit to avoid similar things from happening? My feeling is that this definitely is a 1.0 showstopper. Perhaps someone with a better understanding of the internal architecture could have a look at this? -- Christer Palm |