If I have thought this through correctly, a semaphore would be the ideal solution. The semaphore solution should allow multiple threads to consume events from the same queue. A semaphore will not block the boss thread.
// Worker thread...
WaitForSingleObject(hSem, INFINITE); /* Blocks if semaphore count is zero.
Decrements semaphore count when thread is released. */
my_work_item = myqueue.front();
>> A way to do this would be to create an event object for each worker thread. The thread can then use WaitForSingleObject() to enter a non-busy wait, and the boss thread can signal the event for the thread which it has work for. <<
// Boss thread...
hSem = CreateSemaphore(NULL, 0, LONG_MAX, NULL); /* Create semaphore with initial count of zero. */
// Add work item...
ReleaseSemaphore(hSem, 1, NULL); /* Increments semaphore count. */
Codeplug has previously posted a nice queue solution that uses an event. However, with this solution, you can only have one worker thread consuming events from each queue. This seems to be the model you are using, so shouldn't be a problem.
Using windows queues are another solution. However, these suffer serious security issues. Another process on the same desktop can post messages to your queue, even if it is running under a less priviliged user.
Multi-threading issues are notoriously easy to stuff up and notoriously hard to debug so good luck.