2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef FOLLY_IO_ASYNCIO_H_
18 #define FOLLY_IO_ASYNCIO_H_
20 #include <sys/types.h>
29 #include <boost/noncopyable.hpp>
31 #include "folly/Portability.h"
32 #include "folly/Range.h"
37 * C++ interface around Linux Async IO.
39 class AsyncIO : private boost::noncopyable {
47 * Create an AsyncIO context capacble of holding at most 'capacity' pending
48 * requests at the same time. As requests complete, others can be scheduled,
49 * as long as this limit is not exceeded.
51 * Note: the maximum number of allowed concurrent requests is controlled
52 * by the fs.aio-max-nr sysctl, the default value is usually 64K.
54 * If pollMode is POLLABLE, pollFd() will return a file descriptor that
55 * can be passed to poll / epoll / select and will become readable when
56 * any IOs on this AioReader have completed. If you do this, you must use
57 * pollCompleted() instead of wait() -- do not read from the pollFd()
58 * file descriptor directly.
60 explicit AsyncIO(size_t capacity, PollMode pollMode=NOT_POLLABLE);
64 * An Op represents a pending operation. You may inherit from Op (and
65 * override onCompleted) in order to be notified of completion (see
66 * CallbackOp below for an example), or you may use Op's methods directly.
68 * The Op must remain allocated until completion.
70 class Op : private boost::noncopyable {
76 // There would be a cancel() method here if Linux AIO actually implemented
77 // it. But let's not get your hopes up.
86 * Return the current operation state.
88 State state() const { return state_; }
91 * Reset the operation for reuse. It is an error to call reset() on
92 * an Op that is still pending.
97 * Retrieve the result of this operation. Returns >=0 on success,
98 * -errno on failure (that is, using the Linux kernel error reporting
99 * conventions). Use checkKernelError (folly/Exception.h) on the result to
100 * throw a std::system_error in case of error instead.
102 * It is an error to call this if the Op hasn't yet started or is still
105 ssize_t result() const;
109 void complete(ssize_t result);
111 virtual void onCompleted();
118 * Initiate a read request.
120 void pread(Op* op, int fd, void* buf, size_t size, off_t start);
121 void pread(Op* op, int fd, Range<unsigned char*> range, off_t start);
122 void preadv(Op* op, int fd, const iovec* iov, int iovcnt, off_t start);
125 * Initiate a write request.
127 void pwrite(Op* op, int fd, const void* buf, size_t size, off_t start);
128 void pwrite(Op* op, int fd, Range<const unsigned char*> range, off_t start);
129 void pwritev(Op* op, int fd, const iovec* iov, int iovcnt, off_t start);
132 * Wait for at least minRequests to complete. Returns the requests that
133 * have completed; the returned range is valid until the next call to
134 * wait(). minRequests may be 0 to not block.
136 Range<Op**> wait(size_t minRequests);
139 * Return the number of pending requests.
141 size_t pending() const { return pending_; }
144 * Return the maximum number of requests that can be kept outstanding
147 size_t capacity() const { return capacity_; }
150 * If POLLABLE, return a file descriptor that can be passed to poll / epoll
151 * and will become readable when any async IO operations have completed.
152 * If NOT_POLLABLE, return -1.
154 int pollFd() const { return pollFd_; }
157 * If POLLABLE, call instead of wait after the file descriptor returned
158 * by pollFd() became readable. The returned range is valid until the next
159 * call to pollCompleted().
161 Range<Op**> pollCompleted();
164 void initializeContext();
165 void submit(Op* op, iocb* cb);
166 Range<Op**> doWait(size_t minRequests, size_t maxRequests);
172 std::vector<Op*> completed_;
176 * Implementation of AsyncIO::Op that calls a callback and then deletes
179 class CallbackOp : public AsyncIO::Op {
181 typedef std::function<void(ssize_t)> Callback;
182 static CallbackOp* make(Callback&& callback);
185 explicit CallbackOp(Callback&& callback);
187 void onCompleted() FOLLY_OVERRIDE;
194 #endif /* FOLLY_IO_ASYNCIO_H_ */