c++multithreadingwinapiwaitforsingleobject

WaitForSingleObject Deadlock


Some background if you're interested, otherwise you can go right to the question at the bottom:

I am running into an issue where i have an infinite while loop with two if conditions checking for two event object states to become signaled.

while(1)
{
    if(DAQ_Comm_Server::usb_detect_flag == false)
    {
        if(WaitForSingleObject(USB_PHY_CONN,INFINITE) == WAIT_OBJECT_0)
        {
            DAQ_Comm_Server::usb_detect_flag = true;
        }
    }

    if(DAQ_Comm_Server::usb_detect_flag == true)
    {
        if(WaitForSingleObject(USB_PHY_DISCONN, INFINITE) == NULL)
        {
            DAQ_Comm_Server::usb_detect_flag = false;
        }   
    }
}

The event objects USB_PHY_CONN and USB_PHY_DISCONN are being set in my OS/BSP USB driver code where it will detect the hardware USB connection and proceed to use SetEvent() to set the corresponding event object.

Reading the documentation for WaitForSingleObject(), it does not explicitly state that it must be used inside a thread, although after reading it multiple times I feel like it is implied, but im not 100% sure.

The issue I am having is the first time the code runs through the while loop (i.e., usb is initially disconnected, then connected, and disconnected), my system runs fine and does not hang. However, Upon reconnecting the USB, my system freezes. My device becomes unresponsive/UI freezes and the code is lost.

Now, the moment i kill the process where I have the above code in, everything starts back up and continues to run fine. I did some reading and it seems that WaitForSingleObject() runs the risk of a possible deadlock, but I also noticed that it was always in terms of threads.

My question is, does WaitForSingleObject() HAVE to be used in a thread? If i use it in an infinite loop in a main, does this run a high risk of a deadlock/system freezing?

Note: This is a platform builder windows embedded CE 7 project with VS2008.


Solution

  • You can't execute code outside a thread! There's a "main" thread which starts at main but that too is a thread like any other.

    That said, a deadlock requires 2 threads and 2 synchronization points. One thread locks A, another thread locks B, and then both threads block as they try to acquire the other lock.

    This can be solved absolutely by having a lock order. If lock A is always locked before B, then no deadlock can occur between threads that have A and other threads that have lock B.

    A more theoretical approach proves that the problem is a cycle in the lock graph. The cycle A<=>B is the simplest cycle of length 2. A->B->C->A can deadlock as well. A Directed Acyclic Graph of lock orders corresponds to a deadlock-free program.