X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fexperimental%2Fio%2FAsyncIO.h;h=faa5e27fc4b4e075d36f023bba1e5d72cae15dcc;hb=ed8c80a0e0988e4ce687f51ca832a00e4a6b7930;hp=3c84ebb0c4f2be331669ffb88b379fdfb8fbbfc3;hpb=a8b4b5ea1e090f4dff374aec509119e842297956;p=folly.git diff --git a/folly/experimental/io/AsyncIO.h b/folly/experimental/io/AsyncIO.h index 3c84ebb0..faa5e27f 100644 --- a/folly/experimental/io/AsyncIO.h +++ b/folly/experimental/io/AsyncIO.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,23 +14,25 @@ * limitations under the License. */ -#ifndef FOLLY_IO_ASYNCIO_H_ -#define FOLLY_IO_ASYNCIO_H_ +#pragma once #include -#include #include +#include #include #include #include +#include +#include #include #include #include -#include "folly/Portability.h" -#include "folly/Range.h" +#include +#include +#include namespace folly { @@ -42,6 +44,7 @@ namespace folly { */ class AsyncIOOp : private boost::noncopyable { friend class AsyncIO; + friend std::ostream& operator<<(std::ostream& stream, const AsyncIOOp& o); public: typedef std::function NotificationCallback; @@ -51,7 +54,7 @@ class AsyncIOOp : private boost::noncopyable { // There would be a cancel() method here if Linux AIO actually implemented // it. But let's not get your hopes up. - enum State { + enum class State { UNINITIALIZED, INITIALIZED, PENDING, @@ -108,6 +111,9 @@ class AsyncIOOp : private boost::noncopyable { ssize_t result_; }; +std::ostream& operator<<(std::ostream& stream, const AsyncIOOp& o); +std::ostream& operator<<(std::ostream& stream, AsyncIOOp::State state); + /** * C++ interface around Linux Async IO. */ @@ -133,6 +139,12 @@ class AsyncIO : private boost::noncopyable { * any IOs on this AsyncIO have completed. If you do this, you must use * pollCompleted() instead of wait() -- do not read from the pollFd() * file descriptor directly. + * + * You may use the same AsyncIO object from multiple threads, as long as + * there is only one concurrent caller of wait() / pollCompleted() (perhaps + * by always calling it from the same thread, or by providing appropriate + * mutual exclusion) In this case, pending() returns a snapshot + * of the current number of pending requests. */ explicit AsyncIO(size_t capacity, PollMode pollMode=NOT_POLLABLE); ~AsyncIO(); @@ -155,6 +167,12 @@ class AsyncIO : private boost::noncopyable { */ size_t capacity() const { return capacity_; } + /** + * Return the accumulative number of submitted I/O, since this object + * has been created. + */ + size_t totalSubmits() const { return submitted_; } + /** * If POLLABLE, return a file descriptor that can be passed to poll / epoll * and will become readable when any async IO operations have completed. @@ -175,11 +193,17 @@ class AsyncIO : private boost::noncopyable { void submit(Op* op); private: + void decrementPending(); void initializeContext(); + Range doWait(size_t minRequests, size_t maxRequests); io_context_t ctx_; - size_t pending_; + std::atomic ctxSet_; + std::mutex initMutex_; + + std::atomic pending_; + std::atomic submitted_; const size_t capacity_; int pollFd_; std::vector completed_; @@ -215,6 +239,7 @@ class AsyncIOQueue { */ typedef std::function OpFactory; void submit(OpFactory op); + private: void onCompleted(AsyncIOOp* op); void maybeDequeue(); @@ -225,6 +250,3 @@ class AsyncIOQueue { }; } // namespace folly - -#endif /* FOLLY_IO_ASYNCIO_H_ */ -