Функция aio_return(3AIO) возвращает статус запроса. Если запрос уже завершился и завершился успешно, она возвращает размер прочитанных или записанных данных в байтах. Как и у традиционного read(2), в случае конца файла aio_return(3AIO) возвращает 0 байт. Если запрос завершился ошибкой или еще не завершился, возвращается -1 и устанавливается errno. Если запрос еще не завершился, код ошибки равен EINPROGRESS. Функция aio_return(3AIO) разрушающая; если ее вызвать для завершенного запроса, то она уничтожит системный объект, хранящий информацию о статусе запроса. Многократный вызов aio_return(3AIO) по поводу одного и того же запроса, таким образом, невозможен.
Функция aio_error(3AIO) возвращает код ошибки, связанной с запросом. При успешном завершении запроса возвращается 0, при ошибке – код ошибки, для незавершенных запросов – EINPROGRESS.
Функция aio_suspend(3AIO) блокирует нить до завершения одного из указанных ей запросов асинхронного ввода/вывода либо на указанный интервал времени. Эта функция имеет три параметра:
const struct aiocb *const list[] – массив указателей на описатели запросов.
|
|
int nent – количество элементов в массиве list.
const struct timespec *timeout – тайм-аут с точностью до наносекунд (в действительности, с точностью до разрешения системного таймера).
Функция возвращает 0, если хотя бы одна из операций, перечисленных в списке, завершилась. Если функция завершилась с ошибкой, она возвращает -1 и устанавливает errno. Если функция завершилась по тайм-ауту, она также возвращает -1 и errno==EINPROGRESS.
Пример использования асинхронного ввода/вывода с синхронной проверкой статуса запроса приводится в примере 3.
Асинхронный ввод/вывод с синхронной проверкой статуса запроса.
Код сокращен, из него исключены открытие сокета и обработка ошибок.
const char req[]="GET / HTTP/1.0\r\n\r\n";
int main() {
int s;
static struct aiocb readrq;
static const struct aiocb *readrqv[2]={&readrq, NULL};
/* Открыть сокет […] */
memset(&readrq, 0, sizeof readrq);
readrq.aio_fildes=s;
readrq.aio_buf=buf;
readrq.aio_nbytes=sizeof buf;
if (aio_read(&readrq)) {
/* … */
}
write(s, req, (sizeof req)-1);
while(1) {
aio_suspend(readrqv, 1, NULL);
size=aio_return(&readrq);
if (size>0) {
write(1, buf, size);
aio_read(&readrq);
} else if (size==0) {
break;
} else if (errno!=EINPROGRESS) {
perror("reading from socket");
}
}
}