Exemplo n.º 1
0
static 
void 
server_cleanup(
    struct server* srv_ptr
    ) 
{
  assert(srv_ptr);

  /*
   * Fallthrough is intended.
   */
  switch (srv_ptr->sv_rollback) {
    case 5 :
      for (long i = 0; i < srv_ptr->sv_worker_count; ++i) {
        worker_thread_destroy(srv_ptr->sv_workers[i]);
      }
      srv_ptr->sv_allocator->al_mem_release(srv_ptr->sv_allocator,
                                            srv_ptr->sv_workers);

    case 4 :
      HANDLE_EINTR_ON_SYSCALL(close(srv_ptr->sv_threadrdy_eventfds));

    case 3 :
      HANDLE_EINTR_ON_SYSCALL(close(srv_ptr->sv_sigfds));

    case 2 :
      HANDLE_EINTR_ON_SYSCALL(close(srv_ptr->sv_epollfd));

    case 1 :
      HANDLE_EINTR_ON_SYSCALL(close(srv_ptr->sv_acceptfd));

    default :
      break;
  }
}
Exemplo n.º 2
0
void prm_destroy()
{
	DEBUG("PRM exiting\n");
	worker_thread_stop(&prm_thread);
	worker_thread_destroy(&prm_thread);
	assert(queue_size(prm_queue) == 0);
	pthread_mutex_destroy(&prm_mutex);
	pthread_mutex_destroy(&prm_queue_mutex);
	pthread_cond_destroy(&prm_queue_condvar);
	pthread_cond_destroy(&prm_condvar);
	queue_destroy(prm_queue);
	DEBUG("PRM exited\n");
}
Exemplo n.º 3
0
static 
int 
server_init(
    struct server* p_srv
    )
{
  assert(p_srv);
  memset(p_srv, 0, sizeof(*p_srv));

  p_srv->sv_allocator = allocator_handle;
  p_srv->sv_quitflag = 0;
  p_srv->sv_acceptfd = create_server_socket();
  if (-1 == p_srv->sv_acceptfd) {
    return -1;
  }
  /*
   * Level 1 - accept socket created.
   */
  ++p_srv->sv_rollback;

  p_srv->sv_epollfd = epoll_create(kMaxEpollCompletionEntries);
  if (-1 == p_srv->sv_epollfd) {
    return -1;
  }
  /*
   * Level 2 - epoll descriptor allocated.
   */
  ++p_srv->sv_rollback;

  /*
   * Block SIGINT and create a signal descriptor to receive it via epoll.
   */
  sigset_t sig_mask;
  sigemptyset(&sig_mask);
  if (-1 == sigaddset(&sig_mask, SIGINT)) {
    return -1;
  }
  if (-1 == sigprocmask(SIG_BLOCK, &sig_mask, NULL)) {
    return -1;
  }
  p_srv->sv_sigfds = signalfd(-1, &sig_mask, SFD_NONBLOCK);
  if (-1 == p_srv->sv_sigfds) {
    return -1;
  }
  /*
   * Level 3 - signal descriptor for SIGINT allocated.
   */
  ++p_srv->sv_rollback;

  /*
   * Add termination signal and accept socket to epoll interface.
   */
  if (-1 == add_fd_to_epoll(p_srv->sv_epollfd,
                            p_srv->sv_sigfds,
                            EPOLLIN | EPOLLET,
                            kDataTypeFD,
                            p_srv->sv_sigfds)) {
    return -1;
  }

  if (-1 == add_fd_to_epoll(p_srv->sv_epollfd,
                            p_srv->sv_acceptfd,
                            EPOLLIN | EPOLLET | EPOLLRDHUP,
                            kDataTypeFD,
                            p_srv->sv_acceptfd)) {
    return -1;
  }

  p_srv->sv_threadrdy_eventfds = eventfd(0, 0);
  if (p_srv->sv_threadrdy_eventfds == -1) {
    D_FUNCFAIL_ERRNO(eventfd);
    return -1;
  }
  /*
   * Level 4 - thread notification event created.
   */
  ++p_srv->sv_rollback;

  /*
   * Get number of available processors. The number of spawned threads is
   * nr_processors * thread_to_proc_ratio.
   */
  long nr_procs = sysconf(_SC_NPROCESSORS_ONLN);
  if (nr_procs == -1) {
    D_FUNCFAIL_ERRNO(sysconf);
    return -1;
  }
  D_FMTSTRING("Online processors %d, will spawn %d threads.",
              nr_procs, nr_procs);

  p_srv->sv_workers = p_srv->sv_allocator->al_mem_alloc(
      p_srv->sv_allocator, (sizeof(struct worker_thread*) * nr_procs));
  if (!p_srv->sv_workers) {
    D_FMTSTRING("Out of memory!");
    return -1;
  }
  /*
   * Level 5 - memory for worker thread data allocated.
   */
  ++p_srv->sv_rollback;
  memset(p_srv->sv_workers, 0, sizeof(struct worker_thread*) * nr_procs);

  /*
   * Initialize data and start worker threads.
   */
  for (long l = 0; l < nr_procs; ++l) {
    char thread_msgqueue[NAME_MAX];
    snprintf(thread_msgqueue, sizeof(thread_msgqueue) - 1, 
             "/__msgqueue_thread_%d__", (int) l);
    struct worker_thread* current = worker_thread_create(thread_msgqueue, 
                                                         p_srv->sv_allocator);
    if (current) {
      if (worker_thread_start(p_srv, current, NULL) == 0) {
        /*
         * Thread successfully initialized, add it to list.
         */
        p_srv->sv_workers[p_srv->sv_worker_count++] = current;
      } else {
        /*
         * Cleanup thread data since pthread_create() failed.
         */
        worker_thread_destroy(current);
      }
    }
  }
  if (!p_srv->sv_worker_count) {
    D_FMTSTRING("Fatal : failed to initialize at least one worker thread!");
    return -1;
  }

  D_FMTSTRING("Started a total of %d worker threads", p_srv->sv_worker_count);
  /*
   * Server is up and running.
   */
  return 0;
}