I'm on ubuntu 16.10 with g++ 6.2, testing libaio feature:
1. I was trying to test io_set_callback() function
2. I was using main thread and a child thread to talk by a pipe
3. child thread writes periodically (by alarm timer, signal), and main thread reads
I hope to use "callback" function to receive notifications. It didn't work as expected: callback function "read_done" is never called
My questions:
1. I expected my program should call "read_done" function, but actually not.
2. Why the output prints 2 "Enter while" each time?
I hope it only print together with "thread write msg:..."
3. I tried to comment out "io_getevents" line, same result.
I'm not sure if callback mode still need io_getevents? So how to fix my program so it work as I expected? Thanks.
You need to integrate io_queue_run(3)
and io_queue_init(3)
into your program. Though these aren't new functions, they don't seem to be in the manpages for a bunch of currently shipping distros. Here's a couple of the manpages:
http://manpages.ubuntu.com/manpages/precise/en/man3/io_queue_run.3.html http://manpages.ubuntu.com/manpages/precise/en/man3/io_queue_init.3.html
And, of course, the manpages don't actually say it, but io_queue_run
is what calls the callbacks that you set in io_set_callback
.
UPDATED: Ugh. Here's the source for io_queue_run
from libaio-0.3.109 on Centos/RHEL (LGPL license, Copyright 2002 Red Hat, Inc.)
int io_queue_run(io_context_t ctx)
{
static struct timespec timeout = { 0, 0 };
struct io_event event;
int ret;
/* FIXME: batch requests? */
while (1 == (ret = io_getevents(ctx, 0, 1, &event, &timeout))) {
io_callback_t cb = (io_callback_t)event.data;
struct iocb *iocb = event.obj;
cb(ctx, iocb, event.res, event.res2);
}
return ret;
}
You'd never want to actually call this without the io_queue_wait
call. And, the io_queue_wait
call is commented out in the header included with both Centos/RHEL 6 and 7. I don't think you should call this function.
Instead, I think you should incorporate this source into your own code, then modify it to do what you want. You could pretty trivially add a timeout argument to this io_queue_run
and just replace your call to io_getevents with it, instead of bothering with io_queue_wait
. There's even a patch here that makes io_queue_run MUCH better: https://lwn.net/Articles/39285/).