Esempio n. 1
0
job
make_job_with_id(unsigned int pri, unsigned int delay, unsigned int ttr,
                 int body_size, tube tube, unsigned long long id)
{
    job j;

    j = allocate_job(body_size);
    if (!j) return twarnx("OOM"), (job) 0;

    if (id) {
        j->id = id;
        if (id >= next_id) next_id = id + 1;
    } else {
        j->id = next_id++;
    }
    j->pri = pri;
    j->delay = delay;
    j->ttr = ttr;

    store_job(j);

    TUBE_ASSIGN(j->tube, tube);

    return j;
}
Esempio n. 2
0
//=============================================================================
int Multiplexer::spin()
{
  fd_set fds_read; FD_ZERO(&fds_read);
  fd_set fds_write; FD_ZERO(&fds_write);
  fd_set fds_except; FD_ZERO(&fds_except);
  Date expiry = Date::now() + Time(m_latency);
  check_thread_pool();
  
  m_job_mutex.lock();

  // Add any new jobs into the jobs list
  m_new_mutex.lock();
  while (!m_jobs_new.empty()) {
    m_jobs.push_back(m_jobs_new.front());
    m_jobs_new.pop_front();
    expiry = Date::now();
  }
  m_new_mutex.unlock();
  
  // Return and exit if there are no jobs
  int num = m_jobs.size();
  if (num == 0) {
    m_job_mutex.unlock();
    return -1;
  }

  // Find jobs to run
  int num_added=0;
  int maxfd=m_wakeup[0];
  FD_SET(m_wakeup[0],&fds_read); // Add wakeup socket
  JobList::iterator it;
  for (it = m_jobs.begin(); it != m_jobs.end(); ++it) {
    Job* job = *it;
    int mask = 0;
    if (job->prepare(expiry, mask)) {
      int fd = job->get_fd();
      if (fd >= 0) {
        ++num_added;
        if (0 != (mask & (1<<Stream::Readable))) FD_SET(fd,&fds_read);
        if (0 != (mask & (1<<Stream::Writeable))) FD_SET(fd,&fds_write);
        FD_SET(fd,&fds_except);
	maxfd = std::max(maxfd,fd);
      }
    }
  }

  m_job_mutex.unlock();

  if (num_added == 0) {
    return 0;
  }

  timeval timeout; (expiry - Date::now()).get_timeval(timeout);
  if (timeout.tv_sec < 0 || timeout.tv_usec < 0) {
    timeout.tv_sec = 0; timeout.tv_usec = 0;
  }
  
  // Make the select call
  if (select(maxfd+1, &fds_read, &fds_write, &fds_except, &timeout) < 0) {
    // Select returned an error or it was interrupted
    if (errno != EINTR) {
      DEBUG_LOG_ERRNO("select failed");
    }
    
  } else {

    Date start = Date::now();
    
    // Select succeeded, decode events and allocate jobs
    for (it = m_jobs.begin(); it != m_jobs.end(); ++it) {
      Job* job = *it;
      int events = 0;
      int fd = job->get_fd();
      if (fd >= 0) {
        events |= (FD_ISSET(fd,&fds_read) ? (1<<Stream::Readable) : 0);
        events |= (FD_ISSET(fd,&fds_write) ? (1<<Stream::Writeable) : 0);
      }
      if (job->ready(events)) {
        allocate_job(job);
        ++m_jobs_run;
      }
    }

    update_stats(Date::now() - start);
    
    // Read from the wakeup socket to clear
    if (FD_ISSET(m_wakeup[0],&fds_read)) {
      char buffer[16];
      recv(m_wakeup[0],buffer,16,0);
    }
  }

  // Purge jobs
  m_job_mutex.lock();
  for (it = m_jobs.begin(); it != m_jobs.end(); ) {
    Job* job = *it;
    if (job->get_state() == Job::Purge) {
      it = m_jobs.erase(it);
      delete job;
    } else {
      it++;
    }
  }

  m_end_condition.signal();
  m_job_mutex.unlock();
    
  return 0;
}