Sane C++ Libraries
C++ Platform Abstraction Libraries
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"
16
41namespace SC
42{
43// Forward Declarations
44struct ThreadPool;
45struct ThreadPoolTask;
46
47struct EventObject;
48struct AsyncKernelEvents;
49struct AsyncEventLoopListeners;
50struct AsyncEventLoop;
51struct AsyncEventLoopMonitor;
52
53struct AsyncRequest;
54struct AsyncResult;
55template <typename T, typename C>
56struct AsyncResultOf;
57struct AsyncCompletionData;
58
59struct AsyncTask;
60template <typename AsyncType>
61struct AsyncTaskOf;
62} // namespace SC
63
64namespace SC
65{
66namespace detail
67{
68struct AsyncWinOverlapped;
69struct AsyncWinOverlappedDefinition
70{
71 static constexpr int Windows = sizeof(void*) * 4 + sizeof(uint64_t);
72 static constexpr size_t Alignment = alignof(void*);
73
74 using Object = AsyncWinOverlapped;
75};
76using WinOverlappedOpaque = OpaqueObject<AsyncWinOverlappedDefinition>;
77
78struct AsyncWinWaitDefinition
79{
80 using Handle = FileDescriptor::Handle; // fd
81 static constexpr Handle Invalid = FileDescriptor::Invalid; // invalid fd
82
83 static Result releaseHandle(Handle& waitHandle);
84};
85struct WinWaitHandle : public UniqueHandle<AsyncWinWaitDefinition>
86{
87};
88} // namespace detail
89} // namespace SC
90
93
133{
134 AsyncRequest* next = nullptr;
135 AsyncRequest* prev = nullptr;
136
137 void setDebugName(const char* newDebugName);
138
140 [[nodiscard]] AsyncEventLoop* getEventLoop() const { return eventLoop; }
141
144 void cacheInternalEventLoop(AsyncEventLoop& loop) { eventLoop = &loop; }
145
150
153
155 enum class Type : uint8_t
156 {
158 LoopWakeUp,
159 LoopWork,
163 SocketSend,
166 FileRead,
167 FileWrite,
168 FileClose,
169 FilePoll,
170 };
171
174 AsyncRequest(Type type) : state(State::Free), type(type), flags(0), eventIndex(-1) {}
175
181 [[nodiscard]] Result stop(Function<void(AsyncResult&)>* afterStopped = nullptr);
182
184 [[nodiscard]] bool isFree() const;
185
187 [[nodiscard]] bool isCancelling() const;
188
190 [[nodiscard]] bool isActive() const;
191
193 [[nodiscard]] Type getType() const { return type; }
194
195 protected:
196 [[nodiscard]] Result validateAsync();
197
198 void queueSubmission(AsyncEventLoop& eventLoop);
199
200 AsyncEventLoop* eventLoop = nullptr;
201 AsyncTask* asyncTask = nullptr;
202
203 private:
204 Function<void(AsyncResult&)>* closeCallback = nullptr;
205
206 friend struct AsyncEventLoop;
207 friend struct AsyncResult;
208
209 void markAsFree();
210
211 [[nodiscard]] static const char* TypeToString(Type type);
212 enum class State : uint8_t
213 {
214 Free, // not in any queue, this can be started with an async.start(...)
215 Setup, // when in submission queue waiting to be setup (after an async.start(...))
216 Submitting, // when in submission queue waiting to be activated or re-activated
217 Active, // when monitored by OS syscall or in activeLoopWakeUps / activeTimeouts queues
218 Reactivate, // when flagged for reactivation inside the callback (after a result.reactivateRequest(true))
219 Cancelling, // when in cancellation queue waiting for a cancelAsync (on active async)
220 };
221
222#if SC_CONFIGURATION_DEBUG
223 const char* debugName = "None";
224#endif
225 State state; // 1 byte
226 Type type; // 1 byte
227 int16_t flags; // 2 bytes
228 int32_t eventIndex; // 4 bytes
229};
230
233{
234};
235
239{
241 AsyncResult(AsyncRequest& request, SC::Result&& res) : async(request), returnCode(move(res)) {}
242
244 AsyncResult(AsyncRequest& request) : async(request) {}
245
248 void reactivateRequest(bool value);
249
251 [[nodiscard]] const SC::Result& isValid() const { return returnCode; }
252
253 AsyncRequest& async;
254
255 protected:
256 friend struct AsyncEventLoop;
257
258 bool shouldBeReactivated = false;
259 bool shouldCallCallback = true;
260
261 SC::Result returnCode = SC::Result(true);
262};
263
267template <typename T, typename C>
269{
270 T& getAsync() { return static_cast<T&>(AsyncResult::async); }
271 const T& getAsync() const { return static_cast<const T&>(AsyncResult::async); }
272
274
275 C completionData;
276};
277
285{
286 AsyncTask(AsyncCompletionData& asyncCompletionData) : completionData(asyncCompletionData) {}
287
288 protected:
289 ThreadPoolTask task;
290 ThreadPool* threadPool = nullptr;
291
292 void freeTask() { async = nullptr; }
293 bool isFree() const { return async == nullptr; }
294
295 friend struct AsyncEventLoop;
296 friend struct AsyncRequest;
297
298 AsyncCompletionData& completionData;
299
300 SC::Result returnCode = SC::Result(true);
301 AsyncRequest* async = nullptr;
302};
303
307template <typename AsyncType>
309{
310 typename AsyncType::CompletionData asyncCompletionData;
311 AsyncTaskOf() : AsyncTask(asyncCompletionData) {}
312};
313
314namespace SC
315{
318
324{
326
329
332
339
345
347
349
351 Time::Absolute getExpirationTime() const { return expirationTime; }
352
353 private:
354 friend struct AsyncEventLoop;
355 Time::Absolute expirationTime;
356};
357
371{
373
376
379
384 SC::Result start(AsyncEventLoop& eventLoop, EventObject* eventObject = nullptr);
385
388
390
391 private:
392 friend struct AsyncEventLoop;
393
394 EventObject* eventObject = nullptr;
395 Atomic<bool> pending = false;
396};
397
404{
406
409
412
416
421
422 Function<SC::Result()> work;
424
425 private:
427};
428
434{
436
439 {
441 };
442
444 struct Result : public AsyncResultOf<AsyncProcessExit, CompletionData>
445 {
447
449 {
450 status = completionData.exitStatus;
451 return returnCode;
452 }
453 };
454
459 SC::Result start(AsyncEventLoop& eventLoop, ProcessDescriptor::Handle process);
460
462
463 private:
464 friend struct AsyncEventLoop;
465 ProcessDescriptor::Handle handle = ProcessDescriptor::Invalid;
466#if SC_PLATFORM_WINDOWS
468 detail::WinWaitHandle waitHandle;
469#elif SC_PLATFORM_LINUX
470 FileDescriptor pidFd;
471#endif
472};
473
484{
486
489 {
490 SocketDescriptor acceptedClient;
491 };
492
494 struct Result : public AsyncResultOf<AsyncSocketAccept, CompletionData>
495 {
497
498 SC::Result moveTo(SocketDescriptor& client)
499 {
500 SC_TRY(returnCode);
501 return client.assign(move(completionData.acceptedClient));
502 }
503 };
504
510 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
511
513
514 private:
515 friend struct AsyncEventLoop;
516 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
518#if SC_PLATFORM_WINDOWS
519 void (*pAcceptEx)() = nullptr;
521 SocketDescriptor clientSocket;
522 uint8_t acceptBuffer[288] = {0};
523#elif SC_PLATFORM_LINUX
524 AlignedStorage<28> sockAddrHandle;
525 uint32_t sockAddrLen;
526#endif
527};
528
538{
540
543
546
553 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, SocketIPAddress address);
554
556
557 private:
558 friend struct AsyncEventLoop;
559 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
560 SocketIPAddress ipAddress;
561#if SC_PLATFORM_WINDOWS
562 void (*pConnectEx)() = nullptr;
564#endif
565};
566
576{
578
581 {
582 size_t numBytes = 0;
583 };
584
587
595
603
611
613
614 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
615
618 bool singleBuffer = true;
619
620 private:
621 friend struct AsyncEventLoop;
622
623 size_t totalBytesWritten = 0;
624#if SC_PLATFORM_WINDOWS
626#endif
627};
628
641{
643
646 {
647 size_t numBytes = 0;
648 bool disconnected = false;
649 };
650
652 struct Result : public AsyncResultOf<AsyncSocketReceive, CompletionData>
653 {
655
660 {
661 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, outData));
662 return returnCode;
663 }
664 };
665
672 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, Span<char> data);
673
680
682
684 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
685
686 private:
687#if SC_PLATFORM_WINDOWS
688 friend struct AsyncEventLoop;
690#endif
691};
692
698{
700
703
706
712 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor);
713
714 // TODO: Move code to CompletionData
715 int code = 0;
716
718
719 private:
720 friend struct AsyncEventLoop;
721
722 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
723};
724
746{
747 AsyncFileRead() : AsyncRequest(Type::FileRead) { handle = FileDescriptor::Invalid; }
748
751 {
752 size_t numBytes = 0;
753 bool endOfFile = false;
754 };
755
757 struct Result : public AsyncResultOf<AsyncFileRead, CompletionData>
758 {
760
761 SC::Result get(Span<char>& data)
762 {
763 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, data));
764 return returnCode;
765 }
766 };
767
769
778 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
779
780 Function<void(Result&)> callback;
781
783 FileDescriptor::Handle handle;
785
787 uint64_t getOffset() const { return offset; }
788
791 void setOffset(uint64_t fileOffset)
792 {
793 useOffset = true;
794 offset = fileOffset;
795 }
796
797 private:
798 friend struct AsyncEventLoop;
799 bool useOffset = false;
800 uint64_t offset = 0;
801#if SC_PLATFORM_WINDOWS
802 uint64_t readCursor = 0;
804#endif
805};
806
825{
826 AsyncFileWrite() : AsyncRequest(Type::FileWrite) { handle = FileDescriptor::Invalid; }
827
830 {
831 size_t numBytes = 0;
832 };
833
835 struct Result : public AsyncResultOf<AsyncFileWrite, CompletionData>
836 {
838
839 SC::Result get(size_t& writtenSizeInBytes)
840 {
841 writtenSizeInBytes = completionData.numBytes;
842 return returnCode;
843 }
844 };
845
847
859
865
871
873
874 FileDescriptor::Handle handle;
876
879 bool singleBuffer = true;
880
882 uint64_t getOffset() const { return offset; }
883
886 void setOffset(uint64_t fileOffset)
887 {
888 useOffset = true;
889 offset = fileOffset;
890 }
891
892 private:
893 friend struct AsyncEventLoop;
894 bool isWatchable = false;
895 bool useOffset = false;
896 uint64_t offset = 0xffffffffffffffff;
897
898 size_t totalBytesWritten = 0;
899#if SC_PLATFORM_WINDOWS
901#endif
902};
903
910{
912
915
918
919 SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle fileDescriptor);
920
921 // TODO: Move code to CompletionData
922 int code = 0;
923
925
926 private:
927 friend struct AsyncEventLoop;
928 FileDescriptor::Handle handle = FileDescriptor::Invalid;
929};
930
936{
938
941
944
946 SC::Result start(AsyncEventLoop& loop, FileDescriptor::Handle fileDescriptor);
947
948#if SC_PLATFORM_WINDOWS
949 [[nodiscard]] auto& getOverlappedOpaque() { return overlapped; }
950#endif
951
952 Function<void(Result&)> callback;
953
954 private:
955 friend struct AsyncEventLoop;
956
957 FileDescriptor::Handle handle = FileDescriptor::Invalid;
958#if SC_PLATFORM_WINDOWS
960#endif
961};
962
964
965} // namespace SC
966
971{
973
974 private:
975 int numberOfEvents = 0;
976 friend struct AsyncEventLoop;
977};
978
981{
982 Function<void(AsyncEventLoop&)> beforeBlockingPoll;
983 Function<void(AsyncEventLoop&)> afterBlockingPoll;
984};
985
993{
995 struct Options
996 {
997 enum class ApiType : uint8_t
998 {
999 Automatic = 0,
1002 };
1004
1006 };
1007
1009
1011 [[nodiscard]] Result create(Options options = Options());
1012
1014 [[nodiscard]] Result close();
1015
1018
1020 [[nodiscard]] bool isInitialized() const;
1021
1027 [[nodiscard]] Result run();
1028
1038 [[nodiscard]] Result runOnce();
1039
1045 [[nodiscard]] Result runNoWait();
1046
1051 [[nodiscard]] Result submitRequests(AsyncKernelEvents& kernelEvents);
1052
1071 [[nodiscard]] Result blockingPoll(AsyncKernelEvents& kernelEvents);
1072
1078 [[nodiscard]] Result dispatchCompletions(AsyncKernelEvents& kernelEvents);
1079
1083
1086
1090
1093
1096
1099
1101 [[nodiscard]] Time::Monotonic getLoopTime() const;
1102
1104 [[nodiscard]] int getNumberOfActiveRequests() const;
1105
1107 [[nodiscard]] int getNumberOfSubmittedRequests() const;
1108
1112
1115
1118
1120 void enumerateRequests(Function<void(AsyncRequest&)> enumerationCallback);
1121
1125
1127 [[nodiscard]] static bool isExcludedFromActiveCount(const AsyncRequest& async);
1128
1131 [[nodiscard]] static bool tryLoadingLiburing();
1132
1133 struct Internal;
1134
1135 private:
1136 struct InternalDefinition
1137 {
1138 static constexpr int Windows = 488;
1139 static constexpr int Apple = 480;
1140 static constexpr int Linux = 688;
1141 static constexpr int Default = Linux;
1142
1143 static constexpr size_t Alignment = 8;
1144
1145 using Object = Internal;
1146 };
1147
1148 public:
1149 using InternalOpaque = OpaqueObject<InternalDefinition>;
1150
1151 private:
1152 InternalOpaque internalOpaque;
1153 Internal& internal;
1154
1155 friend struct AsyncRequest;
1156 friend struct AsyncFileWrite;
1157 friend struct AsyncFileRead;
1158};
1159
1164{
1166
1170
1173
1181
1187
1188 private:
1189#if SC_COMPILER_MSVC
1190#pragma warning(push)
1191#pragma warning(disable : 4324) // useless warning on 32 bit... (structure was padded due to __declspec(align()))
1192#endif
1193 alignas(uint64_t) uint8_t eventsMemory[8 * 1024]; // 8 Kb of kernel events
1194#if SC_COMPILER_MSVC
1195#pragma warning(pop)
1196#endif
1197
1198 AsyncKernelEvents asyncKernelEvents;
1199 AsyncEventLoop* eventLoop = nullptr;
1200 AsyncLoopWakeUp eventLoopWakeUp;
1201
1202 Thread eventLoopThread;
1203 EventObject eventObjectEnterBlockingMode;
1204 EventObject eventObjectExitBlockingMode;
1205
1206 Atomic<bool> finished = false;
1207 Atomic<bool> needsWakeUp = true;
1208
1209 bool wakeUpHasBeenCalled = false;
1210
1211 Result monitoringLoopThread(Thread& thread);
1212};
1213
int int32_t
Platform independent (4) bytes signed int.
Definition: PrimitiveTypes.h:46
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
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition: Result.h:48
short int16_t
Platform independent (2) bytes signed int.
Definition: PrimitiveTypes.h:45
A buffer of bytes with given alignment.
Definition: AlignedStorage.h:29
Empty base struct for all AsyncRequest-derived CompletionData (internal) structs.
Definition: Async.h:233
Options given to AsyncEventLoop::create.
Definition: Async.h:996
ApiType apiType
Criteria to choose Async IO API.
Definition: Async.h:1003
ApiType
Definition: Async.h:998
@ 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:993
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.
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.
Allow library user to provide callbacks signaling different phases of async event loop cycle.
Definition: Async.h:981
Monitors Async I/O events from a background thread using a blocking kernel function (no CPU usage on ...
Definition: Async.h:1164
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:1165
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.
Starts a file close operation, closing the OS file descriptor.
Definition: Async.h:910
int code
Return code of close socket operation.
Definition: Async.h:922
Function< void(Result &)> callback
Callback called after fully closing the file descriptor.
Definition: Async.h:924
Starts an handle polling operation.
Definition: Async.h:936
SC::Result start(AsyncEventLoop &loop, FileDescriptor::Handle fileDescriptor)
Starts a file descriptor poll operation, monitoring its readiness with appropriate OS API.
Completion data for AsyncFileRead.
Definition: Async.h:751
Callback result for AsyncFileRead.
Definition: Async.h:758
Starts a file read operation, reading bytes from a file (or pipe).
Definition: Async.h:746
FileDescriptor::Handle handle
The writeable span of memory where to data will be written.
Definition: Async.h:783
Span< char > buffer
Callback called when some data has been read from the file into the buffer.
Definition: Async.h:782
SC::Result start(AsyncEventLoop &eventLoop)
Starts a file receive operation, that completes when data has been read from file / pipe.
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start reading.
Definition: Async.h:791
uint64_t getOffset() const
The file/pipe descriptor handle to read data from.
Definition: Async.h:787
Completion data for AsyncFileWrite.
Definition: Async.h:830
Callback result for AsyncFileWrite.
Definition: Async.h:836
Starts a file write operation, writing bytes to a file (or pipe).
Definition: Async.h:825
uint64_t getOffset() const
Returns the last offset set with AsyncFileWrite::setOffset.
Definition: Async.h:882
FileDescriptor::Handle handle
The file/pipe descriptor to write data to.
Definition: Async.h:874
SC::Result start(AsyncEventLoop &eventLoop, Span< const char > data)
Starts a file write operation with a single buffer.
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start writing.
Definition: Async.h:886
Function< void(Result &)> callback
Callback called when descriptor is ready to be written with more data.
Definition: Async.h:872
Span< Span< const char > > buffers
The read-only spans of memory where to read the data from.
Definition: Async.h:878
SC::Result start(AsyncEventLoop &eventLoop)
Starts a file write operation that completes when it's ready to receive more bytes.
SC::Result start(AsyncEventLoop &eventLoop, Span< Span< const char > > data)
Starts a file write operation with multiple buffers.
Span< const char > buffer
The read-only span of memory where to read the data from.
Definition: Async.h:877
bool singleBuffer
Controls if buffer or buffers will be used.
Definition: Async.h:879
Allows user to supply a block of memory that will store kernel I/O events retrieved from AsyncEventLo...
Definition: Async.h:971
Span< uint8_t > eventsMemory
User supplied block of memory used to store kernel I/O events.
Definition: Async.h:972
Starts a Timeout that is invoked only once after expiration (relative) time has passed.
Definition: Async.h:324
SC::Result start(AsyncEventLoop &eventLoop, Time::Milliseconds relativeTimeout)
Starts a Timeout that is invoked (only once) after the specific relative expiration time has passed.
Time::Absolute getExpirationTime() const
Gets computed absolute expiration time that determines when this timeout get executed.
Definition: Async.h:351
Function< void(Result &)> callback
Called after given expiration time since AsyncLoopTimeout::start has passed.
Definition: Async.h:346
Time::Milliseconds relativeTimeout
First timer expiration (relative) time in milliseconds.
Definition: Async.h:348
SC::Result start(AsyncEventLoop &eventLoop)
Starts a Timeout that is invoked (only once) after the specific relative expiration time has passed.
Starts a wake-up operation, allowing threads to execute callbacks on loop thread.
Definition: Async.h:371
SC::Result start(AsyncEventLoop &eventLoop, EventObject *eventObject=nullptr)
Starts a wake up request, that will be fulfilled when an external thread calls AsyncLoopWakeUp::wakeU...
Function< void(Result &)> callback
Callback called by SC::AsyncEventLoop::run after SC::AsyncLoopWakeUp::wakeUp.
Definition: Async.h:389
SC::Result wakeUp()
Wakes up event loop, scheduling AsyncLoopWakeUp::callback on next AsyncEventLoop::run (or its variati...
Executes work in a thread pool and then invokes a callback on the event loop thread.
Definition: Async.h:404
Function< void(Result &)> callback
Called to execute the work in a background threadpool thread.
Definition: Async.h:423
SC::Result setThreadPool(ThreadPool &threadPool)
Sets the ThreadPool that will supply the thread to run the async work on.
SC::Result start(AsyncEventLoop &eventLoop)
Schedule work to be executed on a background thread, notifying the event loop when it's finished.
Completion data for AsyncProcessExit.
Definition: Async.h:439
Callback result for AsyncProcessExit.
Definition: Async.h:445
Starts monitoring a process, notifying about its termination.
Definition: Async.h:434
SC::Result start(AsyncEventLoop &eventLoop, ProcessDescriptor::Handle process)
Starts monitoring a process, notifying about its termination.
Function< void(Result &)> callback
Called when process has exited.
Definition: Async.h:461
Base class for all async requests, holding state and type.
Definition: Async.h:133
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:174
AsyncEventLoop * getEventLoop() const
Get the event loop associated with this AsyncRequest.
Definition: Async.h:140
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:144
bool isFree() const
Returns true if this request is free.
Type getType() const
Returns request type.
Definition: Async.h:193
Type
Type of async request.
Definition: Async.h:156
@ 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.
Base class for all async results (argument of completion callbacks).
Definition: Async.h:239
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:251
AsyncResult(AsyncRequest &request)
Constructs an async result from a request.
Definition: Async.h:244
AsyncResult(AsyncRequest &request, SC::Result &&res)
Constructs an async result from a request and a result.
Definition: Async.h:241
Helper holding CompletionData for a specific AsyncRequest-derived class.
Definition: Async.h:269
Completion data for AsyncSocketAccept.
Definition: Async.h:489
Callback result for AsyncSocketAccept.
Definition: Async.h:495
Starts a socket accept operation, obtaining a new socket from a listening socket.
Definition: Async.h:484
Function< void(Result &)> callback
Called when a new socket has been accepted.
Definition: Async.h:512
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor)
Starts a socket accept operation, that returns a new socket connected to the given listening endpoint...
Starts a socket close operation.
Definition: Async.h:698
int code
Return code of close socket operation.
Definition: Async.h:715
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor)
Starts a socket close operation.
Function< void(Result &)> callback
Callback called after fully closing the socket.
Definition: Async.h:717
Starts a socket connect operation, connecting to a remote endpoint.
Definition: Async.h:538
Function< void(Result &)> callback
Called after socket is finally connected to endpoint.
Definition: Async.h:555
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, SocketIPAddress address)
Starts a socket connect operation.
Completion data for AsyncSocketReceive.
Definition: Async.h:646
Callback result for AsyncSocketReceive.
Definition: Async.h:653
SC::Result get(Span< char > &outData)
Get a Span of the actually read data.
Definition: Async.h:659
Starts a socket receive operation, receiving bytes from a remote endpoint.
Definition: Async.h:641
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< char > data)
Starts a socket receive operation.
SC::Result start(AsyncEventLoop &eventLoop)
Starts a socket receive operation.
Span< char > buffer
The writeable span of memory where to data will be written.
Definition: Async.h:683
Function< void(Result &)> callback
Called after data has been received.
Definition: Async.h:681
Completion data for AsyncSocketSend.
Definition: Async.h:581
Starts a socket send operation, sending bytes to a remote endpoint.
Definition: Async.h:576
Function< void(Result &)> callback
Called when socket is ready to send more data.
Definition: Async.h:612
bool singleBuffer
Controls if buffer or buffers will be used.
Definition: Async.h:618
SC::Result start(AsyncEventLoop &eventLoop)
Starts a socket send operation (single or multiple epending on AsyncSocketSend::singleBuffer) Callbac...
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< const char > data)
Starts a socket send operation (single buffer).
Span< Span< const char > > buffers
Spans of bytes to send (singleBuffer == false)
Definition: Async.h:617
Span< const char > buffer
Span of bytes to send (singleBuffer == true)
Definition: Async.h:616
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< Span< const char > > data)
Starts a socket send operation (multiple buffers).
SocketDescriptor::Handle handle
The socket to send data to.
Definition: Async.h:614
Holds (reference to) a SC::ThreadPool and SC::ThreadPool::Task to execute an SC::AsyncRequest in a ba...
Definition: Async.h:285
Create an async Callback result for a given AsyncRequest-derived class.
Definition: Async.h:309
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
A native OS thread.
Definition: Threading.h:118
Simple thread pool that executes tasks in a fixed number of worker threads.
Definition: ThreadPool.h:41
A small task containing a function to execute that can be queued in the thread pool.
Definition: ThreadPool.h:19
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