void native_win_aio_provider::worker() { DWORD dwTransLen; DWORD dwErrorCode; ULONG_PTR dwKey; LPOVERLAPPED overLap; do { bool ret = (0 != GetQueuedCompletionStatus(_iocp, &dwTransLen, &dwKey, &overLap, INFINITE)); if (dwKey) break; if (ret) { windows_disk_aio_context* ctx = CONTAINING_RECORD(overLap, windows_disk_aio_context, olp); if (!ctx->evt) { aio_task* aio(ctx->tsk); complete_io(aio, ERR_OK, dwTransLen); } else { ctx->err = ERR_OK; ctx->bytes = dwTransLen; ctx->evt->notify(); } } else if (overLap) { dwErrorCode = ::GetLastError(); dinfo("file operation failed, err = %u", dwErrorCode); windows_disk_aio_context* ctx = CONTAINING_RECORD(overLap, windows_disk_aio_context, olp); error_code err = dwErrorCode == ERROR_SUCCESS ? ERR_OK : (dwErrorCode == ERROR_HANDLE_EOF ? ERR_HANDLE_EOF : ERR_FILE_OPERATION_FAILED); if (!ctx->evt) { aio_task* aio(ctx->tsk); complete_io(aio, err, dwTransLen); } else { ctx->err = err; ctx->bytes = dwTransLen; ctx->evt->notify(); } } else { ::Sleep(1); } } while (true); }
void hpc_aio_provider::complete_aio(struct aiocb* io) { posix_disk_aio_context* ctx = CONTAINING_RECORD(io, posix_disk_aio_context, cb); int err = aio_error(&ctx->cb); if (err != EINPROGRESS) { if (err != 0) { derror("file operation failed, errno = %d", errno); } size_t bytes = aio_return(&ctx->cb); // from e.g., read or write if (!ctx->evt) { aio_task* aio(ctx->tsk); ctx->this_->complete_io(aio, err == 0 ? ERR_OK : ERR_FILE_OPERATION_FAILED, bytes); } else { ctx->err = err == 0 ? ERR_OK : ERR_FILE_OPERATION_FAILED; ctx->bytes = bytes; ctx->evt->notify(); } } }
void aio_completed(sigval sigval) { auto ctx = (posix_disk_aio_context *)sigval.sival_ptr; int err = aio_error(&ctx->cb); if (err != EINPROGRESS) { if (err != 0) { derror("file operation failed, errno = %d", errno); } size_t bytes = aio_return(&ctx->cb); // from e.g., read or write if (!ctx->evt) { aio_task* aio(ctx->tsk); ctx->this_->complete_io(aio, err == 0 ? ERR_OK : ERR_FILE_OPERATION_FAILED, bytes); } else { ctx->err = err == 0 ? ERR_OK : ERR_FILE_OPERATION_FAILED; ctx->bytes = bytes; ctx->evt->notify(); } } }