1#if defined(__linux__)
2
3#include <boost/noncopyable.hpp>
4#include <Common/Exception.h>
5#include <sys/syscall.h>
6#include <unistd.h>
7
8#include <IO/AIO.h>
9
10
11/** Small wrappers for asynchronous I/O.
12 */
13
14namespace DB
15{
16 namespace ErrorCodes
17 {
18 extern const int CANNOT_IOSETUP;
19 }
20}
21
22
23int io_setup(unsigned nr, aio_context_t * ctxp)
24{
25 return syscall(__NR_io_setup, nr, ctxp);
26}
27
28int io_destroy(aio_context_t ctx)
29{
30 return syscall(__NR_io_destroy, ctx);
31}
32
33int io_submit(aio_context_t ctx, long nr, struct iocb * iocbpp[])
34{
35 return syscall(__NR_io_submit, ctx, nr, iocbpp);
36}
37
38int io_getevents(aio_context_t ctx, long min_nr, long max_nr, io_event * events, struct timespec * timeout)
39{
40 return syscall(__NR_io_getevents, ctx, min_nr, max_nr, events, timeout);
41}
42
43
44AIOContext::AIOContext(unsigned int nr_events)
45{
46 ctx = 0;
47 if (io_setup(nr_events, &ctx) < 0)
48 DB::throwFromErrno("io_setup failed", DB::ErrorCodes::CANNOT_IOSETUP);
49}
50
51AIOContext::~AIOContext()
52{
53 io_destroy(ctx);
54}
55
56#elif defined(__FreeBSD__)
57
58# include <aio.h>
59# include <boost/noncopyable.hpp>
60# include <sys/event.h>
61# include <sys/time.h>
62# include <sys/types.h>
63# include <Common/Exception.h>
64
65# include <IO/AIO.h>
66
67
68/** Small wrappers for asynchronous I/O.
69 */
70
71namespace DB
72{
73namespace ErrorCodes
74{
75 extern const int CANNOT_IOSETUP;
76}
77}
78
79
80int io_setup(void)
81{
82 return kqueue();
83}
84
85int io_destroy(int ctx)
86{
87 return close(ctx);
88}
89
90int io_submit(int ctx, long nr, struct iocb * iocbpp[])
91{
92 for (long i = 0; i < nr; i++)
93 {
94 struct aiocb * iocb = &iocbpp[i]->aio;
95
96 struct sigevent * se = &iocb->aio_sigevent;
97 se->sigev_notify_kqueue = ctx;
98 se->sigev_notify_kevent_flags = 0;
99 se->sigev_notify = SIGEV_KEVENT;
100 se->sigev_value.sival_ptr = iocbpp[i];
101
102 switch (iocb->aio_lio_opcode)
103 {
104 case LIO_READ:
105 {
106 int r = aio_read(iocb);
107 if (r < 0)
108 return r;
109 break;
110 }
111 case LIO_WRITE:
112 {
113 int r = aio_write(iocb);
114 if (r < 0)
115 return r;
116 break;
117 }
118 }
119 }
120
121 return nr;
122}
123
124int io_getevents(int ctx, long, long max_nr, struct kevent * events, struct timespec * timeout)
125{
126 return kevent(ctx, NULL, 0, events, max_nr, timeout);
127}
128
129
130AIOContext::AIOContext(unsigned int)
131{
132 ctx = io_setup();
133 if (ctx < 0)
134 DB::throwFromErrno("io_setup failed", DB::ErrorCodes::CANNOT_IOSETUP);
135}
136
137AIOContext::~AIOContext()
138{
139 io_destroy(ctx);
140}
141
142#endif
143