Wednesday, February 22, 2006

Thread synchronization errors

This is something that scares the hell out of me. Thread synchronization is perhaps one of the most subtle arts in our trade and I keep learning every day. The bottom line is that nothing is atomic and you should always consider the worst case scenario. Always play on the safe side - assume nothing.

My last bang on the wall was quite simple. At the very heart of all my products, both on the desktop and the device sides, lies a thread that reads all the messages and stores them in a queue. The device side is simpler - the queue is simply polled. But the desktop side is a bit more complex and requires signalling events. When a properly formed message arrives and is stored in the queue, a call to SetEvent is made to signal other threads of the availability of data.

Now, when I rewrote the code for the 2.0 versions of the products, I called SetEvent before adding the message to the queue. Access to the message queue is guarded by a critical section, as it should. It so happens that adding a message to the queue is a bit lengthy (requires memory allocation) and this meant that after firing the event any thread that would test the event before the message got to the queue would be in a strange situation: there's a signal telling me there's something on the queue but the queue is still empty...

The solution is obvious - raise the event after the message is added to the queue. Humpf...

No comments: