dispatch_read(3)

πŸ’– dispatch_read(3) β€” Library Functions Manual πŸ’–

okay bestie, sit down, hydrate, because we're about to talk about dispatch_read(3) from the Library Functions Manual and honestly? it's giving "asynchronous file descriptor slay". this is the libdispatch corner of the universe where reading and writing to fds happens in the background while your main character keeps living her life ✨


🌸 NAME 🌸

dispatch_read, dispatch_write β€” asynchronously read from and write to file descriptors

no cap, that's literally the whole vibe. async reads, async writes, file descriptors. periodt. πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <dispatch/dispatch.h>

void
dispatch_read(int fd, size_t length, dispatch_queue_t queue,
    void (^handler)(dispatch_data_t data, int error));

void
dispatch_write(int fd, dispatch_data_t data, dispatch_queue_t queue,
    void (^handler)(dispatch_data_t data, int error)));
🫢 friendly reminder: yes, that's really how it's spelled in the original. we are keeping it exactly as-is, character for character, typos and all, because facts don't get a glow-up.

πŸŽ€ DESCRIPTION πŸŽ€

so dispatch_read() and dispatch_write() are these two little icons that asynchronously read from and write to POSIX file descriptors. think of them as the asynchronous, callback-based versions of fread() and fwrite() from the standard C library β€” like, the same energy but she doesn't block your whole thread while she does it. πŸ’«

they're convenience functions built on top of dispatch_io_read(3) and dispatch_io_write(3), made for simple one-shot read or write requests. if you've got multiple requests hitting the same file descriptor, that's not their moment β€” you should be using the full underlying dispatch I/O channel functions instead. iykyk. 🧚


🌈 BEHAVIOR 🌈

okay so, dispatch_read() schedules an asynchronous read operation on the file descriptor fd. once fd is readable, the system reads as much data as is currently available β€” up to the specified length, starting at the current file pointer position. when the operation completes or an error happens, the handler block you gave it gets submitted to queue. πŸ“¬

that block gets handed a dispatch data object with the result of the read. if something went wrong while reading from the file descriptor, the error parameter passed to the block gets set to the appropriate POSIX error code, and data contains any data that could be read successfully. and if the file pointer position is already at end-of-file? then empty data and a zero error get passed to the handler block. no drama, just done. πŸ’–

now dispatch_write() β€” she schedules an asynchronous write operation on the file descriptor fd. the system attempts to write the entire contents of the provided data object to fd at the current file pointer position. the handler block gets submitted to queue when the operation completes or an error occurs. if the write completed successfully, the error parameter to the block is set to zero β€” otherwise it's set to the appropriate POSIX error code, and the data parameter contains any data that could not be written. 😭


πŸ’€ CAVEATS πŸ’€

listen, this part matters, don't skip it:

  • the data object passed to a handler block is released by the system when the block returns. if you need data outside of the handler block, you must concatenate, copy, or retain it. that's not a suggestion, that's the law. 🚨
  • once an asynchronous read or write operation has been submitted on a file descriptor fd, the system takes control of that file descriptor until the handler block is executed. during this time your application must not manipulate fd directly. in particular, it is only safe to close fd from the handler block β€” or after it has returned. don't be messy about it. πŸ™ˆ
  • if multiple asynchronous read or write operations are submitted to the same file descriptor, they will be performed in order, but their handlers will only be submitted once all operations have completed and control over the file descriptor has been relinquished. for the full tea on this, and on how it interacts with dispatch I/O channels created from the same file descriptor, go read β€œFILEDESCRIPTOR OWNERSHIP” in dispatch_io_create(3). πŸ‘‘

⭐ SEE ALSO ⭐


and that's the whole page, bestie πŸ₯ΉπŸ’œ this one's from Darwin, dated December 1, 2010 β€” ancient text, modern queen. go read your file descriptors asynchronously and stay hydrated. mwah. πŸ’…βœ¨πŸŽ€