Go to the documentation of this file.00001
00002 #include "asyncio.h"
00003
00004
00005 #include <vcl_sys/types.h>
00006 #include <vcl_cerrno.h>
00007 #include <vcl_cassert.h>
00008
00009
00010
00011 volatile sig_atomic_t AsyncIO_Shared_State::complete = 1;
00012
00013
00014
00015
00016 void AsyncIO_Shared_State::signal_handler(int)
00017 {
00018 complete = 1;
00019 }
00020
00021
00022
00023
00024 AsyncIO::AsyncIO(int fd, int sig)
00025 {
00026 cb.aio_fildes = fd;
00027 cb.aio_reqprio = 0;
00028 cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
00029 cb.aio_sigevent.sigev_signo = sig;
00030 cb.aio_lio_opcode = LIO_NOP;
00031
00032 signal(sig, &AsyncIO_Shared_State::signal_handler);
00033 }
00034
00035
00036
00037 AsyncIO::~AsyncIO()
00038 {
00039 signal(cb.aio_sigevent.sigev_signo, SIG_DFL);
00040 }
00041
00042
00043
00044 int AsyncIO::read(volatile void *buf, vcl_size_t n)
00045 {
00046
00047
00048
00049 if (!complete)
00050 return EBUSY;
00051
00052 off_t pos = lseek(cb.aio_fildes, 0, SEEK_CUR);
00053 if (pos == -1)
00054 return errno;
00055 else
00056 return read(buf, n, pos);
00057 }
00058
00059
00060
00061 int AsyncIO::read(volatile void *buf, vcl_size_t n, off_t pos)
00062 {
00063
00064
00065
00066 if (!complete)
00067 return EBUSY;
00068
00069 complete = 0;
00070 cb.aio_buf = buf;
00071 cb.aio_nbytes = n;
00072 cb.aio_offset = pos;
00073
00074
00075
00076 if (aio_read(&cb) != 0)
00077 {
00078 complete = 1;
00079 return errno;
00080 }
00081 else
00082 return 0;
00083 }
00084
00085
00086
00087 int AsyncIO::write(volatile void *buf, vcl_size_t n)
00088 {
00089
00090
00091
00092 if (!complete)
00093 return EBUSY;
00094
00095 off_t pos = lseek(cb.aio_fildes, 0, SEEK_CUR);
00096 if (pos == -1)
00097 return errno;
00098 else
00099 return write(buf, n, pos);
00100 }
00101
00102
00103
00104 int AsyncIO::write(volatile void *buf, vcl_size_t n, off_t pos)
00105 {
00106
00107
00108
00109 if (!complete)
00110 return EBUSY;
00111
00112 complete = 0;
00113 cb.aio_buf = buf;
00114 cb.aio_nbytes = n;
00115 cb.aio_offset = pos;
00116
00117
00118
00119 if (aio_write(&cb) != 0)
00120 {
00121 complete = 1;
00122 return errno;
00123 }
00124 else
00125 return 0;
00126 }
00127
00128
00129
00130
00131
00132
00133 int AsyncIO::wait_for_completion(bool suspend)
00134 {
00135 int status;
00136
00137 if (!complete)
00138 {
00139 if (suspend)
00140 {
00141 const struct aiocb *aio_list[1] = { &cb };
00142
00143
00144 while (aio_suspend(aio_list, 1, NULL) == -1)
00145 if (errno != EINTR)
00146 return errno;
00147 }
00148 else
00149 while (aio_error(&cb) == EINPROGRESS)
00150 ;
00151 assert(complete);
00152 }
00153 if ((status = aio_error(&cb)) != 0)
00154 return status;
00155 else if (aio_return(&cb) == -1)
00156 return errno;
00157 else
00158 return 0;
00159 }