/** Fawkes network thread loop. * The thread loop will check all clients for their alivness and dead * clients are removed. Then inbound messages are processed and dispatched * properly to registered handlers. Then the thread waits for a new event * to happen (event emitting threads need to wakeup this thread!). */ void FawkesNetworkServerThread::loop() { std::list<unsigned int> dead_clients; clients.lock(); // check for dead clients for (cit = clients.begin(); cit != clients.end(); ++cit) { if ( ! cit->second->alive() ) { dead_clients.push_back(cit->first); } } clients.unlock(); std::list<unsigned int>::iterator dci; for (dci = dead_clients.begin(); dci != dead_clients.end(); ++dci) { const unsigned int clid = *dci; { MutexLocker handlers_lock(handlers.mutex()); for (hit = handlers.begin(); hit != handlers.end(); ++hit) { (*hit).second->client_disconnected(clid); } } { MutexLocker clients_lock(clients.mutex()); if ( thread_collector ) { thread_collector->remove(clients[clid]); } else { clients[clid]->cancel(); clients[clid]->join(); } usleep(5000); delete clients[clid]; clients.erase(clid); } } // dispatch messages inbound_messages->lock(); while ( ! inbound_messages->empty() ) { FawkesNetworkMessage *m = inbound_messages->front(); { MutexLocker handlers_lock(handlers.mutex()); if ( handlers.find(m->cid()) != handlers.end()) { handlers[m->cid()]->handle_network_message(m); } } m->unref(); inbound_messages->pop(); } inbound_messages->unlock(); }
/** Receive and process messages. */ void recv() { std::list<unsigned int> wakeup_list; try { FawkesNetworkTransceiver::recv(__s, __inbound_msgq); MutexLocker lock(__recv_mutex); __inbound_msgq->lock(); while ( ! __inbound_msgq->empty() ) { FawkesNetworkMessage *m = __inbound_msgq->front(); wakeup_list.push_back(m->cid()); __parent->dispatch_message(m); m->unref(); __inbound_msgq->pop(); } __inbound_msgq->unlock(); lock.unlock(); wakeup_list.sort(); wakeup_list.unique(); for (std::list<unsigned int>::iterator i = wakeup_list.begin(); i != wakeup_list.end(); ++i) { __parent->wake_handlers(*i); } } catch (ConnectionDiedException &e) { throw; } }