Qball's Weblog
Corner case crasher that I could hardly imagine
In gmpc I have a function “process_itterate” this handles (in idle time) the process_queue. (It does this by calling plugins (async))
process_itterates calles it self via g_idle_add() after a item is fully processed. if it is called and process_queue is empty , it stops.
when a new item is injected when process_queue is empty, process_queue is also called via g_idle_add.
Now the crasher occured when:
process_queue emptied it queue and called *g_idle_add (call 1)
*
Directly after that a new query was placed, this sees an empty queue, and also calls *g_idle_add (call 2)
*
Then
call1 is handled
directly after that *call2 *is handled.
causing the same item in the queue being processed, leading to a crash.
The window of failure is _very very_ tiny. process_itterate must just have emptied it queue and called it self, and between it calling g_idle_add and the handling of that call a new item has to be inserted.
This took me over a week and many very late hours to figure out. (as debugging stuff like this with gdb is near impossible, as idle calls screw up your backtrace).
The fix, a single line.
Make process_itterate not call itself (for the last time) when the queue is empty.