Skip to content

AsyncFiles

AsyncFiles queues the Files operations and runs them on a background thread, so the calling thread does not wait for the disk.

#import "AsyncFiles.xc"

Each call returns at once. When the operation has finished, its completion block is called with the result Files would have returned:

AsyncFiles.writeText(path, text, block void(bool ok) { … });
AsyncFiles.readText(path, block void(String* text) {
if (text == 0) { /* no such file */ }
});

One worker runs the queue in order. A read queued after a write of the same file reads what was written, and two appends land in the order they were made.

A completion may be 0 when the caller does not need the result. drain blocks until everything queued so far has run and its completion has returned. A command-line program calls it before it exits, and a test calls it before it checks the files.

static void readText(String* path, block cb void(String*))

Reads the file as text; cb gets the text, or 0 when the file cannot be read.

static void readData(String* path, block cb void(Data*))

Reads the file’s bytes; cb gets them, or 0 when the file cannot be read.

static void writeText(String* path, String* text, block cb void(bool))

Replaces the file with text; cb gets whether it worked.

static void writeData(String* path, Data* data, block cb void(bool))

Replaces the file with data; cb gets whether it worked.

static void appendText(String* path, String* text, block cb void(bool))

Adds text to the end of the file, creating it if needed; cb gets whether it worked.

static void deliverOn(RunLoop* loop)

Posts every completion to loop, so it runs on that loop’s thread. 0 goes back to running completions on the worker. Set it before queueing. With a loop set, drain waits for the operations, not for the posted completions. Not on arm9, which has no RunLoop.

static void drain(void)

Blocks until every operation queued before the call has run and its completion has returned. Do not call it from a completion block: the worker would wait for itself.