Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
SC::AsyncFileSystemOperation Struct Reference

Starts an asynchronous file system operation (open, close, read, write, sendFile, stat, lstat, fstat, etc.) Some operations need a file path and others need a file descriptor. More...

#include <Async.h>

Inheritance diagram for SC::AsyncFileSystemOperation:
SC::AsyncRequest

Public Types

enum class  Operation {
  None = 0 ,
  Open ,
  Close ,
  Read ,
  Write ,
  CopyFile
}
 
using CompletionData = AsyncFileSystemOperationCompletionData
 
using Result = AsyncResultOf<AsyncFileSystemOperation, CompletionData>
 
- Public Types inherited from SC::AsyncRequest
enum class  Type : uint8_t {
  LoopTimeout ,
  LoopWakeUp ,
  LoopWork ,
  ProcessExit ,
  SocketAccept ,
  SocketConnect ,
  SocketSend ,
  SocketSendTo ,
  SocketReceive ,
  SocketReceiveFrom ,
  FileRead ,
  FileWrite ,
  FilePoll ,
  FileSystemOperation
}
 Type of async request. More...
 

Public Member Functions

SC::Result setThreadPool (ThreadPool &threadPool)
 Sets the thread pool to use for the operation.
 
SC::Result open (AsyncEventLoop &eventLoop, StringViewData path, FileOpen mode)
 Opens a file asynchronously and returns its corresponding file descriptor.
 
SC::Result close (AsyncEventLoop &eventLoop, FileDescriptor::Handle handle)
 Closes a file descriptor asynchronously.
 
SC::Result read (AsyncEventLoop &eventLoop, FileDescriptor::Handle handle, Span< char > buffer, uint64_t offset)
 Reads data from a file descriptor at a given offset.
 
SC::Result write (AsyncEventLoop &eventLoop, FileDescriptor::Handle handle, Span< const char > buffer, uint64_t offset)
 Writes data to a file descriptor at a given offset.
 
SC::Result copyFile (AsyncEventLoop &eventLoop, StringViewData path, StringViewData destinationPath, FileSystemCopyFlags copyFlags=FileSystemCopyFlags())
 Copies a file from one location to another.
 
- Public Member Functions inherited from SC::AsyncRequest
void setDebugName (const char *newDebugName)
 
void executeOn (AsyncSequence &sequence)
 Adds the request to be executed on a specific AsyncSequence.
 
Result executeOn (AsyncTaskSequence &task, ThreadPool &pool)
 Adds the request to be executed on a specific AsyncTaskSequence.
 
void disableThreadPool ()
 Disables the thread-pool usage for this request.
 
 AsyncRequest (Type type)
 Constructs a free async request of given type.
 
Result stop (AsyncEventLoop &eventLoop, Function< void(AsyncResult &)> *afterStopped=nullptr)
 Ask to stop current async operation.
 
bool isFree () const
 Returns true if this request is free.
 
bool isCancelling () const
 Returns true if this request is being cancelled.
 
bool isActive () const
 Returns true if this request is active or being reactivated.
 
Type getType () const
 Returns request type.
 
Result start (AsyncEventLoop &eventLoop)
 Shortcut for AsyncEventLoop::start.
 
void setUserFlags (uint16_t externalFlags)
 Sets user flags, holding some meaningful data for the caller.
 
uint16_t getUserFlags () const
 Gets user flags, holding some meaningful data for the caller.
 
Function< void(AsyncResult &)> * getCloseCallback ()
 Returns currently set close callback (if any) passed to AsyncRequest::stop.
 
const Function< void(AsyncResult &)> * getCloseCallback () const
 

Public Attributes

Function< void(Result &)> callback
 Called after the operation is completed, on the event loop thread.
 
- Public Attributes inherited from SC::AsyncRequest
AsyncRequestnext = nullptr
 
AsyncRequestprev = nullptr
 

Friends

struct AsyncEventLoop
 

Additional Inherited Members

- Protected Member Functions inherited from SC::AsyncRequest
Result checkState ()
 
void queueSubmission (AsyncEventLoop &eventLoop)
 
AsyncTaskSequencegetTask ()
 
- Protected Attributes inherited from SC::AsyncRequest
AsyncSequencesequence = nullptr
 

Detailed Description

