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)); }
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)); }
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)); }