void async_req_post(AsyncReqInfo * req) {
    WorkerThread * wt;

    trace(LOG_ASYNCREQ, "async_req_post: req %p, type %d", req, req->type);

#if ENABLE_AIO
    {
        int res = 0;
        switch (req->type) {
        case AsyncReqSeekRead:
        case AsyncReqSeekWrite:
            memset(&req->u.fio.aio, 0, sizeof(req->u.fio.aio));
            req->u.fio.aio.aio_fildes = req->u.fio.fd;
            req->u.fio.aio.aio_offset = req->u.fio.offset;
            req->u.fio.aio.aio_buf = req->u.fio.bufp;
            req->u.fio.aio.aio_nbytes = req->u.fio.bufsz;
            req->u.fio.aio.aio_sigevent.sigev_notify = SIGEV_THREAD;
            req->u.fio.aio.aio_sigevent.sigev_notify_function = aio_done;
            req->u.fio.aio.aio_sigevent.sigev_value.sival_ptr = req;
            res = req->type == AsyncReqSeekWrite ?
                aio_write(&req->u.fio.aio) :
                aio_read(&req->u.fio.aio);
            if (res < 0) {
                req->u.fio.rval = -1;
                req->error = errno;
                post_event(req->done, req);
            }
            return;
        }
    }
#endif
    check_error(pthread_mutex_lock(&wtlock));
    if (list_is_empty(&wtlist)) {
        int error;

        wt = loc_alloc_zero(sizeof *wt);
        check_error(pthread_cond_init(&wt->cond, NULL));
        wt->req = req;
        error = pthread_create(&wt->thread, &pthread_create_attr, worker_thread_handler, wt);
        if (error) {
            trace(LOG_ALWAYS, "Can't create a worker thread: %d %s", error, errno_to_str(error));
            loc_free(wt);
            req->error = error;
            post_event(req->done, req);
        }
    }
    else {
        wt = wtlink2wt(wtlist.next);
        list_remove(&wt->wtlink);
        assert(wt->req == NULL);
        wt->req = req;
        check_error(pthread_cond_signal(&wt->cond));
    }
    check_error(pthread_mutex_unlock(&wtlock));
}
Beispiel #2
0
static void trigger_async_shutdown(ShutdownInfo * obj) {
    check_error(pthread_mutex_lock(&wtlock));
    while (!list_is_empty(&wtlist)) {
        WorkerThread * wt = wtlink2wt(wtlist.next);
        list_remove(&wt->wtlink);
        wtlist_size--;
        assert(wt->req == NULL);
        wt->req = &shutdown_req;
        check_error(pthread_cond_signal(&wt->cond));
    }
    check_error(pthread_mutex_unlock(&wtlock));
}
Beispiel #3
0
void async_req_post(AsyncReqInfo * req) {
    WorkerThread * wt;

    trace(LOG_ASYNCREQ, "async_req_post: req %p, type %d", req, req->type);
    assert(req->done != NULL || req->type == AsyncReqTimer);

#if ENABLE_AIO
    {
        int res = 0;
        switch (req->type) {
        case AsyncReqSeekRead:
        case AsyncReqSeekWrite:
            memset(&req->u.fio.aio, 0, sizeof(req->u.fio.aio));
            req->u.fio.aio.aio_fildes = req->u.fio.fd;
            req->u.fio.aio.aio_offset = (off_t)req->u.fio.offset;
            req->u.fio.aio.aio_buf = req->u.fio.bufp;
            req->u.fio.aio.aio_nbytes = req->u.fio.bufsz;
            req->u.fio.aio.aio_sigevent.sigev_notify = SIGEV_THREAD;
            req->u.fio.aio.aio_sigevent.sigev_notify_function = aio_done;
            req->u.fio.aio.aio_sigevent.sigev_value.sival_ptr = req;
            res = req->type == AsyncReqSeekWrite ?
                aio_write(&req->u.fio.aio) :
                aio_read(&req->u.fio.aio);
            if (res < 0) {
                req->u.fio.rval = -1;
                req->error = errno;
                post_event(req->done, req);
            }
            return;
        }
    }
#endif
    check_error(pthread_mutex_lock(&wtlock));
    if (list_is_empty(&wtlist)) {
        assert(wtlist_size == 0);
        if (is_dispatch_thread()) {
            worker_thread_add(req);
        }
        else {
            post_event(worker_thread_add_deferred, req);
        }
    }
    else {
        wt = wtlink2wt(wtlist.next);
        list_remove(&wt->wtlink);
        wtlist_size--;
        assert(wt->req == NULL);
        wt->req = req;
        check_error(pthread_cond_signal(&wt->cond));
    }
    check_error(pthread_mutex_unlock(&wtlock));
}