void service_dispatch (service *srv, zmsg *msg) { assert (srv); if (msg) { // Queue message if any srv->m_requests.push_back(msg); } purge_workers (); while (! srv->m_waiting.empty() && ! srv->m_requests.empty()) { // Choose the most recently seen idle worker; others might be about to expire std::list<worker*>::iterator wrk = srv->m_waiting.begin(); std::list<worker*>::iterator next = wrk; for (++next; next != srv->m_waiting.end(); ++next) { if ((*next)->m_expiry > (*wrk)->m_expiry) wrk = next; } zmsg *msg = srv->m_requests.front(); srv->m_requests.pop_front(); worker_send (*wrk, (char*)MDPW_REQUEST, "", msg); for(std::vector<worker*>::iterator it = m_waiting.begin(); it != m_waiting.end(); it++) { if (*it == *wrk) { it = m_waiting.erase(it)-1; } } srv->m_waiting.erase(wrk); delete msg; } }
void worker_delete (worker *&wrk, int disconnect) { assert (wrk); if (disconnect) { worker_send (wrk, (char*)MDPW_DISCONNECT, "", NULL); } if (wrk->m_service) { for(std::list<worker*>::iterator it = wrk->m_service->m_waiting.begin(); it != wrk->m_service->m_waiting.end();) { if (*it == wrk) { it = wrk->m_service->m_waiting.erase(it); } else { ++it; } } wrk->m_service->m_workers--; } for(std::vector<worker*>::iterator it = m_waiting.begin(); it != m_waiting.end(); it++) { if (*it == wrk) { it = m_waiting.erase(it)-1; } } // This implicitly calls the worker destructor m_workers.erase(wrk->m_identity); delete wrk; }
void* worker_tx_thread(void *arg) { worker_t *w = (worker_t*)arg; monitor_t *m = w->m; while(1) { pthread_mutex_lock(&w->private_tx_buff_mx); while(w->private_tx_buff == NULL) { pthread_cond_wait(&w->tx_ready, &w->private_tx_buff_mx); } /* timestamp(); */ /* printf("[%d] - tx thread wakeup\n", w->id); */ /* dump_packet(w->private_tx_buff); */ if(w->private_tx_buff->type == MPUDP_CONFIG) { worker_send(w, w->private_tx_buff, SEND_BCAST); } else if(w->private_tx_buff->type == MPUDP_DATA) { worker_send(w, w->private_tx_buff, SEND_UCAST); /* dump_packet(w->private_tx_buff); */ } else { // we are sending ACK worker_send(w, w->private_tx_buff, SEND_UCAST); } /* usleep(w->choke); */ /* sleep(1); */ w->private_tx_buff = NULL; pthread_cond_broadcast(&w->tx_empty); pthread_cond_broadcast(&m->tx_has_data); pthread_mutex_unlock(&w->private_tx_buff_mx); /* printf("[%d] - tx thread finished and unlocked private\n", w->id); */ } }
// Get and process messages forever or until interrupted void start_brokering() { while (!s_interrupted) { zmq::pollitem_t items [] = { { *m_socket, 0, ZMQ_POLLIN, 0 } }; zmq::poll (items, 1, HEARTBEAT_INTERVAL); // Process next input message, if any if (items [0].revents & ZMQ_POLLIN) { zmsg *msg = new zmsg(*m_socket); if (m_verbose) { s_console ("I: received message:"); msg->dump (); } std::string sender = std::string((char*)msg->pop_front ().c_str()); msg->pop_front (); //empty message std::string header = std::string((char*)msg->pop_front ().c_str()); // std::cout << "sbrok, sender: "<< sender << std::endl; // std::cout << "sbrok, header: "<< header << std::endl; // std::cout << "msg size: " << msg->parts() << std::endl; // msg->dump(); if (header.compare(MDPC_CLIENT) == 0) { client_process (sender, msg); } else if (header.compare(MDPW_WORKER) == 0) { worker_process (sender, msg); } else { s_console ("E: invalid message:"); msg->dump (); delete msg; } } // Disconnect and delete any expired workers // Send heartbeats to idle workers if needed if (s_clock () > m_heartbeat_at) { purge_workers (); for (std::vector<worker*>::iterator it = m_waiting.begin(); it != m_waiting.end() && (*it)!=0; it++) { worker_send (*it, (char*)MDPW_HEARTBEAT, "", NULL); } m_heartbeat_at = s_clock () + HEARTBEAT_INTERVAL; } } }