LLFIO v2.00
Loading...
Searching...
No Matches
llfio_v2_xxx::listening_tls_socket_handle Class Referenceabstract

A handle to a TLS socket-like entity able to receive incoming connections. More...

#include "tls_socket_handle.hpp"

Inheritance diagram for llfio_v2_xxx::listening_tls_socket_handle:
llfio_v2_xxx::listening_socket_handle_buffer_types_injector< listening_byte_socket_handle, tls_socket_handle_ptr > llfio_v2_xxx::listening_byte_socket_handle llfio_v2_xxx::listening_socket_handle_buffer_types_injector< handle, byte_socket_handle > llfio_v2_xxx::pollable_handle llfio_v2_xxx::handle

Public Types

using buffer_type = std::pair< tls_socket_handle_ptr, ip::address >
 The buffer type used by this handle, which is a pair of SocketType and ip::address
 
using const_buffer_type = std::pair< tls_socket_handle_ptr, ip::address >
 The const buffer type used by this handle, which is a pair of SocketType and ip::address
 
using const_buffers_type = buffers_type
 The const buffers type used by this handle for reads, which is a single item sequence of buffer_type.
 
using io_result = result< T >
 
using awaitable = byte_io_multiplexer::awaitable< T >
 
enum class  mode : unsigned char {
  unchanged = 0 , none = 2 , attr_read = 4 , attr_write = 5 ,
  read = 6 , write , append = 9
}
 The behaviour of the handle: does it read, read and write, or atomic append? More...
 
enum class  creation : unsigned char {
  open_existing = 0 , only_if_not_exist , if_needed , truncate_existing ,
  always_new
}
 On opening, do we also create a new file or truncate an existing one? More...
 
enum class  caching : unsigned char {
  unchanged = 0 , none , only_metadata , reads ,
  reads_and_metadata , all , safety_barriers , temporary
}
 What i/o on the handle may complete immediately due to kernel caching. More...
 
using path_type = filesystem::path
 The path type used by this handle.
 
using extent_type = unsigned long long
 The file extent type used by this handle.
 
using size_type = size_t
 The memory extent type used by this handle.
 

Public Member Functions

virtual std::string algorithms_description () const =0
 Returns an implementation defined string describing the algorithms to be chosen during connection. Can be an empty string if the implementation has no mechanism for determining the algorithms available.
 
virtual result< void > set_registered_buffer_chunk_size (size_t bytes) noexcept=0
 Sets the chunk size for registered buffer allocation.
 
virtual result< void > set_algorithms (tls_algorithm set) noexcept=0
 Sets the algorithms to be used by the TLS connection.
 
virtual result< void > set_authentication_certificates_path (path_view identifier) noexcept=0
 Sets the CA certificates by which this listening socket identifies itself to clients. Defaults to the system certificates store.
 
result< buffers_type > read (io_request< buffers_type > req, deadline d={}) noexcept
 
awaitable< io_result< buffers_type > > co_read (io_request< buffers_type > reqs, deadline d={}) noexcept
 A coroutinised equivalent to .read() which suspends the coroutine until a new incoming connection occurs. Blocks execution i.e is equivalent to .read() if no i/o multiplexer has been set on this handle!
 
virtual void _deleter ()
 
void swap (listening_byte_socket_handle &o) noexcept
 Swap with another instance.
 
void swap (handle &o) noexcept
 Swap with another instance.
 
virtual result< void > close () noexcept override
 Immediately close the native handle type managed by this handle.
 
byte_io_multiplexermultiplexer () const noexcept
 The i/o multiplexer this handle will use to multiplex i/o. If this returns null, then this handle has not been registered with an i/o multiplexer yet.
 
virtual result< void > set_multiplexer (byte_io_multiplexer *c=this_thread::multiplexer()) noexcept
 Sets the i/o multiplexer this handle will use to implement read(), write() and barrier().
 
ip::family family () const noexcept
 Returns the IP family of this socket instance.
 
virtual result< ip::addresslocal_endpoint () const noexcept
 Returns the local endpoint of this socket instance.
 
virtual result< void > bind (const ip::address &addr, creation _creation=creation::only_if_not_exist, int backlog=-1) noexcept
 Binds a socket to a local endpoint and sets the socket to listen for new connections.
 
 QUICKCPPLIB_BITFIELD_BEGIN_T (flag, uint16_t)
 Bitwise flags which can be specified.
 
virtual result< path_typecurrent_path () const noexcept
 
result< handleclone () const noexcept
 
virtual native_handle_type release () noexcept
 Release the native handle type managed by this handle.
 
bool is_valid () const noexcept
 True if the handle is valid (and usually open)
 
bool is_readable () const noexcept
 True if the handle is readable.
 
bool is_writable () const noexcept
 True if the handle is writable.
 
bool is_append_only () const noexcept
 True if the handle is append only.
 
virtual result< void > set_append_only (bool enable) noexcept
 EXTENSION: Changes whether this handle is append only or not.
 
bool is_multiplexable () const noexcept
 True if multiplexable.
 
bool is_nonblocking () const noexcept
 True if nonblocking.
 
bool is_seekable () const noexcept
 True if seekable.
 
bool requires_aligned_io () const noexcept
 True if requires aligned i/o.
 
bool is_kernel_handle () const noexcept
 True if native_handle() is a valid kernel handle.
 
bool is_regular () const noexcept
 True if a regular file or device.
 
bool is_directory () const noexcept
 True if a directory.
 
bool is_symlink () const noexcept
 True if a symlink.
 
bool is_pipe () const noexcept
 True if a pipe.
 
bool is_socket () const noexcept
 True if a socket.
 
bool is_multiplexer () const noexcept
 True if a multiplexer like BSD kqueues, Linux epoll or Windows IOCP.
 
