Esempio n. 1
0
/**
 * Clean up engine.
 *
 */
void
engine_cleanup(engine_type* engine)
{
    size_t i = 0;

    if (!engine) {
        return;
    }
    if (engine->workers && engine->config) {
        for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
            worker_cleanup(engine->workers[i]);
        }
        free(engine->workers);
    }
    if (engine->drudgers && engine->config) {
       for (i=0; i < (size_t) engine->config->num_signer_threads; i++) {
           worker_cleanup(engine->drudgers[i]);
       }
       free(engine->drudgers);
    }
    zonelist_cleanup(engine->zonelist);
    schedule_cleanup(engine->taskq);
    fifoq_cleanup(engine->signq);
    cmdhandler_cleanup(engine->cmdhandler);
    dnshandler_cleanup(engine->dnshandler);
    xfrhandler_cleanup(engine->xfrhandler);
    engine_config_cleanup(engine->config);
    lock_basic_destroy(&engine->signal_lock);
    lock_basic_off(&engine->signal_cond);
    free(engine);
}
Esempio n. 2
0
void *worker_run(void* userdata) {
  int num_events, flush_outbox;
  worker_t* self = userdata;
  ev_event_t *event;
  conn_t *conn;

  ev_init(&self->loop);
  ev_watch(&self->loop, self->conn_queue[0], EV_READABLE, self);
  ev_watch(&self->loop, self->msg_queue[0], EV_READABLE, NULL);

  while(self->running) {
    num_events = ev_poll(&self->loop);
    flush_outbox = 0;

    if (num_events == -1)
      continue;

    while (--num_events >= 0) {
      event = self->loop.fired[num_events];

      if (!event->fired)
        continue;

      if (!event->userdata) {
        if (event->fired & EV_READABLE)
          worker_flush_inbox(self);
        else
          flush_outbox = 1;

        continue;

      } else if (event->userdata == self) {
        worker_accept(self);
        continue;
      }

      conn = event->userdata;

      if (event->fired & EV_READABLE)
        if (conn_read(conn) == -1)
          continue;

      if (event->fired & EV_WRITEABLE)
        if (conn_write(conn) == -1)
          continue;

    }

    if (flush_outbox)
      worker_flush_outbox(self);
  }

  worker_cleanup(self);
  return NULL;
}
Esempio n. 3
0
/**
 * Clean up engine.
 *
 */
void
engine_cleanup(engine_type* engine)
{
    size_t i = 0;
    allocator_type* allocator;
    cond_basic_type signal_cond;
    lock_basic_type signal_lock;

    if (!engine) {
        return;
    }
    allocator = engine->allocator;
    signal_cond = engine->signal_cond;
    signal_lock = engine->signal_lock;

    if (engine->workers && engine->config) {
        for (i=0; i < (size_t) engine->config->num_worker_threads; i++) {
            worker_cleanup(engine->workers[i]);
        }
        allocator_deallocate(allocator, (void*) engine->workers);
    }
#if HAVE_DRUDGERS
    if (engine->drudgers && engine->config) {
       for (i=0; i < (size_t) engine->config->num_signer_threads; i++) {
           worker_cleanup(engine->drudgers[i]);
       }
        allocator_deallocate(allocator, (void*) engine->drudgers);
    }
#endif
    schedule_cleanup(engine->taskq);
    fifoq_cleanup(engine->signq);
    cmdhandler_cleanup(engine->cmdhandler);
    engine_config_cleanup(engine->config);
    allocator_deallocate(allocator, (void*) engine);

    lock_basic_destroy(&signal_lock);
    lock_basic_off(&signal_cond);
    allocator_cleanup(allocator);
    return;
}
Esempio n. 4
0
/*===========================================================================*
 *				sef_cb_lu_prepare			     *
 *===========================================================================*/
static int sef_cb_lu_prepare(int state)
{
/* This function is called to decide whether we can enter the given live
 * update state, and to prepare for such an update. If we are requested to
 * update to a request-free or protocol-free state, make sure there is no work
 * pending or being processed, and shut down all worker threads.
 */

  switch (state) {
  case SEF_LU_STATE_REQUEST_FREE:
  case SEF_LU_STATE_PROTOCOL_FREE:
	if (!worker_idle()) {
		printf("VFS: worker threads not idle, blocking update\n");
		break;
	}

	worker_cleanup();

	return OK;
  }

  return ENOTREADY;
}
Esempio n. 5
0
static void *worker_loop(Worker *t) {
    int i;
    enum worker_transaction_states state;

    lock();

    if (!heap_isempty(worker_ready_to_run)) {
        /* wait for older threads that are ready to run */
        worker_wake_up_next();
        heap_add(worker_ready_to_run, t);
        cond_wait(t->sleep);
    }

    /* let threads expire after a while so the thread pool can grow and shrink
     * as needed without hard limits on the number of threads */
    for (i = 0; i < THREAD_LIFETIME; i++) {
        if (i > 0) {
            /* wait in the pool for a request */
            worker_thread_pool = append_elt(worker_thread_pool, t);
            cond_wait(t->sleep);
        }
        worker_active++;

        /* initialize the exception handler and catch exceptions */
        do {
            state = setjmp(t->jmp);

            if (state == WORKER_BLOCKED) {
                /* wait for the blocking transaction to finish,
                 * then start over */
                worker_cleanup(t);
                worker_wake_up_next();
                cond_wait(t->sleep);
            } else if (state == WORKER_MULTISTEP) {
                /* wait for the next step in this grant/revoke op to wake us up
                 * with more work to do */
                if (DEBUG_VERBOSE)
                    printf("WORKER_MULTISTEP sleeping\n");
                worker_cleanup(t);
                t->func = NULL;
                t->arg = NULL;
                worker_wake_up_next();
                while (t->func == NULL)
                    cond_wait(t->sleep);
                if (DEBUG_VERBOSE)
                    printf("WORKER_MULTISTEP waking up\n");
            } else if (state == WORKER_RETRY) {
                worker_cleanup(t);
            }
        } while (state != WORKER_ZERO);

        /* process the request */
        if (t->func != NULL)
            t->func(t, t->arg);
        worker_cleanup(t);
        t->func = NULL;

        /* make anyone waiting on this transaction ready to run, then run one */
        if (!null(t->blocking)) {
            for ( ; !null(t->blocking); t->blocking = cdr(t->blocking))
                heap_add(worker_ready_to_run, car(t->blocking));
        }

        worker_active--;
        worker_wake_up_next();
    }

    unlock();

    return NULL;
}