[PATCH] ogg123 hangs with certain OGG files
Version: vorbis tools v1.4.0
System: OpenSUSE 12.1 Linux 3.1.10 32 bit single CPU without hyperthreading.
Reproducibility: Reproducible every time
Sending a SIGINT to Ogg123 while it is playing any of certain ogg files makes it hang. With some of those files, ogg123 hangs when it has finished playing the file, but with the others it seems to hang somewhere in the middle of playing the file. Each of the attached ogg files taken from ManaPlus (except reminder.ogg) will make ogg123 hang. When it hangs, it will not print any more output or respond to anything. This hang happens both with the ogg123 from the OpenSUSE vorbis-tools-1.4.0 package and the ogg123 I compiled from the vorbis-tools source code myself.
I compiled ogg123 with the DEBUG_BUFFER macro defined, ran it, and looked through the resulting log file. From the information in that log combined with using GDB, I found that ogg123 was hanging in the pthread_cond_wait system call waiting for the other thread to signal it, but the other thread had already exited.
The attached patch fixes this by turning the conditional wait into a timed wait to receive a signal or 1 second to pass. I've only tried this patch on a 32-bit machine, so it might not work on a 64bit machine. This change also makes ogg123 start playing the next file when it is given a SIGINT instead of uselessly freezing on the first file, which it does when starting "ogg123 *.ogg" with the unpatched ogg123 in a directory full of ogg files. To reproduce on Linux:
- run "ogg123 attention.ogg" (or another ogg file that hangs it)
- Wait for ogg123 to show the bar that shows how much of the file it has played.
- Send ogg123 a SIGINT using Ctrl+C before the bar disappears.
- ogg123 will hang. Reproducing under GDB:
- run "gdb --args ogg123 attention.ogg"
- type "handle SIGINT nostop print pass"; answer Y
- type "run".
- Wait for ogg123 to show the bar that shows how much of the file it has played.
- Press Control+C before that bar disappears. Ogg123 will now hang.
- Press Control+Z to get back to the GDB prompt.