Line data Source code
1 : /*
2 : * (C) Copyright 2011 Marek Dopiera
3 : *
4 : * This file is part of CoherentDB.
5 : *
6 : * CoherentDB is free software: you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation, either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * CoherentDB is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public
17 : * License along with CoherentDB. If not, see
18 : * http://www.gnu.org/licenses/.
19 : */
20 :
21 : #ifndef AIO_H_3410
22 : #define AIO_H_3410
23 :
24 : #include <sys/uio.h>
25 :
26 : #include <boost/shared_ptr.hpp>
27 :
28 : #include <util/worker_pool.h>
29 : #include <debug/asserts.h>
30 :
31 : namespace coherent {
32 : namespace util {
33 :
34 : class aio_worker;
35 :
36 : class aio_request : public virtual_dest
37 12 : {
38 : public:
39 : virtual void handle_in_worker(aio_worker const & worker) const = 0;
40 :
41 : };
42 :
43 : class aio_open_req :
44 : public aio_request,
45 : private boost::noncopyable
46 2 : {
47 : public:
48 : struct callback : public virtual_dest
49 2 : {
50 : virtual void open_completed(
51 : aio_open_req const & req,
52 : int fd,
53 : int err
54 : ) = 0;
55 : };
56 :
57 : aio_open_req(
58 : callback & cb,
59 : std::string const & path,
60 : int flags,
61 : int mode
62 : );
63 :
64 : virtual void handle_in_worker(aio_worker const & worker) const;
65 :
66 : callback & cb;
67 : std::string const path;
68 : int flags;
69 : int mode;
70 : };
71 :
72 : class aio_pread_req :
73 : public aio_request,
74 : private boost::noncopyable
75 2 : {
76 : public:
77 : struct callback : public virtual_dest
78 2 : {
79 : virtual void pread_completed(
80 : aio_pread_req const & req,
81 : ssize_t res,
82 : int err
83 : ) = 0;
84 : };
85 :
86 : aio_pread_req(callback & cb, int fd, char * buf, off_t off, ssize_t size);
87 :
88 : virtual void handle_in_worker(aio_worker const & worker) const;
89 :
90 : callback & cb;
91 : char * buf;
92 : off_t off;
93 : ssize_t size;
94 : int fd;
95 : };
96 :
97 : class aio_preadv_req :
98 : public aio_request,
99 : private boost::noncopyable
100 2 : {
101 : public:
102 : struct callback : public virtual_dest
103 2 : {
104 : virtual void preadv_completed(
105 : aio_preadv_req const & req,
106 : ssize_t res,
107 : int err
108 : ) = 0;
109 : };
110 :
111 : //destroys the vector
112 : aio_preadv_req(
113 : callback & cb,
114 : int fd,
115 : std::vector<iovec> & iovecs,
116 : off_t off
117 : );
118 :
119 : virtual void handle_in_worker(aio_worker const & worker) const;
120 :
121 : callback & cb;
122 : std::vector<iovec> iovecs;
123 : off_t off;
124 : int fd;
125 : };
126 :
127 : class aio_pwrite_req :
128 : public aio_request,
129 : private boost::noncopyable
130 : {
131 2 : public:
132 : struct callback : public virtual_dest
133 : {
134 2 : virtual void pwrite_completed(
135 : aio_pwrite_req const & req,
136 : ssize_t res,
137 : int err
138 : ) = 0;
139 : };
140 :
141 : aio_pwrite_req(callback & cb, int fd, char const * buf, off_t off, ssize_t size);
142 :
143 : virtual void handle_in_worker(aio_worker const & worker) const;
144 :
145 : callback & cb;
146 : char const * buf;
147 : off_t off;
148 : ssize_t size;
149 : int fd;
150 : };
151 :
152 : class aio_pwritev_req :
153 : public aio_request,
154 : private boost::noncopyable
155 : {
156 2 : public:
157 : struct callback : public virtual_dest
158 : {
159 2 : virtual void pwritev_completed(
160 : aio_pwritev_req const & req,
161 : ssize_t res,
162 : int err
163 : ) = 0;
164 : };
165 :
166 : //destroys the vector
167 : aio_pwritev_req(
168 : callback & cb,
169 : int fd,
170 : std::vector<iovec> & iovecs,
171 : off_t off
172 : );
173 :
174 : virtual void handle_in_worker(aio_worker const & worker) const;
175 :
176 : callback & cb;
177 : std::vector<iovec> iovecs;
178 : off_t off;
179 : int fd;
180 : };
181 :
182 : class aio_close_req :
183 : public aio_request,
184 : private boost::noncopyable
185 : {
186 2 : public:
187 : struct callback : public virtual_dest
188 : {
189 2 : virtual void close_completed(
190 : aio_close_req const & req,
191 : int res,
192 : int err
193 : ) = 0;
194 : };
195 :
196 : aio_close_req(callback & cb, int fd);
197 :
198 : virtual void handle_in_worker(aio_worker const & worker) const;
199 :
200 : callback & cb;
201 : int fd;
202 : };
203 :
204 : typedef boost::shared_ptr<aio_request> aio_request_ptr;
205 :
206 : class aio_worker : public worker<aio_request_ptr>
207 : {
208 105 : public:
209 : aio_worker(worker_pool<aio_request_ptr> & pool);
210 :
211 : void handle(aio_request_ptr const & req) const;
212 : void handle_exact(aio_open_req const & req) const;
213 : void handle_exact(aio_pread_req const & req) const;
214 : void handle_exact(aio_preadv_req const & req) const;
215 : void handle_exact(aio_pwrite_req const & req) const;
216 : void handle_exact(aio_pwritev_req const & req) const;
217 : void handle_exact(aio_close_req const & req) const;
218 : };
219 :
220 : class aio_worker_factory : public worker_factory<aio_request_ptr>
221 : {
222 2 : public:
223 : virtual worker_ptr create_worker(worker_pool<aio_request_ptr> & pool) const;
224 : };
225 :
226 : class aio_context
227 : {
228 : public:
229 : aio_context(uint32_t num_workers);
230 : ~aio_context();
231 : void submit_request(aio_request_ptr req);
232 :
233 : private:
234 : worker_pool<aio_request_ptr> workers;
235 : };
236 :
237 : class async_file :
238 : private aio_open_req::callback,
239 : private aio_close_req::callback
240 : {
241 : public:
242 1 : async_file(aio_context & ctx, std::string const path);
243 :
244 : struct open_callback : public virtual_dest
245 : {
246 : virtual void open_completed(
247 2 : aio_open_req const & req,
248 : int err
249 : ) = 0;
250 : };
251 :
252 : typedef aio_pread_req::callback pread_callback;
253 : typedef aio_preadv_req::callback preadv_callback;
254 : typedef aio_pwrite_req::callback pwrite_callback;
255 : typedef aio_pwritev_req::callback pwritev_callback;
256 :
257 : struct close_callback : public virtual_dest
258 : {
259 : virtual void close_completed(
260 2 : aio_close_req const & req,
261 : int res,
262 : int err
263 : ) = 0;
264 : };
265 :
266 : void submit_open(
267 : open_callback & cb,
268 : int flags,
269 : int mode
270 : );
271 : void submit_pread(
272 : pread_callback & cb,
273 : char * buf,
274 : off_t off,
275 : ssize_t size
276 : );
277 : //destroys the vector
278 : void submit_preadv(
279 : preadv_callback & cb,
280 : std::vector<iovec> & iovecs,
281 : off_t off
282 : );
283 : void submit_pwrite(
284 : pwrite_callback & cb,
285 : char const * buf,
286 : off_t off,
287 : ssize_t size
288 : );
289 : //destroys the vector
290 : void submit_pwritev(
291 : pwritev_callback & cb,
292 : std::vector<iovec> & iovecs,
293 : off_t off
294 : );
295 : void submit_close(
296 : close_callback & cb
297 : );
298 :
299 : inline bool is_open() const;
300 :
301 : private:
302 : virtual void open_completed(
303 : aio_open_req const & req,
304 : int fd,
305 : int err
306 : );
307 : virtual void close_completed(
308 : aio_close_req const & req,
309 : int res,
310 : int err
311 : );
312 :
313 : enum {
314 : NOT_OPEN = -1
315 : };
316 :
317 : aio_context & ctx;
318 : std::string path;
319 : open_callback * open_cb;
320 : close_callback * close_cb;
321 : int fd;
322 : };
323 :
324 : //======= INLINE IMPLEMENTATION ================================================
325 :
326 : bool async_file::is_open() const
327 : {
328 6 : return this->fd != NOT_OPEN;
329 : }
330 6 :
331 : } // namespace util
332 : } // namespace coherent
333 :
334 : #endif /* AIO_H_3410 */
335 :
|