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 "../Time/Time.h"
10
11// Descriptors
12#include "../File/FileDescriptor.h"
13#include "../Process/ProcessDescriptor.h"
14#include "../Socket/SocketDescriptor.h"
15#include "../Threading/ThreadPool.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*) * 7;
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
146 enum class Type : uint8_t
147 {
149 LoopWakeUp,
150 LoopWork,
154 SocketSend,
157 FileRead,
158 FileWrite,
159 FileClose,
160 FilePoll,
161 };
162
165 AsyncRequest(Type type) : state(State::Free), type(type), flags(0), eventIndex(-1) {}
166
168
171 [[nodiscard]] Result stop();
172
173 [[nodiscard]] bool isFree() const { return state == State::Free; }
174
175 protected:
176 [[nodiscard]] Result validateAsync();
177 [[nodiscard]] Result queueSubmission(AsyncEventLoop& eventLoop);
178 [[nodiscard]] Result queueSubmission(AsyncEventLoop& eventLoop, ThreadPool& threadPool, AsyncTask& task);
179
180 AsyncEventLoop* eventLoop = nullptr;
181 AsyncTask* asyncTask = nullptr;
182
183 private:
184 friend struct AsyncEventLoop;
185
186 void markAsFree();
187
188 [[nodiscard]] static const char* TypeToString(Type type);
189 enum class State : uint8_t
190 {
191 Free, // not in any queue, this can be started with an async.start(...)
192 Setup, // when in submission queue waiting to be setup (after an async.start(...))
193 Submitting, // when in submission queue waiting to be activated (after a result.reactivateRequest(true))
194 Active, // when monitored by OS syscall or in activeLoopWakeUps / activeTimeouts queues
195 Cancelling, // when in cancellation queue waiting for a cancelAsync (on active async)
196 Teardown // when in cancellation queue waiting for a teardownAsync (on non-active, already setup async)
197 };
198
199#if SC_CONFIGURATION_DEBUG
200 const char* debugName = "None";
201#endif
202 State state; // 1 byte
203 Type type; // 1 byte
204 int16_t flags; // 2 bytes
205 int32_t eventIndex; // 4 bytes
206};
207
210{
211};
212
216{
218 AsyncResult(AsyncRequest& request, SC::Result&& res) : async(request), returnCode(move(res)) {}
219
221 AsyncResult(AsyncRequest& request) : async(request) {}
222
225 void reactivateRequest(bool value) { shouldBeReactivated = value; }
226
228 [[nodiscard]] const SC::Result& isValid() const { return returnCode; }
229
230 AsyncRequest& async;
231
232 protected:
233 friend struct AsyncEventLoop;
234
235 bool shouldBeReactivated = false;
236 bool shouldCallCallback = true;
237
238 SC::Result returnCode = SC::Result(true);
239};
240
244template <typename T, typename C>
246{
247 T& getAsync() { return static_cast<T&>(AsyncResult::async); }
248 const T& getAsync() const { return static_cast<const T&>(AsyncResult::async); }
249
251
252 C completionData;
253};
254
262{
263 AsyncTask(AsyncCompletionData& asyncCompletionData) : completionData(asyncCompletionData) {}
264
265 protected:
266 ThreadPoolTask task;
267 ThreadPool* threadPool = nullptr;
268
269 void freeTask() { async = nullptr; }
270 bool isFree() const { return async == nullptr; }
271
272 friend struct AsyncEventLoop;
273 friend struct AsyncRequest;
274
275 AsyncCompletionData& completionData;
276
277 SC::Result returnCode = SC::Result(true);
278 AsyncRequest* async = nullptr;
279};
280
284template <typename AsyncType>
286{
287 typename AsyncType::CompletionData asyncCompletionData;
288 AsyncTaskOf() : AsyncTask(asyncCompletionData) {}
289};
290
291namespace SC
292{
295
301{
303
306
309
316
319
320 private:
321 friend struct AsyncEventLoop;
322 Time::HighResolutionCounter expirationTime;
323};
324
338{
340
343
346
351 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, EventObject* eventObject = nullptr);
352
354 [[nodiscard]] SC::Result wakeUp();
355
357
358 private:
359 friend struct AsyncEventLoop;
360
361 EventObject* eventObject = nullptr;
362 Atomic<bool> pending = false;
363};
364
371{
373
376
379
383 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, ThreadPool& threadPool);
384
385 Function<SC::Result()> work;
387
388 private:
390};
391
397{
399
402 {
404 };
405
407 struct Result : public AsyncResultOf<AsyncProcessExit, CompletionData>
408 {
410
411 [[nodiscard]] SC::Result get(ProcessDescriptor::ExitStatus& status)
412 {
413 status = completionData.exitStatus;
414 return returnCode;
415 }
416 };
417
422 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, ProcessDescriptor::Handle process);
423
425
426 private:
427 friend struct AsyncEventLoop;
428 ProcessDescriptor::Handle handle = ProcessDescriptor::Invalid;
429#if SC_PLATFORM_WINDOWS
431 detail::WinWaitHandle waitHandle;
432#elif SC_PLATFORM_LINUX
433 FileDescriptor pidFd;
434#endif
435};
436
447{
449
452 {
453 SocketDescriptor acceptedClient;
454 };
455
457 struct Result : public AsyncResultOf<AsyncSocketAccept, CompletionData>
458 {
460
461 [[nodiscard]] SC::Result moveTo(SocketDescriptor& client)
462 {
463 SC_TRY(returnCode);
464 return client.assign(move(completionData.acceptedClient));
465 }
466 };
467
473 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
474
476
477 private:
478 friend struct AsyncEventLoop;
479 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
481#if SC_PLATFORM_WINDOWS
483
484 SocketDescriptor clientSocket;
485 uint8_t acceptBuffer[288] = {0};
486#elif SC_PLATFORM_LINUX
487 AlignedStorage<28> sockAddrHandle;
488 uint32_t sockAddrLen;
489#endif
490};
491
501{
503
506
509
516 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor,
517 SocketIPAddress ipAddress);
518
520
521 private:
522 friend struct AsyncEventLoop;
523 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
524 SocketIPAddress ipAddress;
525#if SC_PLATFORM_WINDOWS
527#endif
528};
529
539{
541
544 {
545 size_t numBytes = 0;
546 };
547
550
557 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor,
558 Span<const char> data);
559
565 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
566
568
570 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
571
572 private:
573 friend struct AsyncEventLoop;
574
575#if SC_PLATFORM_WINDOWS
577#else
578 size_t totalBytesSent = 0;
579#endif
580};
581struct AsyncSocketReceive;
582
595{
597
600 {
601 size_t numBytes = 0;
602 bool disconnected = false;
603 };
604
606 struct Result : public AsyncResultOf<AsyncSocketReceive, CompletionData>
607 {
609
613 [[nodiscard]] SC::Result get(Span<char>& outData)
614 {
615 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, outData));
616 return returnCode;
617 }
618 };
619
626 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor,
627 Span<char> data);
628
634 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
635
637
639 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
640
641 private:
642#if SC_PLATFORM_WINDOWS
643 friend struct AsyncEventLoop;
645#endif
646};
647
653{
655
658
661
667 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
668
669 // TODO: Move code to CompletionData
670 int code = 0;
671
673
674 private:
675 friend struct AsyncEventLoop;
676
677 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
678};
679
701{
702 AsyncFileRead() : AsyncRequest(Type::FileRead) { fileDescriptor = FileDescriptor::Invalid; }
703
706 {
707 size_t numBytes = 0;
708 bool endOfFile = false;
709 };
710
712 struct Result : public AsyncResultOf<AsyncFileRead, CompletionData>
713 {
715
716 [[nodiscard]] SC::Result get(Span<char>& data)
717 {
718 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, data));
719 return returnCode;
720 }
721 };
722
724
729 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
730
738 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, ThreadPool& threadPool, Task& task);
739
740 Function<void(Result&)> callback;
741
743 FileDescriptor::Handle fileDescriptor;
746
748 uint64_t getOffset() const { return offset; }
749
752 void setOffset(uint64_t fileOffset)
753 {
754 useOffset = true;
755 offset = fileOffset;
756 }
757
758 private:
759 friend struct AsyncEventLoop;
760 bool useOffset = false;
761 uint64_t offset = 0;
762#if SC_PLATFORM_WINDOWS
763 uint64_t readCursor = 0;
765#endif
766};
767
786{
787 AsyncFileWrite() : AsyncRequest(Type::FileWrite) { fileDescriptor = FileDescriptor::Invalid; }
788
791 {
792 size_t numBytes = 0;
793 };
794
796 struct Result : public AsyncResultOf<AsyncFileWrite, CompletionData>
797 {
799
800 [[nodiscard]] SC::Result get(size_t& writtenSizeInBytes)
801 {
802 writtenSizeInBytes = completionData.numBytes;
803 return returnCode;
804 }
805 };
806
808
813 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop);
814
822 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, ThreadPool& threadPool, Task& task);
823
824 Function<void(Result&)> callback;
825
827 FileDescriptor::Handle fileDescriptor;
830
832 uint64_t getOffset() const { return offset; }
833
836 void setOffset(uint64_t fileOffset)
837 {
838 useOffset = true;
839 offset = fileOffset;
840 }
841
842 private:
843 friend struct AsyncEventLoop;
844 bool useOffset = false;
845 uint64_t offset = 0xffffffffffffffff;
846#if SC_PLATFORM_WINDOWS
848#endif
849};
850
857{
859
862
865
866 [[nodiscard]] SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle fileDescriptor);
867
868 // TODO: Move code to CompletionData
869 int code = 0;
870
872
873 private:
874 friend struct AsyncEventLoop;
875 FileDescriptor::Handle fileDescriptor = FileDescriptor::Invalid;
876};
877
883{
885
888
891
893 [[nodiscard]] SC::Result start(AsyncEventLoop& loop, FileDescriptor::Handle fileDescriptor);
894
895#if SC_PLATFORM_WINDOWS
896 [[nodiscard]] auto& getOverlappedOpaque() { return overlapped; }
897#endif
898
899 Function<void(Result&)> callback;
900
901 private:
902 friend struct AsyncEventLoop;
903
904 FileDescriptor::Handle fileDescriptor = FileDescriptor::Invalid;
905#if SC_PLATFORM_WINDOWS
907#endif
908};
909
911
912} // namespace SC
913
918{
920
921 private:
922 int numberOfEvents = 0;
923 friend struct AsyncEventLoop;
924};
925
933{
935 struct Options
936 {
937 enum class ApiType
938 {
939 Automatic = 0,
942 };
944
946 };
947
949
951 [[nodiscard]] Result create(Options options = Options());
952
954 [[nodiscard]] Result close();
955
961 [[nodiscard]] Result run();
962
972 [[nodiscard]] Result runOnce();
973
979 [[nodiscard]] Result runNoWait();
980
985 [[nodiscard]] Result submitRequests(AsyncKernelEvents& kernelEvents);
986
1004 [[nodiscard]] Result blockingPoll(AsyncKernelEvents& kernelEvents);
1005
1011 [[nodiscard]] Result dispatchCompletions(AsyncKernelEvents& kernelEvents);
1012
1016
1019
1023
1026
1029
1032
1035 [[nodiscard]] static bool tryLoadingLiburing();
1036
1037 struct Internal;
1038
1039 private:
1040 struct InternalDefinition
1041 {
1042 static constexpr int Windows = 528;
1043 static constexpr int Apple = 472;
1044 static constexpr int Default = 688;
1045
1046 static constexpr size_t Alignment = 8;
1047
1048 using Object = Internal;
1049 };
1050
1051 public:
1052 using InternalOpaque = OpaqueObject<InternalDefinition>;
1053
1054 private:
1055 InternalOpaque internalOpaque;
1056 Internal& internal;
1057
1058 friend struct AsyncRequest;
1059 friend struct AsyncFileWrite;
1060 friend struct AsyncFileRead;
1061};
1062
1067{
1069
1073
1076
1084
1090
1091 private:
1092 alignas(uint64_t) uint8_t eventsMemory[8 * 1024]; // 8 Kb of kernel events
1093 AsyncKernelEvents asyncKernelEvents;
1094 AsyncEventLoop* eventLoop = nullptr;
1095 AsyncLoopWakeUp eventLoopWakeUp;
1096
1097 Thread eventLoopThread;
1098 EventObject eventObjectEnterBlockingMode;
1099 EventObject eventObjectExitBlockingMode;
1100
1101 Atomic<bool> finished = false;
1102 Atomic<bool> needsWakeUp = true;
1103
1104 bool wakeUpHasBeenCalled = false;
1105
1106 Result monitoringLoopThread(Thread& thread);
1107};
1108
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:47
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:210
Options given to AsyncEventLoop::create.
Definition: Async.h:936
ApiType apiType
Criteria to choose Async IO API.
Definition: Async.h:943
ApiType
Definition: Async.h:938
@ 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:933
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...
Result blockingPoll(AsyncKernelEvents &kernelEvents)
Blocks until at least one event happens, ensuring forward progress, without executing completions.
Result submitRequests(AsyncKernelEvents &kernelEvents)
Submits all queued async requests.
Result dispatchCompletions(AsyncKernelEvents &kernelEvents)
Invokes completions for the AsyncKernelEvents collected by a call to AsyncEventLoop::blockingPoll.
Result wakeUpFromExternalThread(AsyncLoopWakeUp &wakeUp)
Wake up the event loop from a thread different than the one where run() is called (and potentially bl...
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.
Result run()
Blocks until there are no more active queued requests, dispatching all completions.
Monitors Async I/O events from a background thread using a blocking kernel function (no CPU usage on ...
Definition: Async.h:1067
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:1068
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:857
int code
Return code of close socket operation.
Definition: Async.h:869
Function< void(Result &)> callback
Callback called after fully closing the file descriptor.
Definition: Async.h:871
Starts an handle polling operation.
Definition: Async.h:883
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:706
Callback result for AsyncFileRead.
Definition: Async.h:713
Starts a file read operation, reading bytes from a file (or pipe).
Definition: Async.h:701
Span< char > buffer
Callback called when some data has been read from the file into the buffer.
Definition: Async.h:742
FileDescriptor::Handle fileDescriptor
The writeable span of memory where to data will be written.
Definition: Async.h:743
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:752
uint64_t getOffset() const
The file/pipe descriptor handle to read data from.
Definition: Async.h:748
SC::Result start(AsyncEventLoop &eventLoop, ThreadPool &threadPool, Task &task)
Starts a file receive operation on thread pool, that completes when data has been read from file / pi...
Completion data for AsyncFileWrite.
Definition: Async.h:791
Callback result for AsyncFileWrite.
Definition: Async.h:797
Starts a file write operation, writing bytes to a file (or pipe).
Definition: Async.h:786
uint64_t getOffset() const
The file/pipe descriptor to write data to.
Definition: Async.h:832
FileDescriptor::Handle fileDescriptor
The read-only span of memory where to read the data from.
Definition: Async.h:827
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start writing.
Definition: Async.h:836
SC::Result start(AsyncEventLoop &eventLoop, ThreadPool &threadPool, Task &task)
Starts a file write operation on thread pool that completes when it's ready to receive more bytes.
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:826
Allows user to supply a block of memory that will store kernel I/O events retrieved from AsyncEventLo...
Definition: Async.h:918
Span< uint8_t > eventsMemory
User supplied block of memory used to store kernel I/O events.
Definition: Async.h:919
Starts a Timeout that is invoked only once after expiration (relative) time has passed.
Definition: Async.h:301
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:317
Time::Milliseconds relativeTimeout
Timer expiration (relative) time in milliseconds.
Definition: Async.h:318
Starts a wake-up operation, allowing threads to execute callbacks on loop thread.
Definition: Async.h:338
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:356
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:371
SC::Result start(AsyncEventLoop &eventLoop, ThreadPool &threadPool)
Schedule work to be executed on a background thread, notifying the event loop when it's finished.
Function< void(Result &)> callback
Called to execute the work in a background threadpool thread.
Definition: Async.h:386
Completion data for AsyncProcessExit.
Definition: Async.h:402
Callback result for AsyncProcessExit.
Definition: Async.h:408
Starts monitoring a process, notifying about its termination.
Definition: Async.h:397
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:424
Base class for all async requests, holding state and type.
Definition: Async.h:132
AsyncRequest(Type type)
Constructs a free async request of given type.
Definition: Async.h:165
AsyncEventLoop * getEventLoop() const
Get the event loop associated with this AsyncRequest.
Definition: Async.h:139
void cacheInternalEventLoop(AsyncEventLoop &loop)
Caches the event loop associated with this AsyncRequest.
Definition: Async.h:143
Result stop()
Stops the async operation.
Type
Type of async request.
Definition: Async.h:147
@ 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:216
void reactivateRequest(bool value)
Ask the event loop to re-activate this request after it was already completed.
Definition: Async.h:225
const SC::Result & isValid() const
Check if the returnCode of this result is valid.
Definition: Async.h:228
AsyncResult(AsyncRequest &request)
Constructs an async result from a request.
Definition: Async.h:221
AsyncResult(AsyncRequest &request, SC::Result &&res)
Constructs an async result from a request and a result.
Definition: Async.h:218
Helper holding CompletionData for a specific AsyncRequest-derived class.
Definition: Async.h:246
Completion data for AsyncSocketAccept.
Definition: Async.h:452
Callback result for AsyncSocketAccept.
Definition: Async.h:458
Starts a socket accept operation, obtaining a new socket from a listening socket.
Definition: Async.h:447
Function< void(Result &)> callback
Called when a new socket has been accepted.
Definition: Async.h:475
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:653
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor)
Starts a socket close operation.
int code
Return code of close socket operation.
Definition: Async.h:670
Function< void(Result &)> callback
Callback called after fully closing the socket.
Definition: Async.h:672
Starts a socket connect operation, connecting to a remote endpoint.
Definition: Async.h:501
Function< void(Result &)> callback
Called after socket is finally connected to endpoint.
Definition: Async.h:519
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor, SocketIPAddress ipAddress)
Starts a socket connect operation.
Completion data for AsyncSocketReceive.
Definition: Async.h:600
Callback result for AsyncSocketReceive.
Definition: Async.h:607
SC::Result get(Span< char > &outData)
Get a Span of the actually read data.
Definition: Async.h:613
Starts a socket receive operation, receiving bytes from a remote endpoint.
Definition: Async.h:595
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:638
Function< void(Result &)> callback
Called after data has been received.
Definition: Async.h:636
Completion data for AsyncSocketSend.
Definition: Async.h:544
Starts a socket send operation, sending bytes to a remote endpoint.
Definition: Async.h:539
Function< void(Result &)> callback
Called when socket is ready to send more data.
Definition: Async.h:567
SC::Result start(AsyncEventLoop &eventLoop)
Starts a socket send operation.
Span< const char > buffer
Span of bytes to send.
Definition: Async.h:569
SocketDescriptor::Handle handle
The socket to send data to.
Definition: Async.h:570
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:262
Create an async Callback result for a given AsyncRequest-derived class.
Definition: Async.h:286
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
Wraps an OS File descriptor to read and write to and from it.
Definition: FileDescriptor.h:57
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:76
Definition: ProcessDescriptor.h:44
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition: Result.h:11
Low-level OS socket handle.
Definition: SocketDescriptor.h:154
AddressFamily
Sets the address family of an IP Address (IPv4 or IPV6)
Definition: SocketDescriptor.h:84
@ AddressFamilyIPV4
IP Address is IPV4.
Definition: SocketDescriptor.h:85
Native representation of an IP Address.
Definition: SocketDescriptor.h:120
View over a contiguous sequence of items (pointer + size in elements).
Definition: Span.h:20
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:135
Type-safe wrapper of uint64 used to represent milliseconds.
Definition: Time.h:29