Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2017-09-23 18:58:16 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2017-09-23 18:58:16 +0300
commit8ac7c7fa3908ad353594fb4148971f05e643b056 (patch)
tree3cffed7fe53c6a2cf5d97580117a5b436f63d448
parent15b1a6ff306a8a341bd1eb367d84ce1123f424b9 (diff)
Add docs for io_service and async_file_handle. Thanks to @jamboree for reminding me to do this.
-rw-r--r--Doxyfile2
m---------doc/html8
-rw-r--r--include/afio/revision.hpp6
-rw-r--r--include/afio/v2.0/async_file_handle.hpp8
-rw-r--r--include/afio/v2.0/io_service.hpp28
-rw-r--r--test/tests/coroutines.cpp17
6 files changed, 57 insertions, 12 deletions
diff --git a/Doxyfile b/Doxyfile
index 9555f3c7..258ed375 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -845,7 +845,7 @@ EXCLUDE_SYMBOLS = detail::* *::detail::*
# that contain example code fragments that are included (see the \include
# command).
-EXAMPLE_PATH =
+EXAMPLE_PATH = example test/tests
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
diff --git a/doc/html b/doc/html
-Subproject 5c22b279126efb4c2a24b08152616dd80ba1902
+Subproject 3a7ffeb387ac3488c3faccbf4c9b2912a76d99f
diff --git a/include/afio/revision.hpp b/include/afio/revision.hpp
index abf2823b..ed762471 100644
--- a/include/afio/revision.hpp
+++ b/include/afio/revision.hpp
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
-#define AFIO_PREVIOUS_COMMIT_REF c3d4648760ebaf31208d89ad245c640725c2ce4b
-#define AFIO_PREVIOUS_COMMIT_DATE "2017-09-20 17:17:54 +00:00"
-#define AFIO_PREVIOUS_COMMIT_UNIQUE c3d46487
+#define AFIO_PREVIOUS_COMMIT_REF 15b1a6ff306a8a341bd1eb367d84ce1123f424b9
+#define AFIO_PREVIOUS_COMMIT_DATE "2017-09-20 23:20:31 +00:00"
+#define AFIO_PREVIOUS_COMMIT_UNIQUE 15b1a6ff
diff --git a/include/afio/v2.0/async_file_handle.hpp b/include/afio/v2.0/async_file_handle.hpp
index 550c182d..5f876db9 100644
--- a/include/afio/v2.0/async_file_handle.hpp
+++ b/include/afio/v2.0/async_file_handle.hpp
@@ -51,7 +51,7 @@ AFIO_V2_NAMESPACE_END
AFIO_V2_NAMESPACE_EXPORT_BEGIN
/*! \class async_file_handle
-\brief An asynchronous handle to an open something
+\brief An asynchronous handle to an open something.
\note Unlike the others, `async_file_handle` defaults to `only_metadata` caching as that is the
only use case where using async i/o makes sense given the other options below.
@@ -63,7 +63,13 @@ only use case where using async i/o makes sense given the other options below.
<tr><td>`mapped_file_handle`</td><td>Most</td><td>Least</td><td>None</td><td>Cannot be used with uncached i/o</td></tr>
</table>
+\warning i/o initiated by this class MUST be on the same kernel thread as which
+created the owning `io_service` which MUST also be the same kernel thread as which
+runs the i/o service's `run()` function.
+
\todo Direct use of `calloc()` ought to be replaced with a user supplied STL allocator instance.
+
+\snippet coroutines.cpp coroutines_example
*/
class AFIO_DECL async_file_handle : public file_handle
{
diff --git a/include/afio/v2.0/io_service.hpp b/include/afio/v2.0/io_service.hpp
index e9d8ba05..2eff4c7b 100644
--- a/include/afio/v2.0/io_service.hpp
+++ b/include/afio/v2.0/io_service.hpp
@@ -33,7 +33,7 @@ Distributed under the Boost Software License, Version 1.0.
#undef _threadid // windows macro splosh sigh
-//! \file io_service.hpp Provides io_service
+//! \file io_service.hpp Provides io_service.
// Need to decide which kind of POSIX AIO to use
#ifndef _WIN32
@@ -96,6 +96,32 @@ class async_file_handle;
/*! \class io_service
\brief An asynchronous i/o multiplexer service.
+
+This service is used in conjunction with `async_file_handle` to multiplex
+initating i/o and completing it onto a single kernel thread.
+Unlike the `io_service` in ASIO or the Networking TS, this `io_service`
+is much simpler, in particular it is single threaded per instance only
+i.e. you must run a separate `io_service` instance one per kernel thread
+if you wish to run i/o processing across multiple threads. AFIO does not
+do this for you (and for good reason, unlike socket i/o, it is generally
+unwise to distribute file i/o across kernel threads due to the much
+more code executable between user space and physical storage i.e. keeping
+processing per CPU core hot in cache delivers outsize benefits compared
+to socket i/o).
+
+Furthermore, you cannot use this i/o service in any way from any
+thread other than where it was created. You cannot call its `run()`
+from any thread other than where it was created. And you cannot
+initiate i/o on an `async_file_handle` from any thread other than where
+its owning i/o service was created.
+
+In other words, keep your i/o service and all associated file handles
+on their owning thread. The sole function you can call from another
+thread is `post()` which lets you execute some callback in the `run()`
+of the owning thread. This lets you schedule i/o from other threads
+if you really must do that.
+
+\snippet coroutines.cpp coroutines_example
*/
class AFIO_DECL io_service
{
diff --git a/test/tests/coroutines.cpp b/test/tests/coroutines.cpp
index 480df16c..fe23cef0 100644
--- a/test/tests/coroutines.cpp
+++ b/test/tests/coroutines.cpp
@@ -30,10 +30,18 @@ Distributed under the Boost Software License, Version 1.0.
static inline void TestAsyncFileHandleCoroutines()
{
#ifdef __cpp_coroutines
+ //! [coroutines_example]
namespace afio = AFIO_V2_NAMESPACE;
+
+ // Create an i/o service for this thread
afio::io_service service;
+
+ // Create an async file i/o handle attached to the i/o service for this thread
afio::async_file_handle h = afio::async_file_handle::async_file(service, {}, "temp", afio::file_handle::mode::write, afio::file_handle::creation::if_needed, afio::file_handle::caching::only_metadata, afio::file_handle::flag::unlink_on_close).value();
+
+ // Truncate to 1Mb
h.truncate(1024 * 4096);
+
// Launch 8 coroutines, each writing 4Kb of chars 0-8 to every 32Kb block
auto coroutine = [&h](size_t no) -> std::future<void> {
alignas(4096) char buffer[4096];
@@ -41,6 +49,8 @@ static inline void TestAsyncFileHandleCoroutines()
afio::async_file_handle::const_buffer_type bt{buffer};
for(size_t n = 0; n < 128; n++)
{
+ // This will initiate the i/o, and suspend the coroutine until completion.
+ // The caller will thus resume execution with a valid unsignaled future.
auto written = co_await h.co_write({bt, n * 32768 + no * 4096}).value();
written.value();
}
@@ -48,16 +58,19 @@ static inline void TestAsyncFileHandleCoroutines()
std::vector<std::future<void>> coroutines;
for(size_t n = 0; n < 8; n++)
{
+ // Construct each coroutine, initiating the i/o, then suspending.
coroutines.push_back(coroutine(n));
}
- // Pump the i/o, multiplexing the coroutines, until no more work remains
+ // Pump the i/o, multiplexing the coroutines, until no more work remains.
while(service.run().value())
;
- // Make sure nothing went wrong
+ // Make sure nothing went wrong by fetching the futures.
for(auto &i : coroutines)
{
i.get();
}
+ //! [coroutines_example]
+
// Check that the file has the right contents
alignas(4096) char buffer1[4096], buffer2[4096];
afio::async_file_handle::extent_type offset = 0;