Starts an asynchronous file system operation (open, close, read, write, sendFile, stat, lstat, fstat, etc.) Some operations need a file path and others need a file descriptor.

Note
Operations will run on the thread pool set with AsyncFileSystemOperation::setThreadPool on all backends except when the event loop is using io_uring on Linux.
Warning
File paths must be encoded in the native encoding of the OS, that is UTF-8 on Posix and UTF-16 on Windows.

Example of async open operation:

// Create Thread Pool where to run fs operations
static constexpr int NUM_THREADS = 1;
ThreadPool threadPool;
SC_TEST_EXPECT(threadPool.create(NUM_THREADS));
// Create Event Loop
AsyncEventLoop eventLoop;
SC_TEST_EXPECT(eventLoop.create(options));
// Create a test file using FileSystem
FileSystem fs;
SC_TEST_EXPECT(fs.init(report.applicationRootDirectory));
SC_TEST_EXPECT(fs.writeString("FileSystemOperationOpen.txt", "FileSystemOperationOpen"));
AsyncFileSystemOperation asyncFileSystemOperation;
asyncFileSystemOperation.callback = [&](AsyncFileSystemOperation::Result& res)
{
SC_TEST_EXPECT(res.isValid());
SC_TEST_EXPECT(res.completionData.code == 0);
SC_TEST_EXPECT(res.completionData.handle != FileDescriptor::Invalid);
// Read the file content from the file descriptor handle (that is already opened)
// and check that the content is correct. Descriptor is closed automatically by FileDescriptor.
FileDescriptor fd(res.completionData.handle);
File file(fd);
String text;
SC_TEST_EXPECT(file.readUntilEOF(text));
SC_TEST_EXPECT(text.view() == "FileSystemOperationOpen");
};
// Set the thread pool where the open operation will be run
SC_TEST_EXPECT(asyncFileSystemOperation.setThreadPool(threadPool));
// Start the open operation on the given file
// IMPORTANT! The path string passed in must be in Native Encoding (that means UTF16 on Windows)
String path = StringEncoding::Native;
SC_TEST_EXPECT(Path::join(path, {report.applicationRootDirectory, "FileSystemOperationOpen.txt"}));
SC_TEST_EXPECT(asyncFileSystemOperation.open(eventLoop, path.view(), FileOpen::Read));
SC_TEST_EXPECT(eventLoop.run());
// Remove test files
SC_TEST_EXPECT(fs.removeFile("FileSystemOperationOpen.txt"));

Example of async close operation:

// Create Thread Pool where to run fs operations
static constexpr int NUM_THREADS = 1;
ThreadPool threadPool;
SC_TEST_EXPECT(threadPool.create(NUM_THREADS));
// Create Event Loop
AsyncEventLoop eventLoop;
SC_TEST_EXPECT(eventLoop.create(options));
// Create a test file using FileSystem
FileSystem fs;
SC_TEST_EXPECT(fs.init(report.applicationRootDirectory));
SC_TEST_EXPECT(fs.writeString("FileSystemOperationClose.txt", "FileSystemOperationClose"));
AsyncFileSystemOperation asyncFileSystemOperation;
int callbackCalled = 0;
asyncFileSystemOperation.callback = [&](AsyncFileSystemOperation::Result& res)
{
callbackCalled++;
SC_TEST_EXPECT(res.isValid());
SC_TEST_EXPECT(res.completionData.code == 0);
};
SC_TEST_EXPECT(asyncFileSystemOperation.setThreadPool(threadPool));
FileDescriptor fd;
String path = StringEncoding::Native;
SC_TEST_EXPECT(Path::join(path, {report.applicationRootDirectory, "FileSystemOperationClose.txt"}));
SC_TEST_EXPECT(fd.openNativeEncoding(path.view(), FileOpen::Read));
FileDescriptor::Handle handle = FileDescriptor::Invalid;
SC_TEST_EXPECT(fd.get(handle, Result::Error("Invalid FD")));
fd.detach();
SC_TEST_EXPECT(asyncFileSystemOperation.close(eventLoop, handle));
SC_TEST_EXPECT(eventLoop.run());
SC_TEST_EXPECT(callbackCalled == 1);
// Remove test files
SC_TEST_EXPECT(fs.removeFile("FileSystemOperationClose.txt"));

Example of async read operation:

