示例#1
0
rstatus_t
thread_init(struct event_base *main_base)
{
    rstatus_t status;
    err_t err;
    int nworkers = settings.num_workers;
    struct thread_worker *dispatcher;
    int i;

    init_count = 0;
    pthread_mutex_init(&init_lock, NULL);
    pthread_cond_init(&init_cond, NULL);

    last_thread = -1;

    /* dispatcher takes the extra (last) slice of thread descriptor */
    threads = mc_zalloc(sizeof(*threads) * (1 + nworkers));
    if (threads == NULL) {
        return MC_ENOMEM;
    }
    /* keep data of dispatcher close to worker threads for easy aggregation */
    dispatcher = &threads[nworkers];

    /* create keys for common members of thread_worker. */
    err = pthread_key_create(&keys.stats_mutex, NULL);
    if (err != 0) {
        log_error("pthread key create failed: %s", strerror(err));
        return MC_ERROR;
    }

    err = pthread_key_create(&keys.stats_thread, NULL);
    if (err != 0) {
        log_error("pthread key create failed: %s", strerror(err));
        return MC_ERROR;
    }

    err = pthread_key_create(&keys.stats_slabs, NULL);
    if (err != 0) {
        log_error("pthread key create failed: %s", strerror(err));
        return MC_ERROR;
    }

    err = pthread_key_create(&keys.kbuf, NULL);
    if (err != 0) {
        log_error("pthread key create failed: %s", strerror(err));
        return MC_ERROR;
    }

    dispatcher->base = main_base;
    dispatcher->tid = pthread_self();

    status = thread_setup_stats(dispatcher);
    if (status != MC_OK) {
        return status;
    }

    status = thread_setkeys(dispatcher);
    if (status != MC_OK) {
        return status;
    }

    for (i = 0; i < nworkers; i++) {
        int fds[2];
        status = pipe(fds);
        if (status < 0) {
            log_error("pipe failed: %s", strerror(errno));
            return status;
        }

        threads[i].notify_receive_fd = fds[0];
        threads[i].notify_send_fd = fds[1];

        status = thread_setup(&threads[i]);
        if (status != MC_OK) {
            return status;
        }
    }

    /* create worker threads after we've done all the libevent setup */
    for (i = 0; i < nworkers; i++) {
        status = thread_create(thread_worker_main, &threads[i]);
        if (status != MC_OK) {
            return status;
        }
    }

    /* wait for all the workers to set themselves up */
    pthread_mutex_lock(&init_lock);
    while (init_count < nworkers) {
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);

    /* for stats module */

    /* setup thread data structures */
    status = thread_setup_aggregator();
    if (status != MC_OK) {
        return status;
    }

    /* create thread */
    status = thread_create(thread_aggregator_main, NULL);
    if (status != MC_OK) {
        return status;
    }

    /* for klogger */

    /* Setup thread data structure */
    status = thread_setup_klogger();
    if (status != MC_OK) {
        return status;
    }

    /* create thread */
    status = thread_create(thread_klogger_main, NULL);
    if (status != MC_OK) {
        return status;
    }

    /* wait for all the workers and dispatcher to set themselves up */
    pthread_mutex_lock(&init_lock);
    while (init_count < nworkers + 2) { /* +2: aggregator & klogger */
        pthread_cond_wait(&init_cond, &init_lock);
    }
    pthread_mutex_unlock(&init_lock);

    return MC_OK;
}
示例#2
0
struct conn *
conn_get(int sd, conn_state_t state, int ev_flags, int rsize, int udp)
{
    struct conn *c;

    ASSERT(state >= CONN_LISTEN && state < CONN_SENTINEL);
    ASSERT(rsize > 0);

    c = _conn_get();
    if (c == NULL) {
        c = mc_zalloc(sizeof(*c));
        if (c == NULL) {
            return NULL;
        }

        c->rsize = rsize;
        c->rbuf = mc_alloc(c->rsize);

        c->wsize = TCP_BUFFER_SIZE;
        c->wbuf = mc_alloc(c->wsize);

        c->isize = ILIST_SIZE;
        c->ilist = mc_alloc(sizeof(*c->ilist) * c->isize);

        c->ssize = SLIST_SIZE;
        c->slist = mc_alloc(sizeof(*c->slist) * c->ssize);

        c->iov_size = IOV_SIZE;
        c->iov = mc_alloc(sizeof(*c->iov) * c->iov_size);

        c->msg_size = MSG_SIZE;
        c->msg = mc_alloc(sizeof(*c->msg) * c->msg_size);

        if (c->rbuf == NULL || c->wbuf == NULL || c->ilist == NULL ||
            c->iov == NULL || c->msg == NULL || c->slist == NULL) {
            conn_free(c);
            return NULL;
        }

        stats_thread_incr(conn_struct);
    }

    STAILQ_NEXT(c, c_tqe) = NULL;
    c->thread = NULL;

    c->sd = sd;
    c->state = state;
    /* c->event is initialized later */
    c->ev_flags = ev_flags;
    c->which = 0;

    ASSERT(c->rbuf != NULL && c->rsize > 0);
    c->rcurr = c->rbuf;
    c->rbytes = 0;

    ASSERT(c->wbuf != NULL && c->wsize > 0);
    c->wcurr = c->wbuf;
    c->wbytes = 0;

    c->write_and_go = state;
    c->write_and_free = NULL;

    c->ritem = NULL;
    c->rlbytes = 0;

    c->item = NULL;
    c->sbytes = 0;

    ASSERT(c->iov != NULL && c->iov_size > 0);
    c->iov_used = 0;

    ASSERT(c->msg != NULL && c->msg_size > 0);
    c->msg_used = 0;
    c->msg_curr = 0;
    c->msg_bytes = 0;

    ASSERT(c->ilist != NULL && c->isize > 0);
    c->icurr = c->ilist;
    c->ileft = 0;

    ASSERT(c->slist != NULL && c->ssize > 0);
    c->scurr = c->slist;
    c->sleft = 0;

    c->stats.buffer = NULL;
    c->stats.size = 0;
    c->stats.offset = 0;

    c->req_type = REQ_UNKNOWN;
    c->req = NULL;
    c->req_len = 0;

    c->udp = udp;
    c->udp_rid = 0;
    c->udp_hbuf = NULL;
    c->udp_hsize = 0;

    c->noreply = 0;

    stats_thread_incr(conn_total);
    stats_thread_incr(conn_curr);

    log_debug(LOG_VVERB, "get conn %p c %d", c, c->sd);

    return c;
}