bool is_process () const noexcept
 True if a process.
 
bool is_section () const noexcept
 True if a memory section.
 
bool is_allocation () const noexcept
 True if a memory allocation.
 
bool is_path () const noexcept
 True if a path or a directory.
 
bool is_tls_socket () const noexcept
 True if a TLS socket.
 
bool is_http_socket () const noexcept
 True if a HTTP socket.
 
caching kernel_caching () const noexcept
 Kernel cache strategy used by this handle.
 
bool are_reads_from_cache () const noexcept
 True if the handle uses the kernel page cache for reads.
 
bool are_writes_durable () const noexcept
 True if writes are safely on storage on completion.
 
bool are_safety_barriers_issued () const noexcept
 True if issuing safety fsyncs is on.
 
flag flags () const noexcept
 The flags this handle was opened with.
 
native_handle_type native_handle () const noexcept
 The native handle used by this handle.
 

Static Public Member Functions

static result< listening_byte_socket_handlelistening_byte_socket (ip::family _family, mode _mode=mode::write, caching _caching=caching::all, flag flags=flag::none) noexcept
 
static result< listening_byte_socket_handlemultiplexable_listening_byte_socket (ip::family _family, mode _mode=mode::write, caching _caching=caching::all, flag flags=flag::multiplexable) noexcept
 Convenience function defaulting flag::multiplexable set.
 

Protected Member Functions

 listening_tls_socket_handle (listening_byte_socket_handle &&sock)
 
virtual result< buffers_type > _do_read (io_request< buffers_type > req, deadline d) noexcept=0
 
virtual io_result< buffers_type > _do_multiplexer_read (io_request< buffers_type > reqs, deadline d) noexcept=0
 
template<class Impl >
result< typename Impl::buffers_type > _underlying_read (typename Impl::template io_request< typename Impl::buffers_type > req, deadline d) noexcept
 

Protected Attributes

byte_io_multiplexer_ctx {nullptr}
 

Detailed Description

A handle to a TLS socket-like entity able to receive incoming connections.

As you cannot create one of these on your own, one generally acquires one of these from a tls_socket_source.

Member Enumeration Documentation

◆ caching

enum class llfio_v2_xxx::handle::caching : unsigned char
stronginherited

What i/o on the handle may complete immediately due to kernel caching.

Enumerator
none 

No caching whatsoever, all reads and writes come from storage (i.e. O_DIRECT|O_SYNC). Align all i/o to 4Kb boundaries for this to work. disable_safety_barriers can be used here.

only_metadata 

Cache reads and writes of metadata but avoid caching data (O_DIRECT), thus i/o here does not affect other cached data for other handles. Align all i/o to 4Kb boundaries for this to work.

reads 

Cache reads only. Writes of data and metadata do not complete until reaching storage (O_SYNC). disable_safety_barriers can be used here.

reads_and_metadata 

Cache reads and writes of metadata, but writes of data do not complete until reaching storage (O_DSYNC). disable_safety_barriers can be used here.

all 

Cache reads and writes of data and metadata so they complete immediately, sending writes to storage at some point when the kernel decides (this is the default file system caching on a system).

safety_barriers 

Cache reads and writes of data and metadata so they complete immediately, but issue safety barriers at certain points. See documentation for disable_safety_barriers.

temporary 

Cache reads and writes of data and metadata so they complete immediately, only sending any updates to storage on last handle close in the system or if memory becomes tight as this file is expected to be temporary (Windows and FreeBSD only).