// Create Thread Pool where to run fs operations
static constexpr int NUM_THREADS = 1;
ThreadPool threadPool;
SC_TEST_EXPECT(threadPool.create(NUM_THREADS));
// Create Event Loop
AsyncEventLoop eventLoop;
SC_TEST_EXPECT(eventLoop.create(options));
// Create a test file using FileSystem
FileSystem fs;
SC_TEST_EXPECT(fs.init(report.applicationRootDirectory));
SC_TEST_EXPECT(fs.writeString("FileSystemOperationRead.txt", "FileSystemOperationRead"));
// Open the file first
FileDescriptor fd;
String path = StringEncoding::Native;
SC_TEST_EXPECT(Path::join(path, {report.applicationRootDirectory, "FileSystemOperationRead.txt"}));
SC_TEST_EXPECT(fd.openNativeEncoding(path.view(), FileOpen::Read));
FileDescriptor::Handle handle = FileDescriptor::Invalid;
SC_TEST_EXPECT(fd.get(handle, Result::Error("Invalid FD")));
fd.detach();
AsyncFileSystemOperation asyncFileSystemOperation;
asyncFileSystemOperation.callback = [&](AsyncFileSystemOperation::Result& res)
{
SC_TEST_EXPECT(res.isValid());
SC_TEST_EXPECT(res.completionData.numBytes == 23); // Length of "FileSystemOperationRead"
};
SC_TEST_EXPECT(asyncFileSystemOperation.setThreadPool(threadPool));
// Read from the file
char buffer[32] = {0};
SC_TEST_EXPECT(asyncFileSystemOperation.read(eventLoop, handle, Span<char>(buffer, sizeof(buffer)), 0));
SC_TEST_EXPECT(eventLoop.run());
StringView readContent({buffer, 23}, true, StringEncoding::Ascii);
SC_TEST_EXPECT(readContent == StringView("FileSystemOperationRead"));
SC_TEST_EXPECT(eventLoop.run());
// Remove test files
SC_TEST_EXPECT(fs.removeFile("FileSystemOperationRead.txt"));

Member Function Documentation

◆ close()

SC::Result SC::AsyncFileSystemOperation::close ( AsyncEventLoop & eventLoop,
FileDescriptor::Handle handle )

Closes a file descriptor asynchronously.

Parameters
eventLoopThe event loop to use
handleThe file descriptor to close

◆ copyFile()

SC::Result SC::AsyncFileSystemOperation::copyFile ( AsyncEventLoop & eventLoop,
StringViewData path,
StringViewData destinationPath,
FileSystemCopyFlags copyFlags = FileSystemCopyFlags() )

Copies a file from one location to another.

Parameters
eventLoopThe event loop to use
pathThe path to the source file
destinationPathThe path to the destination file
copyFlagsFlags to control the copy operation

◆ open()

SC::Result SC::AsyncFileSystemOperation::open ( AsyncEventLoop & eventLoop,
StringViewData path,
FileOpen mode )

Opens a file asynchronously and returns its corresponding file descriptor.

Parameters
eventLoopThe event loop to use
pathThe path to the file to open (encoded in UTF-8 on Posix and UTF-16 on Windows)
modeThe mode to open the file in (read, write, read-write, etc.)

◆ read()

SC::Result SC::AsyncFileSystemOperation::read ( AsyncEventLoop & eventLoop,
FileDescriptor::Handle handle,
Span< char > buffer,
uint64_t offset )

Reads data from a file descriptor at a given offset.

Parameters
eventLoopThe event loop to use
handleThe file descriptor to read from
bufferThe buffer to read into
offsetThe offset in the file to read from

◆ setThreadPool()

SC::Result SC::AsyncFileSystemOperation::setThreadPool ( ThreadPool & threadPool)

Sets the thread pool to use for the operation.

◆ write()

SC::Result SC::AsyncFileSystemOperation::write ( AsyncEventLoop & eventLoop,
FileDescriptor::Handle handle,
Span< const char > buffer,
uint64_t offset )

Writes data to a file descriptor at a given offset.

Parameters
eventLoopThe event loop to use
handleThe file descriptor to write to
bufferThe buffer containing data to write
offsetThe offset in the file to write to

Member Data Documentation

◆ callback

Function<void(Result&)> SC::AsyncFileSystemOperation::callback

Called after the operation is completed, on the event loop thread.


The documentation for this struct was generated from the following file: