diff options
Diffstat (limited to 'src/ioq.h')
-rw-r--r-- | src/ioq.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/ioq.h b/src/ioq.h new file mode 100644 index 0000000..d8e1573 --- /dev/null +++ b/src/ioq.h @@ -0,0 +1,198 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +/** + * Asynchronous I/O queues. + */ + +#ifndef BFS_IOQ_H +#define BFS_IOQ_H + +#include "prelude.h" +#include "dir.h" +#include "stat.h" +#include <stddef.h> + +/** + * An queue of asynchronous I/O operations. + */ +struct ioq; + +/** + * I/O queue operations. + */ +enum ioq_op { + /** ioq_close(). */ + IOQ_CLOSE, + /** ioq_opendir(). */ + IOQ_OPENDIR, + /** ioq_closedir(). */ + IOQ_CLOSEDIR, + /** ioq_stat(). */ + IOQ_STAT, +}; + +/** + * The I/O queue implementation needs two tag bits in each pointer to a struct + * ioq_ent, so we need to ensure at least 4-byte alignment. The natural + * alignment is enough on most architectures, but not m68k, so over-align it. + */ +#define IOQ_ENT_ALIGN alignas(4) + +/** + * An I/O queue entry. + */ +struct ioq_ent { + /** The I/O operation. */ + IOQ_ENT_ALIGN enum ioq_op op; + + /** The return value (on success) or negative error code (on failure). */ + int result; + + /** Arbitrary user data. */ + void *ptr; + + /** Operation-specific arguments. */ + union { + /** ioq_close() args. */ + struct ioq_close { + int fd; + } close; + /** ioq_opendir() args. */ + struct ioq_opendir { + struct bfs_dir *dir; + const char *path; + int dfd; + enum bfs_dir_flags flags; + } opendir; + /** ioq_closedir() args. */ + struct ioq_closedir { + struct bfs_dir *dir; + } closedir; + /** ioq_stat() args. */ + struct ioq_stat { + const char *path; + struct bfs_stat *buf; + void *xbuf; + int dfd; + enum bfs_stat_flags flags; + } stat; + }; +}; + +/** + * Create an I/O queue. + * + * @param depth + * The maximum depth of the queue. + * @param nthreads + * The maximum number of background threads. + * @return + * The new I/O queue, or NULL on failure. + */ +struct ioq *ioq_create(size_t depth, size_t nthreads); + +/** + * Check the remaining capacity of a queue. + */ +size_t ioq_capacity(const struct ioq *ioq); + +/** + * Asynchronous close(). + * + * @param ioq + * The I/O queue. + * @param fd + * The fd to close. + * @param ptr + * An arbitrary pointer to associate with the request. + * @return + * 0 on success, or -1 on failure. + */ +int ioq_close(struct ioq *ioq, int fd, void *ptr); + +/** + * Asynchronous bfs_opendir(). + * + * @param ioq + * The I/O queue. + * @param dir + * The allocated directory. + * @param dfd + * The base file descriptor. + * @param path + * The path to open, relative to dfd. + * @param flags + * Flags that control which directory entries are listed. + * @param ptr + * An arbitrary pointer to associate with the request. + * @return + * 0 on success, or -1 on failure. + */ +int ioq_opendir(struct ioq *ioq, struct bfs_dir *dir, int dfd, const char *path, enum bfs_dir_flags flags, void *ptr); + +/** + * Asynchronous bfs_closedir(). + * + * @param ioq + * The I/O queue. + * @param dir + * The directory to close. + * @param ptr + * An arbitrary pointer to associate with the request. + * @return + * 0 on success, or -1 on failure. + */ +int ioq_closedir(struct ioq *ioq, struct bfs_dir *dir, void *ptr); + +/** + * Asynchronous bfs_stat(). + * + * @param ioq + * The I/O queue. + * @param dfd + * The base file descriptor. + * @param path + * The path to stat, relative to dfd. + * @param flags + * Flags that affect the lookup. + * @param buf + * A place to store the stat buffer, if successful. + * @param ptr + * An arbitrary pointer to associate with the request. + * @return + * 0 on success, or -1 on failure. + */ +int ioq_stat(struct ioq *ioq, int dfd, const char *path, enum bfs_stat_flags flags, struct bfs_stat *buf, void *ptr); + +/** + * Pop a response from the queue. + * + * @param ioq + * The I/O queue. + * @return + * The next response, or NULL. + */ +struct ioq_ent *ioq_pop(struct ioq *ioq, bool block); + +/** + * Free a queue entry. + * + * @param ioq + * The I/O queue. + * @param ent + * The entry to free. + */ +void ioq_free(struct ioq *ioq, struct ioq_ent *ent); + +/** + * Cancel any pending I/O operations. + */ +void ioq_cancel(struct ioq *ioq); + +/** + * Stop and destroy an I/O queue. + */ +void ioq_destroy(struct ioq *ioq); + +#endif // BFS_IOQ_H |