Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

make_io_req (length deducing)

Convenience instantiator of a io_req, letting the compiler deduce the template specialisation to use.

Synopsis
template<class T>
auto make_io_req(future<> _precondition, T && v, off_t _where)
Parameters

Type

Concept

Name

Description

class T

-

Must be specified

future<>

_precondition

An optional precondition for this operation

T &&

v

A pointer to memory or reference to object into which to read or write

off_t

_where

The offset at which to transfer

Returns

An io_req matching the supplied parameter type. Constructs an instance.

Header

#include <boost/afio/v2/afio.hpp>

Example
namespace afio = BOOST_AFIO_V2_NAMESPACE;
namespace asio = BOOST_AFIO_V2_NAMESPACE::asio;

// Set a dispatcher as current for this thread
afio::current_dispatcher_guard h(afio::make_dispatcher().get());

// Schedule an opening of a file called example_file.txt
afio::future<> openfile = afio::async_file(
"example_file.txt", afio::file_flags::create | afio::file_flags::read_write);

// Something a bit surprising for many people is that writing off
// the end of a file in AFIO does NOT extend the file and writes
// which go past the end will simply fail instead. Why not?
// Simple: that's the convention with async file i/o, because
// synchronising multiple processes concurrently adjusting a
// file's length has significant overhead which is wasted if you
// don't need that functionality. Luckily, there is an easy
// workaround: either open a file for append-only access, in which
// case all writes extend the file for you, or else you explicitly
// extend files before writing, like this:
afio::future<> resizedfile = afio::async_truncate(openfile, 12);

// Config a write gather. You could do this of course as a batch
// of writes, but a write gather has optimised host OS support in most
// cases, so it's one syscall instead of many.
std::vector<asio::const_buffer> buffers;
buffers.push_back(asio::const_buffer("He", 2));
buffers.push_back(asio::const_buffer("ll", 2));
buffers.push_back(asio::const_buffer("o ", 2));
buffers.push_back(asio::const_buffer("Wo", 2));
buffers.push_back(asio::const_buffer("rl", 2));
buffers.push_back(asio::const_buffer("d\n", 2));
// Schedule the write gather to offset zero after the resize file
afio::future<> written(afio::async_write(resizedfile, buffers, 0));

// Have the compiler config the exact same write gather as earlier for you
// The compiler assembles an identical sequence of ASIO write gather
// buffers for you
std::vector<std::string> buffers2 = {"He", "ll", "o ", "Wo", "rl", "d\n"};
// Schedule this to occur after the previous write completes
afio::future<> written2(afio::async_write(written, buffers2, 0));

// Schedule making sure the previous batch has definitely reached physical
// storage
// This won't complete until the write is on disc
afio::future<> stored(afio::async_sync(written2));

// Schedule filling this array from the file. Note how convenient std::array
// is and completely replaces C style char buffer[bytes]
std::array<char, 12> buffer;
afio::future<> read(afio::async_read(stored, buffer, 0));

// Schedule the closing and deleting of example_file.txt after the contents read
afio::future<> deletedfile(afio::async_rmfile(afio::async_close(read)));

// Wait until the buffer has been filled, checking all steps for errors
afio::when_all_p(openfile, resizedfile, written, written2, stored, read)
.get(); 1

// There is actually a io_req<std::string> specialisation you
// can use to skip this bit by reading directly into a string ...
std::string contents(buffer.begin(), buffer.end());
std::cout << "Contents of file is '" << contents << "'" << std::endl;

// Check remaining ops for errors
deletedfile.get();

1

waits for file open, resize, write, sync and read to complete, throwing any exceptions encountered


PrevUpHomeNext