Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
Async.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "../Foundation/Function.h"
6#include "../Foundation/OpaqueObject.h"
7#include "../Foundation/Span.h"
8#include "../Threading/Atomic.h"
9#include "../Threading/ThreadPool.h"
10#include "../Time/Time.h"
11
12// Descriptors
13#include "../File/FileDescriptor.h"
14#include "../Process/ProcessDescriptor.h"
15#include "../Socket/SocketDescriptor.h"
16namespace SC
17{
18struct ThreadPool;
19struct ThreadPoolTask;
20struct EventObject;
21} // namespace SC
46
49namespace SC
50{
51struct AsyncEventLoop;
52struct AsyncResult;
53struct AsyncTask;
54
55namespace detail
56{
57struct AsyncWinOverlapped;
58struct AsyncWinOverlappedDefinition
59{
60 static constexpr int Windows = sizeof(void*) * 4 + sizeof(uint64_t);
61 static constexpr size_t Alignment = alignof(void*);
62
63 using Object = AsyncWinOverlapped;
64};
65using WinOverlappedOpaque = OpaqueObject<AsyncWinOverlappedDefinition>;
66
67struct AsyncWinWaitDefinition
68{
69 using Handle = FileDescriptor::Handle; // fd
70 static constexpr Handle Invalid = FileDescriptor::Invalid; // invalid fd
71
72 static Result releaseHandle(Handle& waitHandle);
73};
74struct WinWaitHandle : public UniqueHandle<AsyncWinWaitDefinition>
75{
76};
77} // namespace detail
78
118{
119 AsyncRequest* next = nullptr;
120 AsyncRequest* prev = nullptr;
121
122 void setDebugName(const char* newDebugName);
123
125 [[nodiscard]] AsyncEventLoop* getEventLoop() const { return eventLoop; }
126
129 void cacheInternalEventLoop(AsyncEventLoop& loop) { eventLoop = &loop; }
130
135
138
140 enum class Type : uint8_t
141 {
143 LoopWakeUp,
144 LoopWork,
148 SocketSend,
151 FileRead,
152 FileWrite,
153 FileClose,
154 FilePoll,
155 };
156
159 AsyncRequest(Type type) : state(State::Free), type(type), flags(0), eventIndex(-1) {}
160
166 [[nodiscard]] Result stop(Function<void(AsyncResult&)>* afterStopped = nullptr);
167
169 [[nodiscard]] bool isFree() const;
170
172 [[nodiscard]] bool isCancelling() const;
173
175 [[nodiscard]] bool isActive() const;
176
178 [[nodiscard]] Type getType() const { return type; }
179
182
183 protected:
184 [[nodiscard]] Result checkState();
185
186 void queueSubmission(AsyncEventLoop& eventLoop);
187
188 AsyncEventLoop* eventLoop = nullptr;
189 AsyncTask* asyncTask = nullptr;
190
191 private:
192 Function<void(AsyncResult&)>* closeCallback = nullptr;
193
194 friend struct AsyncEventLoop;
195 friend struct AsyncResult;
196
197 void markAsFree();
198
199 [[nodiscard]] static const char* TypeToString(Type type);
200 enum class State : uint8_t
201 {
202 Free, // not in any queue, this can be started with an async.start(...)
203 Setup, // when in submission queue waiting to be setup (after an async.start(...))
204 Submitting, // when in submission queue waiting to be activated or re-activated
205 Active, // when monitored by OS syscall or in activeLoopWakeUps / activeTimeouts queues
206 Reactivate, // when flagged for reactivation inside the callback (after a result.reactivateRequest(true))
207 Cancelling, // when in cancellation queue waiting for a cancelAsync (on active async)
208 };
209
210#if SC_CONFIGURATION_DEBUG
211 const char* debugName = "None";
212#endif
213 State state; // 1 byte
214 Type type; // 1 byte
215 int16_t flags; // 2 bytes
216 int32_t eventIndex; // 4 bytes
217};
218
221{
222};
223
227{
229 AsyncResult(AsyncRequest& request, SC::Result&& res) : async(request), returnCode(move(res)) {}
230
232 AsyncResult(AsyncRequest& request) : async(request) {}
233
236 void reactivateRequest(bool value);
237
239 [[nodiscard]] const SC::Result& isValid() const { return returnCode; }
240
241 AsyncRequest& async;
242
243 protected:
244 friend struct AsyncEventLoop;
245
246 bool shouldBeReactivated = false;
247 bool shouldCallCallback = true;
248
249 SC::Result returnCode = SC::Result(true);
250};
251
255template <typename T, typename C>
257{
258 T& getAsync() { return static_cast<T&>(AsyncResult::async); }
259 const T& getAsync() const { return static_cast<const T&>(AsyncResult::async); }
260
262
263 C completionData;
264};
265
292
328
334{
336
338 {
340 };
341
342 struct Result : public AsyncResultOf<AsyncProcessExit, CompletionData>
343 {
344 using AsyncResultOf<AsyncProcessExit, CompletionData>::AsyncResultOf;
345
347 {
348 status = completionData.exitStatus;
349 return returnCode;
350 }
351 };
353
355 SC::Result start(AsyncEventLoop& eventLoop, ProcessDescriptor::Handle process);
356
358
359 private:
360 friend struct AsyncEventLoop;
361 SC::Result validate(AsyncEventLoop&);
362
363 ProcessDescriptor::Handle handle = ProcessDescriptor::Invalid;
364#if SC_PLATFORM_WINDOWS
366 detail::WinWaitHandle waitHandle;
367#elif SC_PLATFORM_LINUX
368 FileDescriptor pidFd;
369#endif
370};
371
382{
384
386 {
387 SocketDescriptor acceptedClient;
388 };
389
390 struct Result : public AsyncResultOf<AsyncSocketAccept, CompletionData>
391 {
392 using AsyncResultOf<AsyncSocketAccept, CompletionData>::AsyncResultOf;
393
394 SC::Result moveTo(SocketDescriptor& client)
395 {
396 SC_TRY(returnCode);
397 return client.assign(move(completionData.acceptedClient));
398 }
399 };
401
403 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
404
406
407 private:
408 friend struct AsyncEventLoop;
409 SC::Result validate(AsyncEventLoop&);
410
411 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
413#if SC_PLATFORM_WINDOWS
414 void (*pAcceptEx)() = nullptr;
416 SocketDescriptor clientSocket;
417 uint8_t acceptBuffer[288] = {0};
418#elif SC_PLATFORM_LINUX
419 AlignedStorage<28> sockAddrHandle;
420 uint32_t sockAddrLen;
421#endif
422};
423
433{
435
439
441 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, SocketIPAddress address);
442
444
445 private:
446 friend struct AsyncEventLoop;
447 SC::Result validate(AsyncEventLoop&);
448
449 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
450 SocketIPAddress ipAddress;
451#if SC_PLATFORM_WINDOWS
452 void (*pConnectEx)() = nullptr;
454#endif
455};
456
466{
469 {
470 size_t numBytes = 0;
471 };
474
477
480
482
483 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
484
487 bool singleBuffer = true;
488
489 private:
490 friend struct AsyncEventLoop;
491 SC::Result validate(AsyncEventLoop&);
492
493 size_t totalBytesWritten = 0;
494#if SC_PLATFORM_WINDOWS
496#endif
497};
498
511{
513
515 {
516 size_t numBytes = 0;
517 bool disconnected = false;
518 };
519
520 struct Result : public AsyncResultOf<AsyncSocketReceive, CompletionData>
521 {
522 using AsyncResultOf<AsyncSocketReceive, CompletionData>::AsyncResultOf;
523
528 {
529 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, outData));
530 return returnCode;
531 }
532 };
535 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, Span<char> data);
536
538
540 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
541
542 private:
543 friend struct AsyncEventLoop;
544 SC::Result validate(AsyncEventLoop&);
545#if SC_PLATFORM_WINDOWS
547#endif
548};
549
555{
557
561
563 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor);
564
565 // TODO: Move code to CompletionData
566 int code = 0;
567
569
570 private:
571 SC::Result validate(AsyncEventLoop&);
572 friend struct AsyncEventLoop;
573
574 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
575};
576
599{
600 AsyncFileRead() : AsyncRequest(Type::FileRead) { handle = FileDescriptor::Invalid; }
601
603 {
604 size_t numBytes = 0;
605 bool endOfFile = false;
606 };
607
608 struct Result : public AsyncResultOf<AsyncFileRead, CompletionData>
609 {
610 using AsyncResultOf<AsyncFileRead, CompletionData>::AsyncResultOf;
611
612 SC::Result get(Span<char>& data)
613 {
614 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, data));
615 return returnCode;
616 }
617 };
619
620 Function<void(Result&)> callback;
622 FileDescriptor::Handle handle;
624
626 uint64_t getOffset() const { return offset; }
627
630 void setOffset(uint64_t fileOffset)
631 {
632 useOffset = true;
633 offset = fileOffset;
634 }
635
636 private:
637 friend struct AsyncEventLoop;
638 SC::Result validate(AsyncEventLoop&);
639 bool useOffset = false;
640 uint64_t offset = 0;
641#if SC_PLATFORM_WINDOWS
642 uint64_t readCursor = 0;
644#endif
645};
646
665{
666 AsyncFileWrite() : AsyncRequest(Type::FileWrite) { handle = FileDescriptor::Invalid; }
667
669 {
670 size_t numBytes = 0;
671 };
672
673 struct Result : public AsyncResultOf<AsyncFileWrite, CompletionData>
674 {
675 using AsyncResultOf<AsyncFileWrite, CompletionData>::AsyncResultOf;
676
677 SC::Result get(size_t& writtenSizeInBytes)
678 {
679 writtenSizeInBytes = completionData.numBytes;
680 return returnCode;
681 }
682 };
683
685
688
691
693
694 FileDescriptor::Handle handle;
696
699 bool singleBuffer = true;
700
702 uint64_t getOffset() const { return offset; }
703
706 void setOffset(uint64_t fileOffset)
707 {
708 useOffset = true;
709 offset = fileOffset;
710 }
711
712 private:
713 friend struct AsyncEventLoop;
714 SC::Result validate(AsyncEventLoop&);
715
716 bool isWatchable = false;
717 bool useOffset = false;
718 uint64_t offset = 0xffffffffffffffff;
719
720 size_t totalBytesWritten = 0;
721#if SC_PLATFORM_WINDOWS
723#endif
724};
725
732{
734
737
740
742 SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle fileDescriptor);
743
744 // TODO: Move code to CompletionData
745 int code = 0;
746
748
749 private:
750 friend struct AsyncEventLoop;
751 SC::Result validate(AsyncEventLoop&);
752
753 FileDescriptor::Handle handle = FileDescriptor::Invalid;
754};
755
761{
763
766
768 SC::Result start(AsyncEventLoop& loop, FileDescriptor::Handle fileDescriptor);
769
770#if SC_PLATFORM_WINDOWS
771 [[nodiscard]] auto& getOverlappedOpaque() { return overlapped; }
772#endif
773
774 Function<void(Result&)> callback;
775
776 private:
777 friend struct AsyncEventLoop;
778 SC::Result validate(AsyncEventLoop&);
779
780 FileDescriptor::Handle handle = FileDescriptor::Invalid;
781#if SC_PLATFORM_WINDOWS
783#endif
784};
785
786struct AsyncLoopWork; // forward declared because it must be defined after AsyncTask
787
788namespace detail
789{
790// A simple hand-made variant of all completion types
791struct AsyncCompletionVariant
792{
793 AsyncCompletionVariant() {}
794 ~AsyncCompletionVariant() { destroy(); }
795
796 AsyncCompletionVariant(const AsyncCompletionVariant&) = delete;
797 AsyncCompletionVariant(AsyncCompletionVariant&&) = delete;
798 AsyncCompletionVariant& operator=(const AsyncCompletionVariant&) = delete;
799 AsyncCompletionVariant& operator=(AsyncCompletionVariant&&) = delete;
800
801 bool inited = false;
803 union
804 {
805 AsyncCompletionData completionDataLoopWork; // Defined after AsyncCompletionVariant / AsyncTask
806 AsyncLoopTimeout::CompletionData completionDataLoopTimeout;
807 AsyncLoopWakeUp::CompletionData completionDataLoopWakeUp;
808 AsyncProcessExit::CompletionData completionDataProcessExit;
809 AsyncSocketAccept::CompletionData completionDataSocketAccept;
810 AsyncSocketConnect::CompletionData completionDataSocketConnect;
811 AsyncSocketSend::CompletionData completionDataSocketSend;
812 AsyncSocketReceive::CompletionData completionDataSocketReceive;
813 AsyncSocketClose::CompletionData completionDataSocketClose;
814 AsyncFileRead::CompletionData completionDataFileRead;
815 AsyncFileWrite::CompletionData completionDataFileWrite;
816 AsyncFileClose::CompletionData completionDataFileClose;
817 AsyncFilePoll::CompletionData completionDataFilePoll;
818 };
819
820 auto& getCompletion(AsyncLoopWork&) { return completionDataLoopWork; }
821 auto& getCompletion(AsyncLoopTimeout&) { return completionDataLoopTimeout; }
822 auto& getCompletion(AsyncLoopWakeUp&) { return completionDataLoopWakeUp; }
823 auto& getCompletion(AsyncProcessExit&) { return completionDataProcessExit; }
824 auto& getCompletion(AsyncSocketAccept&) { return completionDataSocketAccept; }
825 auto& getCompletion(AsyncSocketConnect&) { return completionDataSocketConnect; }
826 auto& getCompletion(AsyncSocketSend&) { return completionDataSocketSend; }
827 auto& getCompletion(AsyncSocketReceive&) { return completionDataSocketReceive; }
828 auto& getCompletion(AsyncSocketClose&) { return completionDataSocketClose; }
829 auto& getCompletion(AsyncFileRead&) { return completionDataFileRead; }
830 auto& getCompletion(AsyncFileWrite&) { return completionDataFileWrite; }
831 auto& getCompletion(AsyncFileClose&) { return completionDataFileClose; }
832 auto& getCompletion(AsyncFilePoll&) { return completionDataFilePoll; }
833
834 template <typename T>
835 auto& construct(T& t)
836 {
837 destroy();
838 placementNew(getCompletion(t));
839 inited = true;
840 type = t.getType();
841 return getCompletion(t);
842 }
843 void destroy();
844};
845} // namespace detail
846
854{
855 protected:
856 ThreadPoolTask task;
857 ThreadPool* threadPool = nullptr;
858 AsyncRequest* async = nullptr;
859
860 friend struct AsyncEventLoop;
861 friend struct AsyncRequest;
862
863 void freeTask() { async = nullptr; }
864 bool isFree() const { return async == nullptr; }
865
866 detail::AsyncCompletionVariant completion;
867
868 SC::Result returnCode = SC::Result(true);
869};
870
898
903{
905
906 private:
907 int numberOfEvents = 0;
908 friend struct AsyncEventLoop;
909};
910
913{
914 Function<void(AsyncEventLoop&)> beforeBlockingPoll;
915 Function<void(AsyncEventLoop&)> afterBlockingPoll;
916};
917
925{
927 struct Options
928 {
929 enum class ApiType : uint8_t
930 {
931 Automatic = 0,
934 };
936
938 };
939
941
943 [[nodiscard]] Result create(Options options = Options());
944
946 [[nodiscard]] Result close();
947
951
953 void interrupt();
954
956 [[nodiscard]] bool isInitialized() const;
957
963 [[nodiscard]] Result run();
964
974 [[nodiscard]] Result runOnce();
975
981 [[nodiscard]] Result runNoWait();
982
987 [[nodiscard]] Result submitRequests(AsyncKernelEvents& kernelEvents);
988
1007 [[nodiscard]] Result blockingPoll(AsyncKernelEvents& kernelEvents);
1008
1014 [[nodiscard]] Result dispatchCompletions(AsyncKernelEvents& kernelEvents);
1015
1019
1022
1026
1029
1032
1035
1037 [[nodiscard]] Time::Monotonic getLoopTime() const;
1038
1040 [[nodiscard]] int getNumberOfActiveRequests() const;
1041
1043 [[nodiscard]] int getNumberOfSubmittedRequests() const;
1044
1048
1051
1054
1056 void enumerateRequests(Function<void(AsyncRequest&)> enumerationCallback);
1057
1061
1063 [[nodiscard]] static bool isExcludedFromActiveCount(const AsyncRequest& async);
1064
1067 [[nodiscard]] static bool tryLoadingLiburing();
1068
1069 struct Internal;
1070
1071 private:
1072 struct InternalDefinition
1073 {
1074 static constexpr int Windows = 488;
1075 static constexpr int Apple = 480;
1076 static constexpr int Linux = 688;
1077 static constexpr int Default = Linux;
1078
1079 static constexpr size_t Alignment = 8;
1080
1081 using Object = Internal;
1082 };
1083
1084 public:
1085 using InternalOpaque = OpaqueObject<InternalDefinition>;
1086
1087 private:
1088 InternalOpaque internalOpaque;
1089 Internal& internal;
1090
1091 friend struct AsyncRequest;
1092 friend struct AsyncFileWrite;
1093 friend struct AsyncFileRead;
1094};
1095
1100{
1102
1106
1109
1117
1123
1124 private:
1125#if SC_COMPILER_MSVC
1126#pragma warning(push)
1127#pragma warning(disable : 4324) // useless warning on 32 bit... (structure was padded due to __declspec(align()))
1128#endif
1129 alignas(uint64_t) uint8_t eventsMemory[8 * 1024]; // 8 Kb of kernel events
1130#if SC_COMPILER_MSVC
1131#pragma warning(pop)
1132#endif
1133
1134 AsyncKernelEvents asyncKernelEvents;
1135 AsyncEventLoop* eventLoop = nullptr;
1136 AsyncLoopWakeUp eventLoopWakeUp;
1137
1138 Thread eventLoopThread;
1139 EventObject eventObjectEnterBlockingMode;
1140 EventObject eventObjectExitBlockingMode;
1141
1142 Atomic<bool> finished = false;
1143 Atomic<bool> needsWakeUp = true;
1144
1145 bool wakeUpHasBeenCalled = false;
1146
1147 Result monitoringLoopThread(Thread& thread);
1148};
1149
1150} // namespace SC
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition Compiler.h:269
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:36
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
short int16_t
Platform independent (2) bytes signed int.
Definition PrimitiveTypes.h:45
int int32_t
Platform independent (4) bytes signed int.
Definition PrimitiveTypes.h:46
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition Result.h:48
A buffer of bytes with given alignment.
Definition AlignedStorage.h:29
Empty base struct for all AsyncRequest-derived CompletionData (internal) structs.
Definition Async.h:221
Allow library user to provide callbacks signaling different phases of async event loop cycle.
Definition Async.h:913
Monitors Async I/O events from a background thread using a blocking kernel function (no CPU usage on ...
Definition Async.h:1100
Result create(AsyncEventLoop &loop)
Create the monitoring thread for an AsyncEventLoop.
Function< void(void)> onNewEventsAvailable
Informs to call dispatchCompletions on GUI Event Loop.
Definition Async.h:1101
Result startMonitoring()
Queue all async requests submissions and start monitoring loop events on a background thread.
Result close()
Stop monitoring the AsyncEventLoop, disposing all resources.
Result stopMonitoringAndDispatchCompletions()
Stops monitoring events on the background thread and dispatches callbacks for completed requests.
Options given to AsyncEventLoop::create.
Definition Async.h:928
ApiType apiType
Criteria to choose Async IO API.
Definition Async.h:935
ApiType
Definition Async.h:930
@ Automatic
Platform specific backend chooses the best API.
@ ForceUseEpoll
(Linux only) Tries to use epoll
@ ForceUseIOURing
(Linux only) Tries to use io_uring (failing if it's not found on the system)
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:925
Time::Monotonic getLoopTime() const
Get Loop time.
Result associateExternallyCreatedFileDescriptor(FileDescriptor &outDescriptor)
Associates a File descriptor created externally with the eventLoop.
Result wakeUpFromExternalThread()
Wake up the event loop from a thread different than the one where run() is called (and potentially bl...
Result runNoWait()
Process active requests if any, dispatching their completions, or returns immediately without blockin...
void updateTime()
Updates loop time to "now".
static bool isExcludedFromActiveCount(const AsyncRequest &async)
Checks if excludeFromActiveCount() has been called on the given request.
Result blockingPoll(AsyncKernelEvents &kernelEvents)
Blocks until at least one event happens, ensuring forward progress, without executing completions.
int getNumberOfSubmittedRequests() const
Obtain the total number of submitted requests.
Result submitRequests(AsyncKernelEvents &kernelEvents)
Submits all queued async requests.
void enumerateRequests(Function< void(AsyncRequest &)> enumerationCallback)
Enumerates all requests objects associated with this loop.
Result start(AsyncRequest &async)
Queues an async request request that has been correctly setup.
AsyncLoopTimeout * findEarliestLoopTimeout() const
Returns the next AsyncLoopTimeout that will be executed (shortest relativeTimeout)
void setListeners(AsyncEventLoopListeners *listeners)
Sets reference to listeners that will signal different events in loop lifetime.
Result dispatchCompletions(AsyncKernelEvents &kernelEvents)
Invokes completions for the AsyncKernelEvents collected by a call to AsyncEventLoop::blockingPoll.
void interrupt()
Interrupts the event loop even if it has active request on it.
Result wakeUpFromExternalThread(AsyncLoopWakeUp &wakeUp)
Wake up the event loop from a thread different than the one where run() is called (and potentially bl...
bool isInitialized() const
Returns true if create has been already called (successfully)
Result create(Options options=Options())
Creates the event loop kernel object.
static bool tryLoadingLiburing()
Check if liburing is loadable (only on Linux)
Result createAsyncTCPSocket(SocketFlags::AddressFamily family, SocketDescriptor &outDescriptor)
Helper to creates a TCP socket with AsyncRequest flags of the given family (IPV4 / IPV6).
Result associateExternallyCreatedTCPSocket(SocketDescriptor &outDescriptor)
Associates a TCP Socket created externally (without using createAsyncTCPSocket) with the eventLoop.
Result close()
Closes the event loop kernel object.
Result runOnce()
Blocks until at least one request proceeds, ensuring forward progress, dispatching all completions.
void excludeFromActiveCount(AsyncRequest &async)
Excludes the request from active handles count (to avoid it keeping event loop alive)
Result run()
Blocks until there are no more active queued requests, dispatching all completions.
void includeInActiveCount(AsyncRequest &async)
Reverses the effect of excludeFromActiveCount for the request.
int getNumberOfActiveRequests() const
Obtain the total number of active requests.
Starts a file close operation, closing the OS file descriptor.
Definition Async.h:732
int code
Return code of close socket operation.
Definition Async.h:745
SC::Result start(AsyncEventLoop &eventLoop, FileDescriptor::Handle fileDescriptor)
Sets async request members and calls AsyncEventLoop::start.
AsyncCompletionData CompletionData
Completion data for AsyncFileClose.
Definition Async.h:736
Function< void(Result &)> callback
Callback called after fully closing the file descriptor.
Definition Async.h:747
Starts an handle polling operation.
Definition Async.h:761
SC::Result start(AsyncEventLoop &loop, FileDescriptor::Handle fileDescriptor)
Starts a file descriptor poll operation, monitoring its readiness with appropriate OS API.
Definition Async.h:603
Definition Async.h:609
Starts a file read operation, reading bytes from a file (or pipe).
Definition Async.h:599
FileDescriptor::Handle handle
The writeable span of memory where to data will be written.
Definition Async.h:622
Span< char > buffer
Callback called when some data has been read from the file into the buffer.
Definition Async.h:621
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start reading.
Definition Async.h:630
uint64_t getOffset() const
The file/pipe descriptor handle to read data from.
Definition Async.h:626
Definition Async.h:674
Starts a file write operation, writing bytes to a file (or pipe).
Definition Async.h:665
uint64_t getOffset() const
Returns the last offset set with AsyncFileWrite::setOffset.
Definition Async.h:702
FileDescriptor::Handle handle
The file/pipe descriptor to write data to.
Definition Async.h:694
SC::Result start(AsyncEventLoop &eventLoop, Span< const char > data)
Sets async request members and calls AsyncEventLoop::start.
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start writing.
Definition Async.h:706
Function< void(Result &)> callback
Callback called when descriptor is ready to be written with more data.
Definition Async.h:692
Span< Span< const char > > buffers
The read-only spans of memory where to read the data from.
Definition Async.h:698
SC::Result start(AsyncEventLoop &eventLoop, Span< Span< const char > > data)
Sets async request members and calls AsyncEventLoop::start.
Span< const char > buffer
The read-only span of memory where to read the data from.
Definition Async.h:697
bool singleBuffer
Controls if buffer or buffers will be used.
Definition Async.h:699
Allows user to supply a block of memory that will store kernel I/O events retrieved from AsyncEventLo...
Definition Async.h:903
Span< uint8_t > eventsMemory
User supplied block of memory used to store kernel I/O events.
Definition Async.h:904
Starts a Timeout that is invoked only once after expiration (relative) time has passed.
Definition Async.h:271
SC::Result start(AsyncEventLoop &eventLoop, Time::Milliseconds relativeTimeout)
Sets async request members and calls AsyncEventLoop::start.
Time::Absolute getExpirationTime() const
Gets computed absolute expiration time that determines when this timeout get executed.
Definition Async.h:285
Function< void(Result &)> callback
Called after given expiration time since AsyncLoopTimeout::start has passed.
Definition Async.h:280
Time::Milliseconds relativeTimeout
First timer expiration (relative) time in milliseconds.
Definition Async.h:282
Starts a wake-up operation, allowing threads to execute callbacks on loop thread.
Definition Async.h:306
SC::Result start(AsyncEventLoop &eventLoop, EventObject &eventObject)
Sets async request members and calls AsyncEventLoop::start.
Function< void(Result &)> callback
Callback called by SC::AsyncEventLoop::run after SC::AsyncLoopWakeUp::wakeUp.
Definition Async.h:319
SC::Result wakeUp()
Wakes up event loop, scheduling AsyncLoopWakeUp::callback on next AsyncEventLoop::run (or its variati...
EventObject * eventObject
Optional EventObject to let external threads wait for the callback to end.
Definition Async.h:320
Executes work in a thread pool and then invokes a callback on the event loop thread.
Definition Async.h:877
Function< void(Result &)> callback
Called to execute the work in a background threadpool thread.
Definition Async.h:891
SC::Result setThreadPool(ThreadPool &threadPool)
Sets the ThreadPool that will supply the thread to run the async work on.
Definition Async.h:343
Starts monitoring a process, notifying about its termination.
Definition Async.h:334
SC::Result start(AsyncEventLoop &eventLoop, ProcessDescriptor::Handle process)
Sets async request members and calls AsyncEventLoop::start.
Function< void(Result &)> callback
Called when process has exited.
Definition Async.h:357
Base class for all async requests, holding state and type.
Definition Async.h:118
bool isCancelling() const
Returns true if this request is being cancelled.
AsyncRequest(Type type)
Constructs a free async request of given type.
Definition Async.h:159
AsyncEventLoop * getEventLoop() const
Get the event loop associated with this AsyncRequest.
Definition Async.h:125
void resetThreadPoolAndTask()
Resets anything previously set with setThreadPoolAndTask.
Result stop(Function< void(AsyncResult &)> *afterStopped=nullptr)
Ask to stop current async operation.
bool isActive() const
Returns true if this request is active or being reactivated.
Result setThreadPoolAndTask(ThreadPool &pool, AsyncTask &task)
Sets the thread pool and task to use for this request.
void cacheInternalEventLoop(AsyncEventLoop &loop)
Caches the event loop associated with this AsyncRequest.
Definition Async.h:129
bool isFree() const
Returns true if this request is free.
Type getType() const
Returns request type.
Definition Async.h:178
Type
Type of async request.
Definition Async.h:141
@ FileClose
Request is an AsyncFileClose object.
@ SocketSend
Request is an AsyncSocketSend object.
@ SocketReceive
Request is an AsyncSocketReceive object.
@ SocketAccept
Request is an AsyncSocketAccept object.
@ FileWrite
Request is an AsyncFileWrite object.
@ LoopTimeout
Request is an AsyncLoopTimeout object.
@ ProcessExit
Request is an AsyncProcessExit object.
@ FileRead
Request is an AsyncFileRead object.
@ FilePoll
Request is an AsyncFilePoll object.
@ LoopWakeUp
Request is an AsyncLoopWakeUp object.
@ SocketClose
Request is an AsyncSocketClose object.
@ SocketConnect
Request is an AsyncSocketConnect object.
@ LoopWork
Request is an AsyncLoopWork object.
Result start(AsyncEventLoop &loop)
Shortcut for AsyncEventLoop::start.
Helper holding CompletionData for a specific AsyncRequest-derived class.
Definition Async.h:257
Base class for all async results (argument of completion callbacks).
Definition Async.h:227
void reactivateRequest(bool value)
Ask the event loop to re-activate this request after it was already completed.
const SC::Result & isValid() const
Check if the returnCode of this result is valid.
Definition Async.h:239
AsyncResult(AsyncRequest &request)
Constructs an async result from a request.
Definition Async.h:232
AsyncResult(AsyncRequest &request, SC::Result &&res)
Constructs an async result from a request and a result.
Definition Async.h:229
Definition Async.h:391
Starts a socket accept operation, obtaining a new socket from a listening socket.
Definition Async.h:382
Function< void(Result &)> callback
Called when a new socket has been accepted.
Definition Async.h:405
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor)
Sets async request members and calls AsyncEventLoop::start.
Starts a socket close operation.
Definition Async.h:555
int code
Return code of close socket operation.
Definition Async.h:566
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor)
Sets async request members and calls AsyncEventLoop::start.
Function< void(Result &)> callback
Callback called after fully closing the socket.
Definition Async.h:568
Starts a socket connect operation, connecting to a remote endpoint.
Definition Async.h:433
Function< void(Result &)> callback
Called after socket is finally connected to endpoint.
Definition Async.h:443
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, SocketIPAddress address)
Sets async request members and calls AsyncEventLoop::start.
Definition Async.h:521
SC::Result get(Span< char > &outData)
Get a Span of the actually read data.
Definition Async.h:527
Starts a socket receive operation, receiving bytes from a remote endpoint.
Definition Async.h:511
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< char > data)
Sets async request members and calls AsyncEventLoop::start.
Span< char > buffer
The writeable span of memory where to data will be written.
Definition Async.h:539
Function< void(Result &)> callback
Called after data has been received.
Definition Async.h:537
Starts a socket send operation, sending bytes to a remote endpoint.
Definition Async.h:466
Function< void(Result &)> callback
Called when socket is ready to send more data.
Definition Async.h:481
bool singleBuffer
Controls if buffer or buffers will be used.
Definition Async.h:487
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< const char > data)
Sets async request members and calls AsyncEventLoop::start.
Span< Span< const char > > buffers
Spans of bytes to send (singleBuffer == false)
Definition Async.h:486
Span< const char > buffer
Span of bytes to send (singleBuffer == true)
Definition Async.h:485
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< Span< const char > > data)
Sets async request members and calls AsyncEventLoop::start.
SocketDescriptor::Handle handle
The socket to send data to.
Definition Async.h:483
Holds (reference to) a SC::ThreadPool and SC::ThreadPool::Task to execute an SC::AsyncRequest in a ba...
Definition Async.h:854
Atomic variables (only for int and bool for now).
Definition Atomic.h:97
An automatically reset event object to synchronize two threads.
Definition Threading.h:174
File Descriptor (use SC::File to open and use it with strings and buffers).
Definition FileDescriptor.h:52
Wraps function pointers, member functions and lambdas without ever allocating.
Definition Function.h:19
Hides implementation details from public headers (static PIMPL).
Definition OpaqueObject.h:77
Definition ProcessDescriptor.h:44
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:12
Low-level OS socket handle.
Definition SocketDescriptor.h:147
AddressFamily
Sets the address family of an IP Address (IPv4 or IPV6)
Definition SocketDescriptor.h:73
@ AddressFamilyIPV4
IP Address is IPV4.
Definition SocketDescriptor.h:74
Native representation of an IP Address.
Definition SocketDescriptor.h:110
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:32
constexpr bool sliceStartLength(SizeType offsetInElements, SizeType lengthInElements, Span &destination) const
Creates another Span, starting at an offset in elements from current Span of specified length.
Definition Span.h:179
A small task containing a function to execute that can be queued in the thread pool.
Definition ThreadPool.h:19
Simple thread pool that executes tasks in a fixed number of worker threads.
Definition ThreadPool.h:41
A native OS thread.
Definition Threading.h:118
Absolute time as realtime or monotonically increasing clock.
Definition Time.h:114
Type-safe wrapper of uint64 used to represent milliseconds.
Definition Time.h:44
Represent monotonically increasing time (use Monotonic::now for current time)
Definition Time.h:180