Пример #1
0
void Network::addConnection(Connection::Ptr conn)
{
  DEBUG("Adding a file descriptor %d", conn->getFD());
  connections[conn->getFD()] = conn;
  FD_SET(conn->getFD(), &master_set);
  if (max_fd < conn->getFD()) {
    max_fd = conn->getFD();
  }
}
Пример #2
0
void Network::addToWriteQueue(Connection::Ptr conn){
  writequeue[conn->getFD()] = conn;
}
Пример #3
0
void Network::masterLoop()
{
  struct timeval tv;
  fd_set cur_set;
  halt = false;
  while (!halt) {

    //sleep(1);
    bool netstat = active;

    while(!timers.empty() && (timers.top()->getExpireTime() <= static_cast<uint64_t>(time(NULL)) ||
          !(timers.top()->isValid()))){
      TimerCallback::Ptr callback = timers.top();
      timers.pop();
      if(callback->isValid())
        callback->call();
    }
    if(timers.empty()){
      tv.tv_sec = 60;
      tv.tv_usec = 0;
    }else{
      tv.tv_sec = (timers.top()->getExpireTime() - time(NULL)) - 1;
      if(tv.tv_sec <= 0){
        tv.tv_sec = 0;
        tv.tv_usec = 200000;
      }else{
        tv.tv_usec = 0;
      }
    }
    fd_set write_set;
    FD_ZERO(&write_set);
    // Unsure what the macro FD_SET stands for, so I can't do for_each
    for(ConnMap::iterator itcurr = writequeue.begin();
        itcurr != writequeue.end(); ++itcurr){
      FD_SET(itcurr->first, &write_set);
    }

    cur_set = master_set;

    if (select(max_fd + 1, &cur_set, &write_set, NULL, &tv) > 0) {

      for(ConnMap::iterator itcurr = writequeue.begin();
          itcurr != writequeue.end(); ++itcurr){
        if(FD_ISSET(itcurr->first, &write_set)){
          Connection::Ptr conn = itcurr->second;
          writequeue.erase(itcurr);
          conn->processWrite();
          //use select again, don't check rest of list as it has changed.
          break;
        }
      }

      ConnMap::iterator itcurr;
      for (itcurr = connections.begin(); itcurr != connections.end(); itcurr++) {
        Connection::Ptr connection = itcurr->second;
        if (FD_ISSET(itcurr->first, &cur_set)) {
          connection->process();
        }
        if (connection->getStatus() == Connection::DISCONNECTED) {
          INFO("Closed connection %d", connection->getFD());
          removeConnection(itcurr->first);
          //use select again, don't check rest of list as it has changed.
          break;
        }
      }

    }

    //advertiser->poll();

    if(netstat != active && active == false){
      for_each_key( connections.begin(), connections.end(), boost::bind( &Network::removeConnection, this, _1 ) );
      DEBUG("Network really stopped");
    }
  }
}