LLFIO
v2.00 late alpha
|
A handle to a source of mapped memory. More...
#include "map_handle.hpp"
Public Types | |
using | extent_type = handle::extent_type |
using | size_type = handle::size_type |
enum | mode : unsigned char { unchanged = 0, mode::none = 2, mode::attr_read = 4, mode::attr_write = 5, mode::read = 6, mode::write = 7, mode::append = 9 } |
The behaviour of the handle: does it read, read and write, or atomic append? More... | |
enum | creation : unsigned char { creation::open_existing = 0, creation::only_if_not_exist, creation::if_needed, creation::truncate_existing, creation::always_new } |
On opening, do we also create a new file or truncate an existing one? More... | |
enum | caching : unsigned char { unchanged = 0, caching::none = 1, caching::only_metadata = 2, caching::reads = 3, caching::reads_and_metadata = 5, caching::all = 6, caching::safety_barriers = 7, caching::temporary = 8 } |
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. | |
Public Member Functions | |
QUICKCPPLIB_BITFIELD_BEGIN (flag) | |
The behaviour of the memory section. More... | |
QUICKCPPLIB_BITFIELD_END (flag) | |
virtual result< void > | close () noexcept override |
Immediately close the native handle type managed by this handle. | |
constexpr | section_handle () |
Default constructor. | |
section_handle (native_handle_type sectionh, file_handle *backing, file_handle anonymous, flag __flag) | |
Construct a section handle using the given native handle type for the section and the given i/o handle for the backing storage. | |
constexpr | section_handle (section_handle &&o) noexcept |
Implicit move construction of section_handle permitted. | |
section_handle (const section_handle &)=delete | |
No copy construction (use clone() ) | |
section_handle & | operator= (section_handle &&o) noexcept |
Move assignment of section_handle permitted. | |
section_handle & | operator= (const section_handle &)=delete |
No copy assignment. | |
void | swap (section_handle &o) noexcept |
Swap with another instance. | |
flag | section_flags () const noexcept |
Returns the memory section's flags. | |
bool | is_nvram () const noexcept |
True if the section reflects non-volatile RAM. | |
file_handle * | backing () const noexcept |
Returns the borrowed handle backing this section, if any. | |
void | set_backing (file_handle *fh) noexcept |
Sets the borrowed handle backing this section, if any. | |
native_handle_type | backing_native_handle () const noexcept |
Returns the borrowed native handle backing this section. | |
result< extent_type > | length () const noexcept |
Return the current length of the memory section. | |
result< extent_type > | truncate (extent_type newsize=0) noexcept |
void | swap (handle &o) noexcept |
Swap with another instance. | |
virtual result< path_type > | current_path () const noexcept |
result< handle > | clone () 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. More... | |
bool | is_overlapped () const noexcept |
True if overlapped. | |
bool | is_seekable () const noexcept |
True if seekable. | |
bool | requires_aligned_io () const noexcept |
True if requires aligned i/o. | |
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_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. | |
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< section_handle > | section (file_handle &backing, extent_type maximum_size, flag _flag) noexcept |
Create a memory section backed by a file. More... | |
static result< section_handle > | section (file_handle &backing, extent_type bytes=0) noexcept |
Create a memory section backed by a file. More... | |
static result< section_handle > | section (extent_type bytes, const path_handle &dirh=path_discovery::storage_backed_temporary_files_directory(), flag _flag=flag::read|flag::write) noexcept |
Create a memory section backed by an anonymous, managed file. More... | |
Protected Attributes | |
file_handle * | _backing {nullptr} |
file_handle | _anonymous |
flag | _flag {flag::none} |
caching | _caching {caching::none} |
flag | _flags {flag::none} |
native_handle_type | _v |
A handle to a source of mapped memory.
There are two configurations of section handle, one where the user supplies the file backing for the section, and the other where an internal file descriptor to an unnamed inode in a tmpfs or ramfs based temporary directory is kept and managed. The latter is merely a convenience for creating an anonymous source of memory which can be resized whilst preserving contents: see algorithm::trivial_vector<T>
.
On Windows the native handle of this handle is that of the NT kernel section object. On POSIX it is a cloned file descriptor of the backing storage if there is backing storage, else it will be the aforementioned file descriptor to an unnamed inode.
|
stronginherited |
What i/o on the handle may complete immediately due to kernel caching.
|
stronginherited |
On opening, do we also create a new file or truncate an existing one?
|
stronginherited |
The behaviour of the handle: does it read, read and write, or atomic append?
|
inlinenoexceptinherited |
Clone this handle (copy constructor is disabled to avoid accidental copying)
|
inlinevirtualnoexceptinherited |
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.
path_handle
to fix a base location on the file system and work from that anchor instead!path_type
, likely several more. 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::symlink_handle.
|
inline |
The behaviour of the memory section.
< No flags
< Memory views can be read
< Memory views can be written
< Memory views can be copy on written
< Memory views can execute code
< Don't allocate space for this memory in the system immediately
< Prefault, as if by reading every page, any views of memory upon creation.
< The backing storage is in fact an executable program binary.
< A single instance of this section is to be shared by all processes using the same backing file.
< Maps of this section, if writable, issue a barrier()
when destructed blocking until data (not metadata) reaches physical storage.
< This section is of non-volatile RAM
< Use utils::page_sizes()[1]
sized pages, or fail.
< Use utils::page_sizes()[2]
sized pages, or fail.
< Use utils::page_sizes()[3]
sized pages, or fail.
|
inlinestaticnoexcept |
Create a memory section backed by a file.
backing | The handle to use as backing storage. |
maximum_size | The initial size of this section, which cannot be larger than any backing file. Zero means to use backing.maximum_extent() . |
_flag | How to create the section. |
|
inlinestaticnoexcept |
Create a memory section backed by a file.
backing | The handle to use as backing storage. |
bytes | The initial size of this section, which cannot be larger than any backing file. Zero means to use backing.maximum_extent() . |
This convenience overload create a writable section if the backing file is writable, otherwise a read-only section.
|
inlinestaticnoexcept |
Create a memory section backed by an anonymous, managed file.
bytes | The initial size of this section. Cannot be zero. |
dirh | Where to create the anonymous, managed file. |
_flag | How to create the section. |
|
inlinevirtualnoexceptinherited |
EXTENSION: Changes whether this handle is append only or not.
|
inlinenoexcept |
Resize the current maximum permitted extent of the memory section to the given extent.
newsize | The new size of the memory section, which cannot be zero. Specify zero to use backing.maximum_extent() . This cannot exceed the size of any backing file used if that file is not writable. |
NtExtendSection()
or ftruncate()
can return.