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 AsyncEventLoop;
50struct AsyncEventLoopMonitor;
51
52struct AsyncRequest;
53struct AsyncResult;
54template <typename T, typename C>
55struct AsyncResultOf;
56struct AsyncCompletionData;
57
58struct AsyncTask;
59template <typename AsyncType>
60struct AsyncTaskOf;
61} // namespace SC
62
63namespace SC
64{
65namespace detail
66{
67struct AsyncWinOverlapped;
68struct AsyncWinOverlappedDefinition
69{
70 static constexpr int Windows = sizeof(void*) * 4 + sizeof(uint64_t);
71 static constexpr size_t Alignment = alignof(void*);
72
73 using Object = AsyncWinOverlapped;
74};
75using WinOverlappedOpaque = OpaqueObject<AsyncWinOverlappedDefinition>;
76
77struct AsyncWinWaitDefinition
78{
79 using Handle = FileDescriptor::Handle; // fd
80 static constexpr Handle Invalid = FileDescriptor::Invalid; // invalid fd
81
82 static Result releaseHandle(Handle& waitHandle);
83};
84struct WinWaitHandle : public UniqueHandle<AsyncWinWaitDefinition>
85{
86};
87} // namespace detail
88} // namespace SC
89
92
132{
133 AsyncRequest* next = nullptr;
134 AsyncRequest* prev = nullptr;
135
136 void setDebugName(const char* newDebugName);
137
139 [[nodiscard]] AsyncEventLoop* getEventLoop() const { return eventLoop; }
140
143 void cacheInternalEventLoop(AsyncEventLoop& loop) { eventLoop = &loop; }
144
149
152
154 enum class Type : uint8_t
155 {
157 LoopWakeUp,
158 LoopWork,
162 SocketSend,
165 FileRead,
166 FileWrite,
167 FileClose,
168 FilePoll,
169 };
170
173 AsyncRequest(Type type) : state(State::Free), type(type), flags(0), eventIndex(-1) {}
174
180 [[nodiscard]] Result stop(Function<void(AsyncResult&)>* afterStopped = nullptr);
181
183 [[nodiscard]] bool isFree() const;
184
186 [[nodiscard]] bool isCancelling() const;
187
189 [[nodiscard]] bool isActive() const;
190
192 [[nodiscard]] Type getType() const { return type; }
193
194 protected:
195 [[nodiscard]] Result validateAsync();
196
197 void queueSubmission(AsyncEventLoop& eventLoop);
198
199 AsyncEventLoop* eventLoop = nullptr;
200 AsyncTask* asyncTask = nullptr;
201
202 private:
203 Function<void(AsyncResult&)>* closeCallback = nullptr;
204
205 friend struct AsyncEventLoop;
206 friend struct AsyncResult;
207
208 void markAsFree();
209
210 [[nodiscard]] static const char* TypeToString(Type type);
211 enum class State : uint8_t
212 {
213 Free, // not in any queue, this can be started with an async.start(...)
214 Setup, // when in submission queue waiting to be setup (after an async.start(...))
215 Submitting, // when in submission queue waiting to be activated or re-activated
216 Active, // when monitored by OS syscall or in activeLoopWakeUps / activeTimeouts queues
217 Reactivate, // when flagged for reactivation inside the callback (after a result.reactivateRequest(true))
218 Cancelling, // when in cancellation queue waiting for a cancelAsync (on active async)
219 };
220
221#if SC_CONFIGURATION_DEBUG
222 const char* debugName = "None";
223#endif
224 State state; // 1 byte
225 Type type; // 1 byte
226 int16_t flags; // 2 bytes
227 int32_t eventIndex; // 4 bytes
228};
229
232{
233};
234
238{
240 AsyncResult(AsyncRequest& request, SC::Result&& res) : async(request), returnCode(move(res)) {}
241
243 AsyncResult(AsyncRequest& request) : async(request) {}
244
247 void reactivateRequest(bool value);
248
250 [[nodiscard]] const SC::Result& isValid() const { return returnCode; }
251
252 AsyncRequest& async;
253
254 protected:
255 friend struct AsyncEventLoop;
256
257 bool shouldBeReactivated = false;
258 bool shouldCallCallback = true;
259
260 SC::Result returnCode = SC::Result(true);
261};
262
266template <typename T, typename C>
268{
269 T& getAsync() { return static_cast<T&>(AsyncResult::async); }
270 const T& getAsync() const { return static_cast<const T&>(AsyncResult::async); }
271
273
274 C completionData;
275};
276
284{
285 AsyncTask(AsyncCompletionData& asyncCompletionData) : completionData(asyncCompletionData) {}
286
287 protected:
288 ThreadPoolTask task;
289 ThreadPool* threadPool = nullptr;
290
291 void freeTask() { async = nullptr; }
292 bool isFree() const { return async == nullptr; }
293
294 friend struct AsyncEventLoop;
295 friend struct AsyncRequest;
296
297 AsyncCompletionData& completionData;
298
299 SC::Result returnCode = SC::Result(true);
300 AsyncRequest* async = nullptr;
301};
302
306template <typename AsyncType>
308{
309 typename AsyncType::CompletionData asyncCompletionData;
310 AsyncTaskOf() : AsyncTask(asyncCompletionData) {}
311};
312
313namespace SC
314{
317
323{
325
328
331
338
343 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
344
346
348
349 Time::HighResolutionCounter getExpirationTime() const { return expirationTime; }
350
351 private:
352 friend struct AsyncEventLoop;
353 Time::HighResolutionCounter expirationTime;
354};
355
369{
371
374
377
382 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, EventObject* eventObject = nullptr);
383
385 [[nodiscard]] SC::Result wakeUp();
386
388
389 private:
390 friend struct AsyncEventLoop;
391
392 EventObject* eventObject = nullptr;
393 Atomic<bool> pending = false;
394};
395
402{
404
407
410
413 [[nodiscard]] SC::Result setThreadPool(ThreadPool& threadPool);
414
418 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
419
420 Function<SC::Result()> work;
422
423 private:
425};
426
432{
434
437 {
439 };
440
442 struct Result : public AsyncResultOf<AsyncProcessExit, CompletionData>
443 {
445
446 [[nodiscard]] SC::Result get(ProcessDescriptor::ExitStatus& status)
447 {
448 status = completionData.exitStatus;
449 return returnCode;
450 }
451 };
452
457 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, ProcessDescriptor::Handle process);
458
460
461 private:
462 friend struct AsyncEventLoop;
463 ProcessDescriptor::Handle handle = ProcessDescriptor::Invalid;
464#if SC_PLATFORM_WINDOWS
466 detail::WinWaitHandle waitHandle;
467#elif SC_PLATFORM_LINUX
468 FileDescriptor pidFd;
469#endif
470};
471
482{
484
487 {
488 SocketDescriptor acceptedClient;
489 };
490
492 struct Result : public AsyncResultOf<AsyncSocketAccept, CompletionData>
493 {
495
496 [[nodiscard]] SC::Result moveTo(SocketDescriptor& client)
497 {
498 SC_TRY(returnCode);
499 return client.assign(move(completionData.acceptedClient));
500 }
501 };
502
508 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
509
511
512 private:
513 friend struct AsyncEventLoop;
514 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
516#if SC_PLATFORM_WINDOWS
517 void (*pAcceptEx)() = nullptr;
519 SocketDescriptor clientSocket;
520 uint8_t acceptBuffer[288] = {0};
521#elif SC_PLATFORM_LINUX
522 AlignedStorage<28> sockAddrHandle;
523 uint32_t sockAddrLen;
524#endif
525};
526
536{
538
541
544
551 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor,
552 SocketIPAddress ipAddress);
553
555
556 private:
557 friend struct AsyncEventLoop;
558 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
559 SocketIPAddress ipAddress;
560#if SC_PLATFORM_WINDOWS
561 void (*pConnectEx)() = nullptr;
563#endif
564};
565
575{
577
580 {
581 size_t numBytes = 0;
582 };
583
586
593 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor,
594 Span<const char> data);
595
601 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
602
604
606 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
607
608 private:
609 friend struct AsyncEventLoop;
610
611#if SC_PLATFORM_WINDOWS
613#else
614 size_t totalBytesSent = 0;
615#endif
616};
617
630{
632
635 {
636 size_t numBytes = 0;
637 bool disconnected = false;
638 };
639
641 struct Result : public AsyncResultOf<AsyncSocketReceive, CompletionData>
642 {
644
648 [[nodiscard]] SC::Result get(Span<char>& outData)
649 {
650 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, outData));
651 return returnCode;
652 }
653 };
654
661 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor,
662 Span<char> data);
663
669 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
670
672
674 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
675
676 private:
677#if SC_PLATFORM_WINDOWS
678 friend struct AsyncEventLoop;
680#endif
681};
682
688{
690
693
696
702 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
703
704 // TODO: Move code to CompletionData
705 int code = 0;
706
708
709 private:
710 friend struct AsyncEventLoop;
711
712 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
713};
714
736{
737 AsyncFileRead() : AsyncRequest(Type::FileRead) { fileDescriptor = FileDescriptor::Invalid; }
738
741 {
742 size_t numBytes = 0;
743 bool endOfFile = false;
744 };
745
747 struct Result : public AsyncResultOf<AsyncFileRead, CompletionData>
748 {
750
751 [[nodiscard]] SC::Result get(Span<char>& data)
752 {
753 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, data));
754 return returnCode;
755 }
756 };
757
759
768 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
769
770 Function<void(Result&)> callback;
771
773 FileDescriptor::Handle fileDescriptor;
775
777 uint64_t getOffset() const { return offset; }
778
781 void setOffset(uint64_t fileOffset)
782 {
783 useOffset = true;
784 offset = fileOffset;
785 }
786
787 private:
788 friend struct AsyncEventLoop;
789 bool useOffset = false;
790 uint64_t offset = 0;
791#if SC_PLATFORM_WINDOWS
792 uint64_t readCursor = 0;
794#endif
795};
796
815{
816 AsyncFileWrite() : AsyncRequest(Type::FileWrite) { fileDescriptor = FileDescriptor::Invalid; }
817
820 {
821 size_t numBytes = 0;
822 };
823
825 struct Result : public AsyncResultOf<AsyncFileWrite, CompletionData>
826 {
828
829 [[nodiscard]] SC::Result get(size_t& writtenSizeInBytes)
830 {
831 writtenSizeInBytes = completionData.numBytes;
832 return returnCode;
833 }
834 };
835
837
846 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
847
848 Function<void(Result&)> callback;
849
851 FileDescriptor::Handle fileDescriptor;
853
855 uint64_t getOffset() const { return offset; }
856
859 void setOffset(uint64_t fileOffset)
860 {
861 useOffset = true;
862 offset = fileOffset;
863 }
864
865 private:
866 friend struct AsyncEventLoop;
867 bool useOffset = false;
868 uint64_t offset = 0xffffffffffffffff;
869#if SC_PLATFORM_WINDOWS
871#endif
872};
873
880{
882
885
888
889 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle fileDescriptor);
890
891 // TODO: Move code to CompletionData
892 int code = 0;
893
895
896 private:
897 friend struct AsyncEventLoop;
898 FileDescriptor::Handle fileDescriptor = FileDescriptor::Invalid;
899};
900
906{
908
911
914
916 [[nodiscard]] SC::Result start(AsyncEventLoop& loop, FileDescriptor::Handle fileDescriptor);
917
918#if SC_PLATFORM_WINDOWS
919 [[nodiscard]] auto& getOverlappedOpaque() { return overlapped; }
920#endif
921
922 Function<void(Result&)> callback;
923
924 private:
925 friend struct AsyncEventLoop;
926
927 FileDescriptor::Handle fileDescriptor = FileDescriptor::Invalid;
928#if SC_PLATFORM_WINDOWS
930#endif
931};
932
934
935} // namespace SC
936
941{
943
944 private:
945 int numberOfEvents = 0;
946 friend struct AsyncEventLoop;
947};
948
956{
958 struct Options
959 {
960 enum class ApiType : uint8_t
961 {
962 Automatic = 0,
965 };
967
969 };
970
972
974 [[nodiscard]] Result create(Options options = Options());
975
977 [[nodiscard]] Result close();
978
980 void interrupt();
981
983 [[nodiscard]] bool isInitialized() const;
984
990 [[nodiscard]] Result run();
991
1001 [[nodiscard]] Result runOnce();
1002
1008 [[nodiscard]] Result runNoWait();
1009
1014 [[nodiscard]] Result submitRequests(AsyncKernelEvents& kernelEvents);
1015
1033 [[nodiscard]] Result blockingPoll(AsyncKernelEvents& kernelEvents);
1034
1040 [[nodiscard]] Result dispatchCompletions(AsyncKernelEvents& kernelEvents);
1041
1045
1048
1052
1055
1058
1061
1064
1066 [[nodiscard]] int getNumberOfActiveRequests() const;
1067
1069 [[nodiscard]] int getNumberOfSubmittedRequests() const;
1070
1073
1076
1078 void enumerateRequests(Function<void(AsyncRequest&)> enumerationCallback);
1079
1081 [[nodiscard]] static bool isExcludedFromActiveCount(const AsyncRequest& async);
1082
1085 [[nodiscard]] static bool tryLoadingLiburing();
1086
1087 struct Internal;
1088
1089 private:
1090 struct InternalDefinition
1091 {
1092 static constexpr int Windows = 496;
1093 static constexpr int Apple = 488;
1094 static constexpr int Linux = 696;
1095 static constexpr int Default = Linux;
1096
1097 static constexpr size_t Alignment = 8;
1098
1099 using Object = Internal;
1100 };
1101
1102 public:
1103 using InternalOpaque = OpaqueObject<InternalDefinition>;
1104
1105 private:
1106 InternalOpaque internalOpaque;
1107 Internal& internal;
1108
1109 friend struct AsyncRequest;
1110 friend struct AsyncFileWrite;
1111 friend struct AsyncFileRead;
1112};
1113
1118{
1120
1124
1127
1135
1141
1142 private:
1143 alignas(uint64_t) uint8_t eventsMemory[8 * 1024]; // 8 Kb of kernel events
1144 AsyncKernelEvents asyncKernelEvents;
1145 AsyncEventLoop* eventLoop = nullptr;
1146 AsyncLoopWakeUp eventLoopWakeUp;
1147
1148 Thread eventLoopThread;
1149 EventObject eventObjectEnterBlockingMode;
1150 EventObject eventObjectExitBlockingMode;
1151
1152 Atomic<bool> finished = false;
1153 Atomic<bool> needsWakeUp = true;
1154
1155 bool wakeUpHasBeenCalled = false;
1156
1157 Result monitoringLoopThread(Thread& thread);
1158};
1159
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:25
Empty base struct for all AsyncRequest-derived CompletionData (internal) structs.
Definition: Async.h:232
Options given to AsyncEventLoop::create.
Definition: Async.h:959
ApiType apiType
Criteria to choose Async IO API.
Definition: Async.h:966
ApiType
Definition: Async.h:961
@ 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:956
Result associateExternallyCreatedFileDescriptor(FileDescriptor &outDescriptor)
Associates a File descriptor created externally with the eventLoop.
Time::HighResolutionCounter getLoopTime() const
Get Loop time.
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 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.
Monitors Async I/O events from a background thread using a blocking kernel function (no CPU usage on ...
Definition: Async.h:1118
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:1119
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:880
int code
Return code of close socket operation.
Definition: Async.h:892
Function< void(Result &)> callback
Callback called after fully closing the file descriptor.
Definition: Async.h:894
Starts an handle polling operation.
Definition: Async.h:906
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:741
Callback result for AsyncFileRead.
Definition: Async.h:748
Starts a file read operation, reading bytes from a file (or pipe).
Definition: Async.h:736
Span< char > buffer
Callback called when some data has been read from the file into the buffer.
Definition: Async.h:772
FileDescriptor::Handle fileDescriptor
The writeable span of memory where to data will be written.
Definition: Async.h:773
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:781
uint64_t getOffset() const
The file/pipe descriptor handle to read data from.
Definition: Async.h:777
Completion data for AsyncFileWrite.
Definition: Async.h:820
Callback result for AsyncFileWrite.
Definition: Async.h:826
Starts a file write operation, writing bytes to a file (or pipe).
Definition: Async.h:815
uint64_t getOffset() const
The file/pipe descriptor to write data to.
Definition: Async.h:855
FileDescriptor::Handle fileDescriptor
The read-only span of memory where to read the data from.
Definition: Async.h:851
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start writing.
Definition: Async.h:859
SC::Result start(AsyncEventLoop &eventLoop)
Starts a file write operation that completes when it's ready to receive more bytes.
Span< const char > buffer
Callback called when descriptor is ready to be written with more data.
Definition: Async.h:850
Allows user to supply a block of memory that will store kernel I/O events retrieved from AsyncEventLo...
Definition: Async.h:941
Span< uint8_t > eventsMemory
User supplied block of memory used to store kernel I/O events.
Definition: Async.h:942
Starts a Timeout that is invoked only once after expiration (relative) time has passed.
Definition: Async.h:323
SC::Result start(AsyncEventLoop &eventLoop, Time::Milliseconds relativeTimeout)
Starts a Timeout that is invoked (only once) after the specific relative expiration time has passed.
Function< void(Result &)> callback
Called after given expiration time since AsyncLoopTimeout::start has passed.
Definition: Async.h:345
Time::Milliseconds relativeTimeout
First timer expiration (relative) time in milliseconds.
Definition: Async.h:347
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:369
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:387
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:402
Function< void(Result &)> callback
Called to execute the work in a background threadpool thread.
Definition: Async.h:421
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:437
Callback result for AsyncProcessExit.
Definition: Async.h:443
Starts monitoring a process, notifying about its termination.
Definition: Async.h:432
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:459
Base class for all async requests, holding state and type.
Definition: Async.h:132
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:173
AsyncEventLoop * getEventLoop() const
Get the event loop associated with this AsyncRequest.
Definition: Async.h:139
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:143
bool isFree() const
Returns true if this request is free.
Type getType() const
Returns request type.
Definition: Async.h:192
Type
Type of async request.
Definition: Async.h:155
@ 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:238
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:250
AsyncResult(AsyncRequest &request)
Constructs an async result from a request.
Definition: Async.h:243
AsyncResult(AsyncRequest &request, SC::Result &&res)
Constructs an async result from a request and a result.
Definition: Async.h:240
Helper holding CompletionData for a specific AsyncRequest-derived class.
Definition: Async.h:268
Completion data for AsyncSocketAccept.
Definition: Async.h:487
Callback result for AsyncSocketAccept.
Definition: Async.h:493
Starts a socket accept operation, obtaining a new socket from a listening socket.
Definition: Async.h:482
Function< void(Result &)> callback
Called when a new socket has been accepted.
Definition: Async.h:510
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:688
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor)
Starts a socket close operation.
int code
Return code of close socket operation.
Definition: Async.h:705
Function< void(Result &)> callback
Callback called after fully closing the socket.
Definition: Async.h:707
Starts a socket connect operation, connecting to a remote endpoint.
Definition: Async.h:536
Function< void(Result &)> callback
Called after socket is finally connected to endpoint.
Definition: Async.h:554
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor, SocketIPAddress ipAddress)
Starts a socket connect operation.
Completion data for AsyncSocketReceive.
Definition: Async.h:635
Callback result for AsyncSocketReceive.
Definition: Async.h:642
SC::Result get(Span< char > &outData)
Get a Span of the actually read data.
Definition: Async.h:648
Starts a socket receive operation, receiving bytes from a remote endpoint.
Definition: Async.h:630
SC::Result start(AsyncEventLoop &eventLoop)
Starts a socket receive operation.
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor, Span< char > data)
Starts a socket receive operation.
Span< char > buffer
The writeable span of memory where to data will be written.
Definition: Async.h:673
Function< void(Result &)> callback
Called after data has been received.
Definition: Async.h:671
Completion data for AsyncSocketSend.
Definition: Async.h:580
Starts a socket send operation, sending bytes to a remote endpoint.
Definition: Async.h:575
Function< void(Result &)> callback
Called when socket is ready to send more data.
Definition: Async.h:603
SC::Result start(AsyncEventLoop &eventLoop)
Starts a socket send operation.
Span< const char > buffer
Span of bytes to send.
Definition: Async.h:605
SocketDescriptor::Handle handle
The socket to send data to.
Definition: Async.h:606
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor, Span< const char > data)
Starts a socket send operation.
Holds (reference to) a SC::ThreadPool and SC::ThreadPool::Task to execute an SC::AsyncRequest in a ba...
Definition: Async.h:284
Create an async Callback result for a given AsyncRequest-derived class.
Definition: Async.h:308
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 containers).
Definition: FileDescriptor.h:52
Wraps function pointers, member functions and lambdas without ever allocating.
Definition: Function.h:50
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:24
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
An high resolution time counter.
Definition: Time.h:171
Type-safe wrapper of uint64 used to represent milliseconds.
Definition: Time.h:42