2 * Copyright (c) 2011 Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
17 * This file contains support for the POSIX 1003.1B AIO/LIO facility.
19 * This version of AIO is aimed at standards compliance; it is not aimed
20 * at either reasonability or performance. It merely wraps synchronous I/O
23 * This version cannot perform asynchronous notification of I/O completion
24 * on DragonFly via SIGEV_SIGNAL.
26 * 2) SIGEV_SIGNAL code is present, but if-ed out under 'notyet'; Dfly
27 * does not support sigqueue(), so we cannot control the payload to
28 * a SIGINFO-signal from userspace. Programs using AIO signals use
29 * the payload field to carry pointers to the completed AIO structure,
30 * which is not yet possible here.
32 * It would be possible for this version to support SIGEV_KEVENT.
36 #include <sys/types.h>
38 #include <sys/signal.h>
39 #include <sys/queue.h>
45 static void *_aio_thr_start(void *);
48 _aio_notify(struct sigevent *sigevp)
57 switch (sigevp->sigev_notify) {
63 sigevp->sigev_notify_attributes,
71 sig = sigevp->sigev_signo;
72 sv = sigevp->sigev_value;
73 sigqueue(pid, sig, sv);
84 _aio_thr_start(void *vsigevp)
86 struct sigevent *sigevp = vsigevp;
87 sigevp->sigev_notify_function(sigevp->sigev_value);
94 * Asynchronously read from a file
97 aio_read(struct aiocb *ap)
100 if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) &&
101 (ap->aio_sigevent.sigev_notify != SIGEV_THREAD))
105 ap->_aio_val = pread(ap->aio_fildes,
106 (void *) ap->aio_buf,
109 ap->_aio_err = errno;
111 _aio_notify(&ap->aio_sigevent);
117 aio_write(struct aiocb *ap)
120 if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) &&
121 (ap->aio_sigevent.sigev_notify != SIGEV_THREAD))
125 ap->_aio_val = pwrite(ap->aio_fildes,
126 (void *) ap->aio_buf,
129 ap->_aio_err = errno;
131 _aio_notify(&ap->aio_sigevent);
137 aio_fsync(int op, struct aiocb *ap)
140 if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) &&
141 (ap->aio_sigevent.sigev_notify != SIGEV_THREAD))
145 ap->_aio_val = fsync(ap->aio_fildes);
146 ap->_aio_err = errno;
148 _aio_notify(&ap->aio_sigevent);
154 lio_listio(int mode, struct aiocb *const apv[], int nent,
155 struct sigevent *sigevp)
160 if ((sigevp->sigev_notify != SIGEV_NONE) &&
161 (sigevp->sigev_notify != SIGEV_THREAD))
165 for (i = 0; i < nent; i++)
166 switch (apv[i]->aio_lio_opcode) {
189 * Get I/O completion status
191 * Returns EINPROGRESS until I/O is complete. Returns ECANCELED if
192 * I/O is canceled. Returns I/O status if operation completed.
194 * This routine does not block.
197 aio_error(const struct aiocb *ap)
199 return (ap->_aio_err);
205 * Finish up I/O, releasing I/O resources and returns the value
206 * that would have been associated with a synchronous request.
209 aio_return(struct aiocb *ap)
211 return (ap->_aio_val);
215 aio_cancel(int fildes, struct aiocb *aiocbp)
217 return (AIO_ALLDONE);
221 aio_suspend(const struct aiocb *const list[], int nent, const struct timespec *timo)