user1382306
user1382306

Reputation:

does .push() fail or wait while locked in this code example?

Wow, I wish I'd known about this page https://github.com/zaphoyd/websocketpp/blob/experimental/examples/broadcast_server/broadcast_server.cpp written by my c++ hero https://stackoverflow.com/users/1047661/zaphoyd before I started my c++ websocket adventure. Tons of lessons there.

If I'm reading it correctly (that's a stretch lol), it looks like connections and message sends & receipts are all handled in a single thread (can't wait til he "multi-threads" that or whatever it's called since he says in this basic example http://www.zaphoyd.com/websocketpp/manual/common-patterns/server-initiated-messages that WebSocket++ handlers block core networking functions. While this program is running its send loop in on_message, no new connections are being processed and no new messages are being received.) and a separate thread boost::thread(bind(&broadcast_server::process_messages,&server)); is set up to actually process the messages while the primary websocket++ thread simply adds to the queue the necessary information.

Please clear up my lack of knowledge: will the .push() fail if it happens at the same time as this section of code in the link

while(m_actions.empty()) {
    m_action_cond.wait(lock);
}

action a = m_actions.front();
m_actions.pop();

lock.unlock();

or does the .push() simply wait for the lock to be released?

Upvotes: 0

Views: 263

Answers (1)

Stephen Lin
Stephen Lin

Reputation: 5540

std::queue<T> doesn't know anything about threading on its own; however, in the code linked, all calls to push are wrapped like the following:

    boost::unique_lock<boost::mutex> lock(m_action_lock);
    //std::cout << "on_open" << std::endl;
    m_actions.push(action(SUBSCRIBE,hdl));
    lock.unlock();
    m_action_cond.notify_one();

The constructor of the lock object above internally calls m_action_lock.lock() which blocks until the lock is released.

Note that m_action_cond.wait(lock), in the code you pasted in your question, unlocks the lock while waiting for the condition, and acquires the lock again after it has been woken up (either due to a signal from another thread, or possibly spuriously), so it doesn't prevent the producer (the one doing the push) thread from acquiring the lock while it's waiting: it's only between waking up and the call to lock.unlock() that blocking occurs.

Upvotes: 1

Related Questions