97 {
98 unchanged = 0,
99 none =
100 1, //!< No caching whatsoever, all reads and writes come from storage (i.e. <tt>O_DIRECT|O_SYNC</tt>). Align all i/o to 4Kb boundaries for this to work. <tt>disable_safety_barriers</tt> can be used here.
102 2, //!< Cache reads and writes of metadata but avoid caching data (<tt>O_DIRECT</tt>), thus i/o here does not affect other cached data for other handles. Align all i/o to 4Kb boundaries for this to work.
103 reads =
104 3, //!< Cache reads only. Writes of data and metadata do not complete until reaching storage (<tt>O_SYNC</tt>). <tt>disable_safety_barriers</tt> can be used here.
106 5, //!< Cache reads and writes of metadata, but writes of data do not complete until reaching storage (<tt>O_DSYNC</tt>). <tt>disable_safety_barriers</tt> can be used here.
107 all =
108 6, //!< Cache reads and writes of data and metadata so they complete immediately, sending writes to storage at some point when the kernel decides (this is the default file system caching on a system).
110 7, //!< Cache reads and writes of data and metadata so they complete immediately, but issue safety barriers at certain points. See documentation for <tt>disable_safety_barriers</tt>.
111 temporary =
112 8 //!< Cache reads and writes of data and metadata so they complete immediately, only sending any updates to storage on last handle close in the system or if memory becomes tight as this file is expected to be temporary (Windows and FreeBSD only).
113 // NOTE: IF UPDATING THIS UPDATE THE std::ostream PRINTER BELOW!!!
114 };
@ none
No ability to read or write anything, but can synchronise (SYNCHRONIZE or 0)
@ reads
Cache reads only. Writes of data and metadata do not complete until reaching storage (O_SYNC)....
@ safety_barriers
Cache reads and writes of data and metadata so they complete immediately, but issue safety barriers a...
@ all
Cache reads and writes of data and metadata so they complete immediately, sending writes to storage a...
@ only_metadata
Cache reads and writes of metadata but avoid caching data (O_DIRECT), thus i/o here does not affect o...
@ temporary
Cache reads and writes of data and metadata so they complete immediately, only sending any updates to...
@ reads_and_metadata
Cache reads and writes of metadata, but writes of data do not complete until reaching storage (O_DSYN...

◆ creation

enum class llfio_v2_xxx::handle::creation : unsigned char
stronginherited

On opening, do we also create a new file or truncate an existing one?

Enumerator
open_existing 

Filesystem entry must already exist.

only_if_not_exist 

Filesystem entry must NOT exist, and is atomically created by the success of this operation.

if_needed 

If filesystem entry exists that is used, else one is created.

truncate_existing 

Filesystem entry must already exist. It is atomically truncated on open, leaving creation date and unique identifier unmodified.

always_new 

If filesystem entry exists, it is atomically replaced with a new inode, else a new entry is created.

87 {
88 open_existing = 0, //!< Filesystem entry must already exist
89 only_if_not_exist, //!< Filesystem entry must NOT exist, and is atomically created by the success of this operation
90 if_needed, //!< If filesystem entry exists that is used, else one is created
91 truncate_existing, //!< Filesystem entry must already exist. It is atomically truncated on open, leaving creation date and unique identifier unmodified.
92 always_new //!< If filesystem entry exists, it is atomically replaced with a new inode, else a new entry is created.
93 // NOTE: IF UPDATING THIS UPDATE THE std::ostream PRINTER BELOW!!!
94 };
@ if_needed
If filesystem entry exists that is used, else one is created.
@ open_existing
Filesystem entry must already exist.
@ truncate_existing
Filesystem entry must already exist. It is atomically truncated on open, leaving creation date and un...
@ only_if_not_exist
Filesystem entry must NOT exist, and is atomically created by the success of this operation.
@ always_new
If filesystem entry exists, it is atomically replaced with a new inode, else a new entry is created.

◆ mode

enum class llfio_v2_xxx::handle::mode : unsigned char
stronginherited

The behaviour of the handle: does it read, read and write, or atomic append?

Enumerator
none 

No ability to read or write anything, but can synchronise (SYNCHRONIZE or 0)

attr_read 

Ability to read attributes (FILE_READ_ATTRIBUTES|SYNCHRONIZE or O_RDONLY)

attr_write 

Ability to read and write attributes (FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|SYNCHRONIZE or O_RDONLY)

read 

Ability to read (READ_CONTROL|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|SYNCHRONISE or O_RDONLY)

write 

Ability to read and write (READ_CONTROL|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONISE or O_RDWR)

append 

All mainstream OSs and CIFS guarantee this is atomic with respect to all other appenders (FILE_APPEND_DATA|SYNCHRONISE or O_APPEND)

74 {
75 unchanged = 0,
76 none = 2, //!< No ability to read or write anything, but can synchronise (SYNCHRONIZE or 0)
77 attr_read = 4, //!< Ability to read attributes (FILE_READ_ATTRIBUTES|SYNCHRONIZE or O_RDONLY)
78 attr_write = 5, //!< Ability to read and write attributes (FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|SYNCHRONIZE or O_RDONLY)
79 read = 6, //!< Ability to read (READ_CONTROL|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|SYNCHRONISE or O_RDONLY)
80 write =
81 7, //!< Ability to read and write (READ_CONTROL|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONISE or O_RDWR)
82 append = 9 //!< All mainstream OSs and CIFS guarantee this is atomic with respect to all other appenders (FILE_APPEND_DATA|SYNCHRONISE or O_APPEND)
83 // NOTE: IF UPDATING THIS UPDATE THE std::ostream PRINTER BELOW!!!
84 };
@ append
All mainstream OSs and CIFS guarantee this is atomic with respect to all other appenders (FILE_APPEND...
@ attr_write
Ability to read and write attributes (FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|SYNCHRONIZE or O_RDO...
@ attr_read
Ability to read attributes (FILE_READ_ATTRIBUTES|SYNCHRONIZE or O_RDONLY)
@ read
Ability to read (READ_CONTROL|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|SYNCHRONISE or O_RDONL...
@ write
Ability to read and write (READ_CONTROL|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_WRITE_D...

Constructor & Destructor Documentation

◆ listening_tls_socket_handle() [1/2]

constexpr llfio_v2_xxx::listening_tls_socket_handle::listening_tls_socket_handle ( )
inlineconstexprprotected
211{}

◆ listening_tls_socket_handle() [2/2]

llfio_v2_xxx::listening_tls_socket_handle::listening_tls_socket_handle ( listening_byte_socket_handle &&  sock)
inlineexplicitprotected
213 : _base(sock.release(), sock.flags(), sock.multiplexer())
214 {
215 this->_v.behaviour |= native_handle_type::disposition::tls_socket;
216 }

Member Function Documentation

◆ _deleter()

virtual void llfio_v2_xxx::listening_byte_socket_handle::_deleter ( )
inlinevirtualinherited
871{ delete this; }

◆ _do_multiplexer_read()

virtual io_result< buffers_type > llfio_v2_xxx::listening_tls_socket_handle::_do_multiplexer_read ( io_request< buffers_type >  reqs,
deadline  d 
)
protectedpure virtualnoexcept

◆ _do_read()

virtual result< buffers_type > llfio_v2_xxx::listening_tls_socket_handle::_do_read ( io_request< buffers_type >  req,
deadline  d 
)
protectedpure virtualnoexcept

◆ _underlying_read()

template<class Impl >
result< typename Impl::buffers_type > llfio_v2_xxx::listening_byte_socket_handle::_underlying_read ( typename Impl::template io_request< typename Impl::buffers_type >  req,
deadline  d 
)
inlineprotectednoexceptinherited
860 {
861 if(_v.behaviour & native_handle_type::disposition::is_pointer)
862 {
863 return reinterpret_cast<Impl *>(_v.ptr)->read(std::move(req), d);
864 }
865 auto *sock = static_cast<Impl *>(static_cast<handle *>(this));
866 return (_ctx == nullptr) ? sock->Impl::_do_read(std::move(req), d) : sock->Impl::_do_multiplexer_read(std::move(req), d);
867 }
constexpr handle()
Default constructor.
Definition handle.hpp:229

◆ are_reads_from_cache()

bool llfio_v2_xxx::handle::are_reads_from_cache ( ) const
inlinenoexceptinherited

True if the handle uses the kernel page cache for reads.

416{ return !!(_v.behaviour & native_handle_type::disposition::cache_reads); }

◆ are_safety_barriers_issued()

bool llfio_v2_xxx::handle::are_safety_barriers_issued ( ) const
inlinenoexceptinherited

True if issuing safety fsyncs is on.

420{ return !!(_v.behaviour & native_handle_type::disposition::safety_barriers); }

◆ are_writes_durable()

bool llfio_v2_xxx::handle::are_writes_durable ( ) const
inlinenoexceptinherited

True if writes are safely on storage on completion.

418{ return !(_v.behaviour & native_handle_type::disposition::cache_writes); }

◆ bind()

virtual result< void > llfio_v2_xxx::listening_byte_socket_handle::bind ( const ip::address addr,
creation  _creation = creation::only_if_not_exist,
int  backlog = -1 
)
virtualnoexceptinherited

Binds a socket to a local endpoint and sets the socket to listen for new connections.

Parameters
addrThe local endpoint to which to bind the socket.
_creationWhether to apply SO_REUSEADDR before binding.
backlogThe maximum queue length of pending connections. -1 chooses SOMAXCONN.

You should set any socket options etc that you need on native_handle() before binding the socket to its local endpoint.

Errors returnable
Any of the values bind() and listen() can return.

◆ clone()

result< handle > llfio_v2_xxx::handle::clone ( ) const
noexceptinherited

Clone this handle (copy constructor is disabled to avoid accidental copying)

Errors returnable
Any of the values POSIX dup() or DuplicateHandle() can return.

◆ close()

virtual result< void > llfio_v2_xxx::listening_byte_socket_handle::close ( )
inlineoverridevirtualnoexceptinherited

Immediately close the native handle type managed by this handle.

Reimplemented from llfio_v2_xxx::handle.

977 {
978 LLFIO_LOG_FUNCTION_CALL(this);
979 if(_ctx != nullptr)
980 {
981 OUTCOME_TRY(set_multiplexer(nullptr));
982 }
983#ifndef NDEBUG
984 if(_v)
985 {
986 // Tell handle::close() that we have correctly executed
987 _v.behaviour |= native_handle_type::disposition::_child_close_executed;
988 }
989#endif
990 auto ret = handle::close();
991#ifdef _WIN32
992 if(_v)
993 {
994 detail::unregister_socket_handle_instance(this);
995 }
996#endif
997 return ret;
998 }
virtual result< void > close() noexcept
Immediately close the native handle type managed by this handle.
virtual result< void > set_multiplexer(byte_io_multiplexer *c=this_thread::multiplexer()) noexcept
Sets the i/o multiplexer this handle will use to implement read(), write() and barrier().
Definition byte_socket_handle.hpp:1018

◆ co_read()

awaitable< io_result< buffers_type > > llfio_v2_xxx::listening_tls_socket_handle::co_read ( io_request< buffers_type >  reqs,
deadline  d = {} 
)
noexcept

A coroutinised equivalent to .read() which suspends the coroutine until a new incoming connection occurs. Blocks execution i.e is equivalent to .read() if no i/o multiplexer has been set on this handle!

The awaitable returned is eager i.e. it immediately begins the i/o. If the i/o completes and finishes immediately, no coroutine suspension occurs.

◆ current_path()

virtual result< path_type > llfio_v2_xxx::handle::current_path ( ) const
virtualnoexceptinherited

Returns the current path of the open handle as said by the operating system. Note that you are NOT guaranteed that any path refreshed bears any resemblance to the original, some operating systems will return some different path which still reaches the same inode via some other route e.g. hardlinks, dereferenced symbolic links, etc. Windows and Linux correctly track changes to the specific path the handle was opened with, not getting confused by other hard links. MacOS nearly gets it right, but under some circumstances e.g. renaming may switch to a different hard link's path which is almost certainly a bug.

If LLFIO was not able to determine the current path for this open handle e.g. the inode has been unlinked, it returns an empty path. Be aware that FreeBSD can return an empty (deleted) path for file inodes no longer cached by the kernel path cache, LLFIO cannot detect the difference. FreeBSD will also return any path leading to the inode if it is hard linked. FreeBSD does implement path retrieval for directory inodes correctly however, and see algorithm::cached_parent_handle_adapter<T> for a handle adapter which makes use of that.

On Linux if /proc is not mounted, this call fails with an error. All APIs in LLFIO which require the use of current_path() can be told to not use it e.g. flag::disable_safety_unlinks. It is up to you to detect if current_path() is not working, and to change how you call LLFIO appropriately.

On Windows, you will almost certainly get back a path of the form \!!\Device\HarddiskVolume10\Users\ned\.... See path_view for what all the path prefix sequences mean, but to summarise the \!!\ prefix is LLFIO-only and will not be accepted by other Windows APIs. Pass LLFIO derived paths through the function to_win32_path() to Win32-ise them. This function is also available on Linux where it does nothing, so you can use it in portable code.

Warning
This call is expensive, it always asks the kernel for the current path, and no checking is done to ensure what the kernel returns is accurate or even sensible. Be aware that despite these precautions, paths are unstable and can change randomly at any moment. Most code written to use absolute file systems paths is racy, so don't do it, use path_handle to fix a base location on the file system and work from that anchor instead!
Memory Allocations
At least one malloc for the path_type, likely several more.
See also
algorithm::cached_parent_handle_adapter<T> which overrides this with an implementation based on retrieving the current path of a cached handle to the parent directory. On platforms with instability or failure to retrieve the correct current path for regular files, the cached parent handle adapter works around the problem by taking advantage of directory inodes not having the same instability problems on any platform.

Reimplemented in llfio_v2_xxx::process_handle.

◆ family()

ip::family llfio_v2_xxx::listening_byte_socket_handle::family ( ) const
inlinenoexceptinherited

Returns the IP family of this socket instance.

1074{ return (this->_v.behaviour & native_handle_type::disposition::is_alternate) ? ip::family::v6 : ip::family::v4; }

◆ flags()

flag llfio_v2_xxx::handle::flags ( ) const
inlinenoexceptinherited

The flags this handle was opened with.

423{ return _.flags; }

◆ is_allocation()

bool llfio_v2_xxx::handle::is_allocation ( ) const
inlinenoexceptinherited

True if a memory allocation.

377{ return _v.is_allocation(); }

◆ is_append_only()

bool llfio_v2_xxx::handle::is_append_only ( ) const
inlinenoexceptinherited

True if the handle is append only.

336{ return _v.is_append_only(); }

◆ is_directory()

bool llfio_v2_xxx::handle::is_directory ( ) const
inlinenoexceptinherited

True if a directory.

363{ return _v.is_directory(); }

◆ is_http_socket()

bool llfio_v2_xxx::handle::is_http_socket ( ) const
inlinenoexceptinherited

True if a HTTP socket.

383{ return _v.is_http_socket(); }

◆ is_kernel_handle()

bool llfio_v2_xxx::handle::is_kernel_handle ( ) const
inlinenoexceptinherited

True if native_handle() is a valid kernel handle.

358{ return _v.is_kernel_handle(); }

◆ is_multiplexable()

bool llfio_v2_xxx::handle::is_multiplexable ( ) const
inlinenoexceptinherited

True if multiplexable.

350{ return !!(_.flags & flag::multiplexable); }

◆ is_multiplexer()

bool llfio_v2_xxx::handle::is_multiplexer ( ) const
inlinenoexceptinherited

True if a multiplexer like BSD kqueues, Linux epoll or Windows IOCP.

371{ return _v.is_multiplexer(); }

◆ is_nonblocking()

bool llfio_v2_xxx::handle::is_nonblocking ( ) const
inlinenoexceptinherited

True if nonblocking.

352{ return _v.is_nonblocking(); }

◆ is_path()

bool llfio_v2_xxx::handle::is_path ( ) const
inlinenoexceptinherited

True if a path or a directory.

379{ return _v.is_path(); }

◆ is_pipe()

bool llfio_v2_xxx::handle::is_pipe ( ) const
inlinenoexceptinherited

True if a pipe.

367{ return _v.is_pipe(); }

◆ is_process()

bool llfio_v2_xxx::handle::is_process ( ) const
inlinenoexceptinherited

True if a process.

373{ return _v.is_process(); }

◆ is_readable()

bool llfio_v2_xxx::handle::is_readable ( ) const
inlinenoexceptinherited

True if the handle is readable.

332{ return _v.is_readable(); }

◆ is_regular()

bool llfio_v2_xxx::handle::is_regular ( ) const
inlinenoexceptinherited

True if a regular file or device.

361{ return _v.is_regular(); }

◆ is_section()

bool llfio_v2_xxx::handle::is_section ( ) const
inlinenoexceptinherited

True if a memory section.

375{ return _v.is_section(); }

◆ is_seekable()

bool llfio_v2_xxx::handle::is_seekable ( ) const
inlinenoexceptinherited

True if seekable.

354{ return _v.is_seekable(); }

◆ is_socket()

bool llfio_v2_xxx::handle::is_socket ( ) const
inlinenoexceptinherited

True if a socket.

369{ return _v.is_socket(); }

◆ is_symlink()

bool llfio_v2_xxx::handle::is_symlink ( ) const
inlinenoexceptinherited

True if a symlink.

365{ return _v.is_symlink(); }

◆ is_tls_socket()

bool llfio_v2_xxx::handle::is_tls_socket ( ) const
inlinenoexceptinherited

True if a TLS socket.

381{ return _v.is_tls_socket(); }

◆ is_valid()

bool llfio_v2_xxx::handle::is_valid ( ) const
inlinenoexceptinherited

True if the handle is valid (and usually open)

329{ return _v.is_valid(); }

◆ is_writable()

bool llfio_v2_xxx::handle::is_writable ( ) const
inlinenoexceptinherited

True if the handle is writable.

334{ return _v.is_writable(); }

◆ kernel_caching()

caching llfio_v2_xxx::handle::kernel_caching ( ) const
inlinenoexceptinherited

Kernel cache strategy used by this handle.

387 {
388 const bool safety_barriers = !!(_v.behaviour & native_handle_type::disposition::safety_barriers);
389 const bool cache_metadata = !!(_v.behaviour & native_handle_type::disposition::cache_metadata);
390 const bool cache_reads = !!(_v.behaviour & native_handle_type::disposition::cache_reads);
391 const bool cache_writes = !!(_v.behaviour & native_handle_type::disposition::cache_writes);
392 const bool cache_temporary = !!(_v.behaviour & native_handle_type::disposition::cache_temporary);
393 if(cache_temporary)
394 {
395 return caching::temporary;
396 }
397 if(cache_metadata && cache_reads && cache_writes)
398 {
400 }
401 if(cache_metadata && cache_reads)
402 {
404 }
405 if(cache_reads)
406 {
407 return caching::reads;
408 }
409 if(cache_metadata)
410 {
412 }
413 return caching::none;
414 }
@ none
No caching whatsoever, all reads and writes come from storage (i.e. O_DIRECT|O_SYNC)....

◆ listening_byte_socket()

static result< listening_byte_socket_handle > llfio_v2_xxx::listening_byte_socket_handle::listening_byte_socket ( ip::family  _family,
mode  _mode = mode::write,
caching  _caching = caching::all,
flag  flags = flag::none 
)
staticnoexceptinherited

Create a listening socket handle.

Parameters
_familyWhich IP family to create the socket in.
_modeHow to open the socket. If this is mode::append, the read side of the socket is shutdown; if this is mode::read, the write side of the socket is shutdown.
_cachingHow to ask the kernel to cache the socket. If writes are not cached, SO_SNDBUF to the minimum possible value and TCP_NODELAY is set, this should cause writes to hit the network as quickly as possible.
flagsAny additional custom behaviours.
Errors returnable
Any of the values POSIX socket() or WSASocket() can return.

◆ multiplexable_listening_byte_socket()

static result< listening_byte_socket_handle > llfio_v2_xxx::listening_byte_socket_handle::multiplexable_listening_byte_socket ( ip::family  _family,
mode  _mode = mode::write,
caching  _caching = caching::all,
flag  flags = flag::multiplexable 
)
inlinestaticnoexceptinherited

Convenience function defaulting flag::multiplexable set.

1068 {
1069 return listening_byte_socket(_family, _mode, _caching, flags);
1070 }
flag flags() const noexcept
The flags this handle was opened with.
Definition handle.hpp:423
static result< listening_byte_socket_handle > listening_byte_socket(ip::family _family, mode _mode=mode::write, caching _caching=caching::all, flag flags=flag::none) noexcept

◆ multiplexer()

byte_io_multiplexer * llfio_v2_xxx::listening_byte_socket_handle::multiplexer ( ) const
inlinenoexceptinherited

The i/o multiplexer this handle will use to multiplex i/o. If this returns null, then this handle has not been registered with an i/o multiplexer yet.

1004{ return _ctx; }

◆ native_handle()

native_handle_type llfio_v2_xxx::handle::native_handle ( ) const
inlinenoexceptinherited

The native handle used by this handle.

425{ return _v; }

◆ QUICKCPPLIB_BITFIELD_BEGIN_T()

llfio_v2_xxx::handle::QUICKCPPLIB_BITFIELD_BEGIN_T ( flag  ,
uint16_t   
)
inlineinherited

Bitwise flags which can be specified.

< No flags

Unlinks the file on handle close. On POSIX, this simply unlinks whatever is pointed to by path() upon the call of close() if and only if the inode matches. On Windows, if you are on Windows 10 1709 or later, exactly the same thing occurs. If on previous editions of Windows, the file entry does not disappears but becomes unavailable for anyone else to open with an errc::resource_unavailable_try_again error return. Because this is confusing, unless the win_disable_unlink_emulation flag is also specified, this POSIX behaviour is somewhat emulated by LLFIO on older Windows by renaming the file to a random name on close() causing it to appear to have been unlinked immediately.

Some kernel caching modes have unhelpfully inconsistent behaviours in getting your data onto storage, so by default unless this flag is specified LLFIO adds extra fsyncs to the following operations for the caching modes specified below: truncation of file length either explicitly or during file open. closing of the handle either explicitly or in the destructor.

Additionally on Linux only to prevent loss of file metadata: On the parent directory whenever a file might have been created. On the parent directory on file close.

This only occurs for these kernel caching modes: caching::none caching::reads caching::reads_and_metadata caching::safety_barriers

file_handle::unlink() could accidentally delete the wrong file if someone has renamed the open file handle since the time it was opened. To prevent this occuring, where the OS doesn't provide race free unlink-by-open-handle we compare the inode of the path we are about to unlink with that of the open handle before unlinking.

Warning
This does not prevent races where in between the time of checking the inode and executing the unlink a third party changes the item about to be unlinked. Only operating systems with a true race-free unlink syscall are race free.

Ask the OS to disable prefetching of data. This can improve random i/o performance.

Ask the OS to maximise prefetching of data, possibly prefetching the entire file into kernel cache. This can improve sequential i/o performance.

< See the documentation for unlink_on_first_close

Microsoft Windows NTFS, having been created in the late 1980s, did not originally implement extents-based storage and thus could only represent sparse files via efficient compression of intermediate zeros. With NTFS v3.0 (Microsoft Windows 2000), a proper extents-based on-storage representation was added, thus allowing only 64Kb extent chunks written to be stored irrespective of whatever the maximum file extent was set to.

For various historical reasons, extents-based storage is disabled by default in newly created files on NTFS, unlike in almost every other major filing system. You have to explicitly "opt in" to extents-based storage.

As extents-based storage is nearly cost free on NTFS, LLFIO by default opts in to extents-based storage for any empty file it creates. If you don't want this, you can specify this flag to prevent that happening.

Filesystems tend to be embarrassingly parallel for operations performed to different inodes. Where LLFIO performs i/o to multiple inodes at a time, it will use OpenMP or the Parallelism or Concurrency standard library extensions to usually complete the operation in constant rather than linear time. If you don't want this default, you can disable default using this flag.

Microsoft Windows NTFS has the option, when creating a directory, to set whether leafname lookup will be case sensitive. This is the only way of getting exact POSIX semantics on Windows without resorting to editing the system registry, however it also affects all code doing lookups within that directory, so we must default it to off.

Create the handle in a way where i/o upon it can be multiplexed with other i/o on the same initiating thread of execution i.e. you can perform more than one read concurrently, without using threads. The blocking operations .read() and .write() may have to use a less efficient, but cancellable, blocking implementation for handles created in this way. On Microsoft Windows, this creates handles with OVERLAPPED semantics. On POSIX, this creates handles with nonblocking semantics for non-file handles such as pipes and sockets, however for file, directory and symlink handles it does not set nonblocking, as it is non-portable.

< Using insane POSIX byte range locks

< This is an inode created with no representation on the filing system

116 {
117none = uint16_t(0), //!< No flags
118/*! Unlinks the file on handle close. On POSIX, this simply unlinks whatever is pointed
119to by `path()` upon the call of `close()` if and only if the inode matches. On Windows,
120if you are on Windows 10 1709 or later, exactly the same thing occurs. If on previous
121editions of Windows, the file entry does not disappears but becomes unavailable for
122anyone else to open with an `errc::resource_unavailable_try_again` error return. Because this is confusing, unless the
123`win_disable_unlink_emulation` flag is also specified, this POSIX behaviour is
124somewhat emulated by LLFIO on older Windows by renaming the file to a random name on `close()`
125causing it to appear to have been unlinked immediately.
126*/
127unlink_on_first_close = uint16_t(1U << 0U),
128
129/*! Some kernel caching modes have unhelpfully inconsistent behaviours
130in getting your data onto storage, so by default unless this flag is
131specified LLFIO adds extra fsyncs to the following operations for the
132caching modes specified below:
133* truncation of file length either explicitly or during file open.
134* closing of the handle either explicitly or in the destructor.
135
136Additionally on Linux only to prevent loss of file metadata:
137* On the parent directory whenever a file might have been created.
138* On the parent directory on file close.
139
140This only occurs for these kernel caching modes:
141* caching::none
142* caching::reads
143* caching::reads_and_metadata
144* caching::safety_barriers
145*/
146disable_safety_barriers = uint16_t(1U << 2U),
147/*! `file_handle::unlink()` could accidentally delete the wrong file if someone has
148renamed the open file handle since the time it was opened. To prevent this occuring,
149where the OS doesn't provide race free unlink-by-open-handle we compare the inode of
150the path we are about to unlink with that of the open handle before unlinking.
151\warning This does not prevent races where in between the time of checking the inode
152and executing the unlink a third party changes the item about to be unlinked. Only
153operating systems with a true race-free unlink syscall are race free.
154*/
155disable_safety_unlinks = uint16_t(1U << 3U),
156/*! Ask the OS to disable prefetching of data. This can improve random
157i/o performance.
158*/
159disable_prefetching = uint16_t(1U << 4U),
160/*! Ask the OS to maximise prefetching of data, possibly prefetching the entire file
161into kernel cache. This can improve sequential i/o performance.
162*/
163maximum_prefetching = uint16_t(1U << 5U),
164
165win_disable_unlink_emulation = uint16_t(1U << 9U), //!< See the documentation for `unlink_on_first_close`
166/*! Microsoft Windows NTFS, having been created in the late 1980s, did not originally
167implement extents-based storage and thus could only represent sparse files via
168efficient compression of intermediate zeros. With NTFS v3.0 (Microsoft Windows 2000),
169a proper extents-based on-storage representation was added, thus allowing only 64Kb
170extent chunks written to be stored irrespective of whatever the maximum file extent
171was set to.
172
173For various historical reasons, extents-based storage is disabled by default in newly
174created files on NTFS, unlike in almost every other major filing system. You have to
175explicitly "opt in" to extents-based storage.
176
177As extents-based storage is nearly cost free on NTFS, LLFIO by default opts in to
178extents-based storage for any empty file it creates. If you don't want this, you
179can specify this flag to prevent that happening.
180*/
181win_disable_sparse_file_creation = uint16_t(1U << 10U),
182/*! Filesystems tend to be embarrassingly parallel for operations performed to different
183inodes. Where LLFIO performs i/o to multiple inodes at a time, it will use OpenMP or
184the Parallelism or Concurrency standard library extensions to usually complete the
185operation in constant rather than linear time. If you don't want this default, you can
186disable default using this flag.
187*/
188disable_parallelism = uint16_t(1U << 11U),
189/*! Microsoft Windows NTFS has the option, when creating a directory, to set whether
190leafname lookup will be case sensitive. This is the only way of getting exact POSIX
191semantics on Windows without resorting to editing the system registry, however it also
192affects all code doing lookups within that directory, so we must default it to off.
193*/
194win_create_case_sensitive_directory = uint16_t(1U << 12U),
195
196/*! Create the handle in a way where i/o upon it can be multiplexed with other i/o
197on the same initiating thread of execution i.e. you can perform more than one read
198concurrently, without using threads. The blocking operations `.read()` and `.write()`
199may have to use a less efficient, but cancellable, blocking implementation for handles created
200in this way. On Microsoft Windows, this creates handles with `OVERLAPPED` semantics.
201On POSIX, this creates handles with nonblocking semantics for non-file handles such
202as pipes and sockets, however for file, directory and symlink handles it does not set
203nonblocking, as it is non-portable.
204*/
205multiplexable = uint16_t(1U << 13U),
206
207// NOTE: IF UPDATING THIS UPDATE THE std::ostream PRINTER BELOW!!!
208
209byte_lock_insanity = uint16_t(1U << 14U), //!< Using insane POSIX byte range locks
210anonymous_inode = uint16_t(1U << 15U) //!< This is an inode created with no representation on the filing system
211} QUICKCPPLIB_BITFIELD_END(flag)

◆ read()

result< buffers_type > llfio_v2_xxx::listening_tls_socket_handle::read ( io_request< buffers_type >  req,
deadline  d = {} 
)
inlinenoexcept

Read the contents of the listening socket for newly connected byte sockets.

Returns
Returns the buffers filled, with its socket handle and address set to the newly connected socket.
Parameters
reqA buffer to fill with a newly connected socket.
dAn optional deadline by which to time out.
Errors returnable
Any of the errors which accept() or WSAAccept() might return.
271 {}) noexcept
272 {
273 return (_ctx == nullptr) ? _do_read(std::move(req), d) : _do_multiplexer_read(std::move(req), d);
274 }

◆ release()

virtual native_handle_type llfio_v2_xxx::handle::release ( )
inlinevirtualnoexceptinherited

Release the native handle type managed by this handle.

Reimplemented in llfio_v2_xxx::map_handle, and llfio_v2_xxx::mapped_file_handle.

323 {
324 native_handle_type ret(std::move(_v));
325 return ret;
326 }

◆ requires_aligned_io()

bool llfio_v2_xxx::handle::requires_aligned_io ( ) const
inlinenoexceptinherited

True if requires aligned i/o.

356{ return _v.requires_aligned_io(); }

◆ set_append_only()

virtual result< void > llfio_v2_xxx::handle::set_append_only ( bool  enable)
virtualnoexceptinherited

EXTENSION: Changes whether this handle is append only or not.

Warning
On Windows this is implemented as a bit of a hack to make it fast like on POSIX, so make sure you open the handle for read/write originally. Note unlike on POSIX the append_only disposition will be the only one toggled, seekable and readable will remain turned on.
Errors returnable
Whatever POSIX fcntl() returns. On Windows nothing is changed on the handle.
Memory Allocations
No memory allocation.

Reimplemented in llfio_v2_xxx::process_handle.

◆ set_authentication_certificates_path()

virtual result< void > llfio_v2_xxx::listening_tls_socket_handle::set_authentication_certificates_path ( path_view  identifier)
pure virtualnoexcept

Sets the CA certificates by which this listening socket identifies itself to clients. Defaults to the system certificates store.

Note that setting this to an empty path disables authentication by the server, so server impersonation attacks become possible. This can be useful however for situations where setting up server authentication certificates is non-trivial or unnecessary, and all that is wanted is an encrypted network transport.

Be aware that the path may not be a filesystem path, but some other sort of implementation defined identifier.

◆ set_multiplexer()

virtual result< void > llfio_v2_xxx::listening_byte_socket_handle::set_multiplexer ( byte_io_multiplexer c = this_thread::multiplexer())
inlinevirtualnoexceptinherited

Sets the i/o multiplexer this handle will use to implement read(), write() and barrier().

Note that this call deregisters this handle from any existing i/o multiplexer, and registers it with the new i/o multiplexer. You must therefore not call it if any i/o is currently outstanding on this handle. You should also be aware that multiple dynamic memory allocations and deallocations may occur, as well as multiple syscalls (i.e. this is an expensive call, try to do it from cold code).

If the handle was not created as multiplexable, this call always fails.

Memory Allocations
Multiple dynamic memory allocations and deallocations.
1019 {
1020 if(!is_multiplexable())
1021 {
1022 return errc::operation_not_supported;
1023 }
1024 if(c == _ctx)
1025 {
1026 return success();
1027 }
1028 if(_ctx != nullptr)
1029 {
1030 OUTCOME_TRY(_ctx->do_byte_io_handle_deregister(this));
1031 _ctx = nullptr;
1032 }
1033 if(c != nullptr)
1034 {
1035 OUTCOME_TRY(auto &&state, c->do_byte_io_handle_register(this));
1036 _v.behaviour = (_v.behaviour & ~(native_handle_type::disposition::_multiplexer_state_bit0 | native_handle_type::disposition::_multiplexer_state_bit1));
1037 if((state & 1) != 0)
1038 {
1039 _v.behaviour |= native_handle_type::disposition::_multiplexer_state_bit0;
1040 }
1041 if((state & 2) != 0)
1042 {
1043 _v.behaviour |= native_handle_type::disposition::_multiplexer_state_bit1;
1044 }
1045 }
1046 _ctx = c;
1047 return success();
1048 }
virtual result< void > do_byte_io_handle_deregister(byte_io_handle *) noexcept
Implements byte_io_handle deregistration.
Definition byte_io_multiplexer.hpp:542
bool is_multiplexable() const noexcept
True if multiplexable.
Definition handle.hpp:350

◆ set_registered_buffer_chunk_size()

virtual result< void > llfio_v2_xxx::listening_tls_socket_handle::set_registered_buffer_chunk_size ( size_t  bytes)
pure virtualnoexcept

Sets the chunk size for registered buffer allocation.

Some TLS socket handle implementations are able to use registered buffers from their underlying plain socket. If so, this sets the granularity of registered buffer allocation, otherwise an error is returned if registered buffers are not supported.

◆ swap() [1/2]

void llfio_v2_xxx::handle::swap ( handle o)
inlinenoexceptinherited

Swap with another instance.

263 {
264 handle temp(std::move(*this));
265 *this = std::move(o);
266 o = std::move(temp);
267 }

◆ swap() [2/2]

void llfio_v2_xxx::listening_byte_socket_handle::swap ( listening_byte_socket_handle o)
inlinenoexceptinherited

Swap with another instance.

964 {
965 listening_byte_socket_handle temp(std::move(*this));
966 *this = std::move(o);
967 o = std::move(temp);
968 }
constexpr listening_byte_socket_handle()
Default constructor.
Definition byte_socket_handle.hpp:902

Member Data Documentation

◆ _ctx

byte_io_multiplexer* llfio_v2_xxx::listening_byte_socket_handle::_ctx {nullptr}
protectedinherited
856{nullptr}; // +4 or +8 bytes

The documentation for this class was generated from the following file: