1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
Title: Asynchronous IO
The [class@Gio.IOStream] APIs already provide robust support for asynchronous IO.
The common API allows for different types of implementation based on the stream implementation.
Libdex provides wrappers for various APIs.
Coverage is not complete but we do expect additional APIs to be covered in future releases.
# Files, Directories & Streams
## File Management
See [func@Dex.file_copy] for copying files.
See [func@Dex.file_delete] for deleting files.
See [func@Dex.file_move] for moving files.
## File Attributes
See [func@Dex.file_query_info] and [func@Dex.file_query_file_type], and [func@Dex.file_query_exists] for basic querying.
You can set file attributes using [func@Dex.file_set_attributes].
## Directories
You can create a directory or hierarchy of directories using [func@Dex.file_make_directory] and [func@Dex.file_make_directory_with_parents] respectively.
### Enumerating Files
You can create a file enumerator for a directory using [func@Dex.file_enumerate_children].
You can also asynchronously enumerate the files of that directory using [func@Dex.file_enumerator_next_files] which will resolve to a `g_autolist(GFileInfo)` of infos.
## Reading and Writing Files
The [func@Dex.file_read] will provide a [class@Gio.FileInputStream] which can be read from.
A simpler interface to get the bytes of a file is provided via [func@Dex.file_load_contents_bytes].
The [func@Dex.file_replace] will replace a file on disk providing a [class@Gio.FileOutputStream] to write to.
The [func@Dex.file_replace_contents_bytes] provides a simplified API for this when the content is readily available.
## Reading Streams
See [func@Dex.input_stream_read], [func@Dex.input_stream_read_bytes], [func@Dex.input_stream_skip], and [func@Dex.input_stream_close] for working with input streams asynchronously.
## Writing Streams
See [func@Dex.output_stream_write], [func@Dex.output_stream_write_bytes], [func@Dex.output_stream_splice], and [func@Dex.output_stream_close] for writing to streams asynchronously.
# Sockets
The [func@Dex.socket_listener_accept], [func@Dex.socket_client_connect], and [func@Dex.resolver_lookup_by_name] may be helpful when writing socket servers and clients.
# D-Bus
[See the page about D-Bus](dbus.html)
# Subprocesses
You can await completion of a subprocess using [func@Dex.subprocess_wait_check].
# Asynchronous IO with File Descriptors
[class@Gio.IOStream] and related APIs provides much opportunity for streams to be used asynchronously.
There may be cases where you want similar behavior with traditional file-descriptors.
Libdex provides a set of AIO-like functions for traditional file-descriptors which may be backed with more efficient mechanisms.
[class@Gio.IOStream] typically uses a thread pool of blocking IO operations on Linux and other operating systems because that was the fastest method when the APIs were created.
However, on some operating systems such as Linux, faster methods finally exist.
On Linux, `io_uring` can be used for asynchronous IO and is provided in the form of a [class@Dex.Future].
# Asynchronous Reads
```c
DexFuture *dex_aio_read (DexAioContext *aio_context,
int fd,
gpointer buffer,
gsize count,
goffset offset)
```
Use the `dex_aio_read()` function to read from a file-descriptor.
The result will be a future that resolves to a `gint64` containing the number of bytes read.
If there was a failure, the future will reject using the appropriate error code.
Your `buffer` must stay alive for the duration of the asynchronous read.
One easy way to make that happen is to wrap the resulting future in a `dex_future_then()` which stores the buffer as `user_data` and releases it when finished.
If you are doing buffer pooling, more effort may be required.
# Asynchronous Writes
```c
DexFuture *dex_aio_write (DexAioContext *aio_context,
int fd,
gconstpointer buffer,
gsize count,
goffset offset)
```
A similar API exists as `dex_aio_read()` but for writing.
It too will resolve to a `gint64` containing the number of bytes written.
`buffer` must be kept alive for the duration of the call and it is the callers responsibility to do so.
|