Is this blocking queue implementation safe?

I am trying to implement a queue that blocks the Pop operation if it is empty, and unlocks as soon as a new item is clicked. I'm afraid that I might have some kind of race condition; I tried to look at some other implementations, but most of them were found in .NET, and the few C ++ I found were too dependent on other library classes.

template <class Element>
class BlockingQueue{
    DRA::CommonCpp::CCriticalSection    m_csQueue;
    DRA::CommonCpp::CEvent              m_eElementPushed;
    std::queue<Element>                 m_Queue;
public:
    void Push( Element newElement ){
        CGuard g( m_csQueue );
        m_Queue.push( newElement );
        m_eElementPushed.set();
    }
    Element Pop(){
        {//RAII block
            CGuard g( m_csQueue );
            bool wait = m_Queue.empty();
        }
        if( wait )
            m_eElementPushed.wait();
        Element first;
        {//RAII block
            CGuard g( m_csQueue );
            first = m_Queue.front();
            m_Queue.pop();
        }
        return first;
    }
};

Some explanation is required:

  • CCriticalSection is the shell for the critical Windows partition, the Enter and Leave methods are private, and CGuard is his only friend
  • CGuard is the RAII shell for CCriticalSection, enters the critical section of the constructor, leaves it on the destructor
  • CEvent is a wrapper for a Windows event, wait uses the WaitForSingleObject function
  • , , .
  • Boost, Windows ( CEvent CGuard)

, Pop() - . , , ?

UPDATE. Visual Studio 2010 (.NET 4.0), unbounded_buffer, ++. , , (Chesire Cat), .

+5
2

:

    {//RAII block
        CGuard g( m_csQueue );
        bool wait = m_Queue.empty();
    }
    /// BOOM! Other thread ninja-Pop()s an item.
    if( wait )
        m_eElementPushed.wait();

BOOM. , ( if). front pop .

+9

, Windows. .

Boost - Boost , .

+4

All Articles