Reputation:
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
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