Reputation: 20470
My code works perfectly on a native Linux system, but when I run it on a WSL, it seems something is wrong.
Here's how I send the AsyncWrites:
Status PosixAIOEngine::AsyncWrite(int fd, uint64_t offset, const char* buffer, uint64_t size,
char** cb) {
if (requests_.size() >= io_depth_) {
LOG(ERROR, "io depth full, please try again later, cur: {}", io_depth_);
return Status::Busy();
}
requests_.push_back({.aio_req_ = {}, .type_ = kAsyncWrite});
auto& request = requests_.back();
memset(&request.aio_req_, 0, sizeof(struct aiocb));
request.aio_req_.aio_offset = (off_t)offset;
request.aio_req_.aio_buf = (void*)buffer;
request.aio_req_.aio_nbytes = size;
request.aio_req_.aio_fildes = fd;
int ret = aio_write(&request.aio_req_);
if (ret == -1) {
auto msg = "aio_write failed, err msg: " + std::string(strerror(errno));
LOG(ERROR, msg);
requests_.pop_back();
return Status::IOError(msg);
}
return Status::OK();
}
After I send out a few write requests, I Poll the result here:
uint32_t PosixAIOEngine::Poll() {
uint32_t cnt = 0;
auto it = requests_.begin();
while (it != requests_.end()) {
auto& req = *it;
int err_value = aio_error(&req.aio_req_);
// If the request was canceld, we remove & skip it.
if (err_value == ECANCELED) {
it = requests_.erase(it);
continue;
}
// If the request is not yet completed, we skip it.
if (err_value == EINPROGRESS) {
++it;
continue;
}
// If the request has an error.
if (err_value != 0) { <------------------- ERROR here <<<<<<<<<<<<<<<<<<
LOG(ERROR, "I/O failed, aio_error: {}, errmsg: {}, offset: {}", err_value, strerror(errno),
req.aio_req_.aio_offset);
it = requests_.erase(it);
continue;
}
// If there's no operation error occurs, we should check the return value.
int ret_value = aio_return(&req.aio_req_);
if (ret_value == -1) {
LOG(ERROR, "I/O failed, aio_return: {}, errmsg: {}, offset: {}", ret_value, strerror(errno),
req.aio_req_.aio_offset);
it = requests_.erase(it);
continue;
}
// Otherwise, the operation success
it = requests_.erase(it);
cnt++;
}
I check the aio_error
first to make sure the requests were send out correctly, but it has a 38 return value, which means Not Implemented
. I suppose the errno would be changed too, but it turns out errno is still 0, which means Sucess.
Questions:
According to the description of this API:, it seems it should has the same value of the errno? Or I mis-understand the description... (not a native speaker)
A positive error number, if the asynchronous I/O operation
failed. This is the same value that would have been
stored in the errno variable in the case of a synchronous
read(2), write(2), fsync(2), or fdatasync(2) call.
Upvotes: 0
Views: 37
Reputation: 20470
OK, the solution is here:
It turns out that WSL1.0 is not able to process async aio
correctly (under aio.h
), so I upgraded it to WSL2.0, which works perfectly.
Upvotes: 0