On 07/06/2022 07:23, Daniel Pirkl wrote:
> (gdb) print *workQueue,front ()
> $7 = {active = false, rect = {tl = {x = 288, y = 320}, br = {x = 320, y =
> 324}}, encoding = 7, decoder = 0x127860, server = 0xf488c, pb = 0x124810,
> bufferStream = 0xfc618, affectedRegion = {rgn = 0x1afda8}}
>
That entry looks completely normal. I'm staring at the code, and I'm not
seeing any way where that entry can be left on the queue.
I can only think of two scenarios happening:
a) The queue is empty, all threads idle, that last rectangle is read by
the main thread, put on the queue, and somehow it fails to wake a thread
to consume it
b) This entry is blocked by another entry, which means at least one
thread is busy doing stuff. Once that thread finishes processing the
blocking entry, that previously blocked entry should be grabbed, but
isn't for some reason.
Scenario a) shouldn't be possible, as the main thread holds the queue
lock when adding the new entry, and keeps the lock whilst waking a
thread. So the entry and the signal should be safely paired.
On the other side, the threads only stop and wait for the signal after
holding the queue lock and checking if there are any entries. The lock
guarantees that this is done in a way where the signal cannot be missed.
Scenario b) should also not be possible. When the thread handling the
blocking rect finishes, it will both wake all other threads, and look at
the queue itself. The remaining entry is then at the front of the queue,
and not active. So the expected result is that the same thread will grab
the entry. And even if it doesn't the three other threads should also
look at the queue and grab it.
Your workaround suggests that scenario a) is happening, as that's where
it will have the most effect. But I don't see how that's possible,
barring some system level (i.e. kernel or glibc) bug.
I'm not sure how to proceed here. Normally, some more diagnostic info
would be added (like prints). But that doesn't seem feasible, given how
long it takes to provoke the issue. :/