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/Compiler.h"
6#ifndef SC_EXPORT_LIBRARY_ASYNC
7#define SC_EXPORT_LIBRARY_ASYNC 0
8#endif
9#define SC_ASYNC_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_ASYNC)
10
11#include "../Async/Internal/IntrusiveDoubleLinkedList.h"
12#include "../File/File.h"
13#include "../FileSystem/FileSystem.h"
14#include "../Foundation/Function.h"
15#include "../Foundation/OpaqueObject.h"
16#include "../Socket/Socket.h"
17#include "../Threading/Atomic.h"
18#include "../Threading/ThreadPool.h"
19
20namespace SC
21{
22struct ThreadPool;
23struct ThreadPoolTask;
24struct EventObject;
25} // namespace SC
50
53namespace SC
54{
55struct AsyncEventLoop;
56struct AsyncResult;
57struct AsyncSequence;
58struct AsyncTaskSequence;
59
60namespace detail
61{
62struct AsyncWinOverlapped;
63struct AsyncWinOverlappedDefinition
64{
65 static constexpr int Windows = sizeof(void*) * 4 + sizeof(uint64_t);
66 static constexpr size_t Alignment = alignof(void*);
67
68 using Object = AsyncWinOverlapped;
69};
70using WinOverlappedOpaque = OpaqueObject<AsyncWinOverlappedDefinition>;
71
72struct AsyncWinWaitDefinition
73{
74 using Handle = FileDescriptor::Handle; // fd
75 static constexpr Handle Invalid = FileDescriptor::Invalid; // invalid fd
76
77 static Result releaseHandle(Handle& waitHandle);
78};
79struct SC_ASYNC_EXPORT WinWaitHandle : public UniqueHandle<AsyncWinWaitDefinition>
80{
81};
82} // namespace detail
83
122struct SC_ASYNC_EXPORT AsyncRequest
123{
124 AsyncRequest* next = nullptr;
125 AsyncRequest* prev = nullptr;
126
127 void setDebugName(const char* newDebugName);
128
130 void executeOn(AsyncSequence& sequence);
131
136
139
141 enum class Type : uint8_t
142 {
143 LoopTimeout,
144 LoopWakeUp,
145 LoopWork,
146 ProcessExit,
147 Signal,
148 SocketAccept,
149 SocketConnect,
150 SocketSend,
151 SocketSendTo,
152 SocketReceive,
153 SocketReceiveFrom,
154 FileRead,
155 FileWrite,
156 FileSend,
157 FilePoll,
158 FileSystemOperation,
159 };
160
163 AsyncRequest(Type type) : state(State::Free), type(type), flags(0), unused(0), userFlags(0) {}
164
171 Result stop(AsyncEventLoop& eventLoop, Function<void(AsyncResult&)>* afterStopped = nullptr);
172
174 [[nodiscard]] bool isFree() const;
175
177 [[nodiscard]] bool isCancelling() const;
178
180 [[nodiscard]] bool isActive() const;
181
183 [[nodiscard]] Type getType() const { return type; }
184
187
189 void setUserFlags(uint16_t externalFlags) { userFlags = externalFlags; }
190
192 uint16_t getUserFlags() const { return userFlags; }
193
195 [[nodiscard]] Function<void(AsyncResult&)>* getCloseCallback() { return closeCallback; }
196
197 [[nodiscard]] const Function<void(AsyncResult&)>* getCloseCallback() const { return closeCallback; }
198
199 protected:
200 Result checkState();
201
202 void queueSubmission(AsyncEventLoop& eventLoop);
203
204 AsyncSequence* sequence = nullptr;
205
206 AsyncTaskSequence* getTask();
207
208 private:
209 Function<void(AsyncResult&)>* closeCallback = nullptr;
210
211 friend struct AsyncEventLoop;
212 friend struct AsyncResult;
213
214 void markAsFree();
215
216 [[nodiscard]] static const char* TypeToString(Type type);
217 enum class State : uint8_t
218 {
219 Free, // not in any queue, this can be started with an async.start(...)
220 Setup, // when in submission queue waiting to be setup (after an async.start(...))
221 Submitting, // when in submission queue waiting to be activated or re-activated
222 Active, // when monitored by OS syscall or in activeLoopWakeUps / activeTimeouts queues
223 Reactivate, // when flagged for reactivation inside the callback (after a result.reactivateRequest(true))
224 Cancelling, // when in cancellation queue waiting for a cancelAsync (on active async)
225 };
226
227#if SC_ASYNC_ENABLE_LOG
228 const char* debugName = "None";
229#endif
230 State state; // 1 byte
231 Type type; // 1 byte
232 int16_t flags; // 2 bytes
233
234 uint16_t unused; // 2 bytes
235 uint16_t userFlags; // 2 bytes
236};
237
242struct SC_ASYNC_EXPORT AsyncSequence
243{
244 AsyncSequence* next = nullptr;
245 AsyncSequence* prev = nullptr;
246
247 bool clearSequenceOnCancel = true;
248 bool clearSequenceOnError = true;
249 private:
250 friend struct AsyncEventLoop;
251 bool runningAsync = false; // true if an async from this sequence is being run
252 bool tracked = false;
253
254 IntrusiveDoubleLinkedList<AsyncRequest> submissions;
255};
256
258struct SC_ASYNC_EXPORT AsyncCompletionData
259{
260};
261
264struct SC_ASYNC_EXPORT AsyncResult
265{
267 AsyncResult(AsyncEventLoop& eventLoop, AsyncRequest& request, SC::Result& res, bool* hasBeenReactivated = nullptr)
268 : eventLoop(eventLoop), async(request), hasBeenReactivated(hasBeenReactivated), returnCode(res)
269 {}
270
273 void reactivateRequest(bool shouldBeReactivated);
274
276 [[nodiscard]] const SC::Result& isValid() const { return returnCode; }
277
278 AsyncEventLoop& eventLoop;
279 AsyncRequest& async;
280
281 protected:
282 friend struct AsyncEventLoop;
283
284 bool shouldCallCallback = true;
285 bool* hasBeenReactivated = nullptr;
286
287 SC::Result& returnCode;
288};
289
293template <typename T, typename C>
295{
296 T& getAsync() { return static_cast<T&>(AsyncResult::async); }
297 const T& getAsync() const { return static_cast<const T&>(AsyncResult::async); }
298
300
301 C completionData;
302 int32_t eventIndex = 0;
303};
304
309struct SC_ASYNC_EXPORT AsyncLoopTimeout : public AsyncRequest
310{
311 AsyncLoopTimeout() : AsyncRequest(Type::LoopTimeout) {}
312
315 using AsyncRequest::start;
316
318 SC::Result start(AsyncEventLoop& eventLoop, TimeMs relativeTimeout);
319
321
323
325 TimeMs getExpirationTime() const { return expirationTime; }
326
327 private:
328 SC::Result validate(AsyncEventLoop&);
329 friend struct AsyncEventLoop;
330 TimeMs expirationTime;
331};
332
335{
338 bool coalesce = true;
339};
340
357struct SC_ASYNC_EXPORT AsyncLoopWakeUp : public AsyncRequest
358{
359 AsyncLoopWakeUp() : AsyncRequest(Type::LoopWakeUp) {}
360
362 {
363 uint32_t deliveryCount = 1;
364 };
365
367
370
372 SC::Result start(AsyncEventLoop& eventLoop, EventObject& eventObject, AsyncLoopWakeUpOptions options = {});
373
376
378 EventObject* eventObject = nullptr;
379
380 private:
381 friend struct AsyncEventLoop;
382 SC::Result validate(AsyncEventLoop&);
383 int32_t consumePendingWakeUps();
384 int32_t getPendingWakeUps() const;
385
386 AsyncLoopWakeUpOptions wakeUpOptions;
387 Atomic<int32_t> pendingWakeUps = 0;
388};
389
394struct SC_ASYNC_EXPORT AsyncProcessExit : public AsyncRequest
395{
396 AsyncProcessExit() : AsyncRequest(Type::ProcessExit) {}
397
399 {
400 int exitStatus;
401 };
402
403 struct Result : public AsyncResultOf<AsyncProcessExit, CompletionData>
404 {
405 using AsyncResultOf<AsyncProcessExit, CompletionData>::AsyncResultOf;
406
407 SC::Result get(int& status)
408 {
409 status = completionData.exitStatus;
410 return returnCode;
411 }
412 };
413 using AsyncRequest::start;
414
418 SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle process);
419
421
422 private:
423 friend struct AsyncEventLoop;
424 SC::Result validate(AsyncEventLoop&);
425
426 FileDescriptor::Handle handle = FileDescriptor::Invalid;
427#if SC_PLATFORM_WINDOWS
429 detail::WinWaitHandle waitHandle;
430 AsyncEventLoop* eventLoop = nullptr;
431#elif SC_PLATFORM_LINUX
432 FileDescriptor pidFd;
433#endif
434};
435
438{
440 enum class Mode : uint8_t
441 {
442 Persistent,
443 OneShot
444 };
446 bool coalesce = true;
447};
448
456struct SC_ASYNC_EXPORT AsyncSignal : public AsyncRequest
457{
458 AsyncSignal() : AsyncRequest(Type::Signal) {}
459
461 {
462 int signalNumber = 0;
463 uint32_t deliveryCount = 1;
464 };
465
466 struct Result : public AsyncResultOf<AsyncSignal, CompletionData>
467 {
468 using AsyncResultOf<AsyncSignal, CompletionData>::AsyncResultOf;
469 };
470 using AsyncRequest::start;
471
473 SC::Result start(AsyncEventLoop& eventLoop, int num, AsyncSignalOptions options = {});
474
476
477 private:
478 friend struct AsyncEventLoop;
479 SC::Result validate(AsyncEventLoop&);
480
481 int signalNumber = 0;
482 AsyncSignalOptions signalOptions;
483#if SC_PLATFORM_WINDOWS
485 AsyncEventLoop* eventLoop = nullptr;
486#elif SC_PLATFORM_LINUX
487 FileDescriptor signalFd;
488 FileDescriptor::Handle signalFdHandle = FileDescriptor::Invalid;
489#endif
490};
491
492struct AsyncSocketAccept;
493namespace detail
494{
497struct SC_ASYNC_EXPORT AsyncSocketAcceptData
498{
499#if SC_PLATFORM_WINDOWS
500 void (*pAcceptEx)() = nullptr;
502 SocketDescriptor clientSocket;
503 uint8_t acceptBuffer[288] = {0};
504#elif SC_PLATFORM_LINUX
505 AlignedStorage<28> sockAddrHandle;
506 uint32_t sockAddrLen;
507#endif
508};
509
511struct SC_ASYNC_EXPORT AsyncSocketAcceptBase : public AsyncRequest
512{
513 AsyncSocketAcceptBase() : AsyncRequest(Type::SocketAccept) {}
514
515 struct CompletionData : public AsyncCompletionData
516 {
517 SocketDescriptor acceptedClient;
518 };
519
520 struct Result : public AsyncResultOf<AsyncSocketAccept, CompletionData>
521 {
522 using AsyncResultOf<AsyncSocketAccept, CompletionData>::AsyncResultOf;
523
524 SC::Result moveTo(SocketDescriptor& client)
525 {
526 SC_TRY(returnCode);
527 return client.assign(move(completionData.acceptedClient));
528 }
529 };
530 using AsyncRequest::start;
531
533 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor, AsyncSocketAcceptData& data);
534 SC::Result validate(AsyncEventLoop&);
535
536 Function<void(Result&)> callback;
537 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
538 SocketFlags::AddressFamily addressFamily = SocketFlags::AddressFamilyIPV4;
539 AsyncSocketAcceptData* acceptData = nullptr;
540};
541
542} // namespace detail
543
553struct SC_ASYNC_EXPORT AsyncSocketAccept : public detail::AsyncSocketAcceptBase
554{
555 AsyncSocketAccept() { AsyncSocketAcceptBase::acceptData = &data; }
556 using AsyncSocketAcceptBase::start;
557
559 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& socketDescriptor);
560
561 private:
562 detail::AsyncSocketAcceptData data;
563};
564
573struct SC_ASYNC_EXPORT AsyncSocketConnect : public AsyncRequest
574{
575 AsyncSocketConnect() : AsyncRequest(Type::SocketConnect) {}
576
579 using AsyncRequest::start;
580
582 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, SocketIPAddress address);
583
585
586 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
587 SocketIPAddress ipAddress;
588
589 private:
590 friend struct AsyncEventLoop;
591 SC::Result validate(AsyncEventLoop&);
592
593#if SC_PLATFORM_WINDOWS
594 void (*pConnectEx)() = nullptr;
596#endif
597};
598
607struct SC_ASYNC_EXPORT AsyncSocketSend : public AsyncRequest
608{
609 AsyncSocketSend() : AsyncRequest(Type::SocketSend) {}
611 {
612 size_t numBytes = 0;
613 };
615 using AsyncRequest::start;
616
619
622
624
625 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
626
627 SC::Result closeHandle() { return detail::SocketDescriptorDefinition::releaseHandle(handle); }
628
631 bool singleBuffer = true;
632
633 protected:
634 AsyncSocketSend(Type type) : AsyncRequest(type) {}
635 friend struct AsyncEventLoop;
636 SC::Result validate(AsyncEventLoop&);
637
638 size_t totalBytesWritten = 0;
639#if SC_PLATFORM_WINDOWS
641#endif
642};
643
653struct SC_ASYNC_EXPORT AsyncSocketSendTo : public AsyncSocketSend
654{
655 AsyncSocketSendTo() : AsyncSocketSend(Type::SocketSendTo) {}
656
657 SocketIPAddress address;
658
659 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, SocketIPAddress ipAddress,
660 Span<const char> data);
661
662 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, SocketIPAddress ipAddress,
663 Span<Span<const char>> data);
664
665 private:
666 using AsyncSocketSend::start;
667 friend struct AsyncEventLoop;
668 SC::Result validate(AsyncEventLoop&);
669#if SC_PLATFORM_LINUX
670 AlignedStorage<56> typeErasedMsgHdr;
671#endif
672};
673
685struct SC_ASYNC_EXPORT AsyncSocketReceive : public AsyncRequest
686{
687 AsyncSocketReceive() : AsyncRequest(Type::SocketReceive) {}
688
690 {
691 size_t numBytes = 0;
692 bool disconnected = false;
693 };
694
695 struct Result : public AsyncResultOf<AsyncSocketReceive, CompletionData>
696 {
697 using AsyncResultOf<AsyncSocketReceive, CompletionData>::AsyncResultOf;
698
699 bool isEnded() const { return completionData.disconnected; }
700
705 {
706 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, outData));
707 return returnCode;
708 }
709
710 SocketIPAddress getSourceAddress() const;
711 };
712 using AsyncRequest::start;
713
715 SC::Result start(AsyncEventLoop& eventLoop, const SocketDescriptor& descriptor, Span<char> data);
716
718
720 SocketDescriptor::Handle handle = SocketDescriptor::Invalid;
721
722 SC::Result closeHandle() { return detail::SocketDescriptorDefinition::releaseHandle(handle); }
723
724 protected:
725 AsyncSocketReceive(Type type) : AsyncRequest(type) {}
726 friend struct AsyncEventLoop;
727 SC::Result validate(AsyncEventLoop&);
728#if SC_PLATFORM_WINDOWS
729 detail::WinOverlappedOpaque overlapped;
730#endif
731};
732
742struct SC_ASYNC_EXPORT AsyncSocketReceiveFrom : public AsyncSocketReceive
743{
744 AsyncSocketReceiveFrom() : AsyncSocketReceive(Type::SocketReceiveFrom) {}
745 using AsyncSocketReceive::start;
746
747 private:
748 SocketIPAddress address;
749 friend struct AsyncSocketReceive;
750 friend struct AsyncEventLoop;
751#if SC_PLATFORM_LINUX
752 AlignedStorage<56> typeErasedMsgHdr;
753#endif
754};
755
777struct SC_ASYNC_EXPORT AsyncFileRead : public AsyncRequest
778{
779 AsyncFileRead() : AsyncRequest(Type::FileRead) { handle = FileDescriptor::Invalid; }
780
782 {
783 size_t numBytes = 0;
784 bool endOfFile = false;
785 };
786
787 struct Result : public AsyncResultOf<AsyncFileRead, CompletionData>
788 {
789 using AsyncResultOf<AsyncFileRead, CompletionData>::AsyncResultOf;
790
791 bool isEnded() const { return completionData.endOfFile; }
792
793 SC::Result get(Span<char>& data)
794 {
795 SC_TRY(getAsync().buffer.sliceStartLength(0, completionData.numBytes, data));
796 return returnCode;
797 }
798 };
799 using AsyncRequest::start;
800
802 SC::Result start(AsyncEventLoop& eventLoop, const FileDescriptor& descriptor, Span<char> data);
803
804 Function<void(Result&)> callback;
806 FileDescriptor::Handle handle;
808
809 SC::Result closeHandle() { return detail::FileDescriptorDefinition::releaseHandle(handle); }
810
812 uint64_t getOffset() const { return offset; }
813
816 void setOffset(uint64_t fileOffset)
817 {
818 useOffset = true;
819 offset = fileOffset;
820 }
821
822 private:
823 friend struct AsyncEventLoop;
824 SC::Result validate(AsyncEventLoop&);
825
826 bool useOffset = false;
827 bool endedSync = false;
828
829 uint64_t offset = 0;
830#if SC_PLATFORM_WINDOWS
831 uint64_t readCursor = 0;
833#endif
834};
835
853struct SC_ASYNC_EXPORT AsyncFileWrite : public AsyncRequest
854{
855 AsyncFileWrite() : AsyncRequest(Type::FileWrite) { handle = FileDescriptor::Invalid; }
856
858 {
859 size_t numBytes = 0;
860 };
861
862 struct Result : public AsyncResultOf<AsyncFileWrite, CompletionData>
863 {
864 using AsyncResultOf<AsyncFileWrite, CompletionData>::AsyncResultOf;
865
866 SC::Result get(size_t& writtenSizeInBytes)
867 {
868 writtenSizeInBytes = completionData.numBytes;
869 return returnCode;
870 }
871 };
872
873 using AsyncRequest::start;
874
876 SC::Result start(AsyncEventLoop& eventLoop, const FileDescriptor& descriptor, Span<Span<const char>> data);
877
880
882 SC::Result start(AsyncEventLoop& eventLoop, const FileDescriptor& descriptor, Span<const char> data);
883
886
888
889 FileDescriptor::Handle handle;
891
892 SC::Result closeHandle() { return detail::FileDescriptorDefinition::releaseHandle(handle); }
893
896 bool singleBuffer = true;
897
899 uint64_t getOffset() const { return offset; }
900
903 void setOffset(uint64_t fileOffset)
904 {
905 useOffset = true;
906 offset = fileOffset;
907 }
908
909 private:
910 friend struct AsyncEventLoop;
911 SC::Result validate(AsyncEventLoop&);
912
913#if SC_PLATFORM_WINDOWS
914 bool endedSync = false;
915#else
916 bool isWatchable = false;
917#endif
918 bool useOffset = false;
919 uint64_t offset = 0xffffffffffffffff;
920
921 size_t totalBytesWritten = 0;
922#if SC_PLATFORM_WINDOWS
924#endif
925};
926
931struct SC_ASYNC_EXPORT AsyncFilePoll : public AsyncRequest
932{
933 AsyncFilePoll() : AsyncRequest(Type::FilePoll) {}
934
937
939 SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle fileDescriptor);
940
941#if SC_PLATFORM_WINDOWS
942 [[nodiscard]] void* getOverlappedPtr();
943#endif
944
945 Function<void(Result&)> callback;
946
947 private:
948 friend struct AsyncEventLoop;
949 SC::Result validate(AsyncEventLoop&);
950
951 FileDescriptor::Handle handle = FileDescriptor::Invalid;
952#if SC_PLATFORM_WINDOWS
954#endif
955};
956
981struct SC_ASYNC_EXPORT AsyncFileSend : public AsyncRequest
982{
983 AsyncFileSend() : AsyncRequest(Type::FileSend) {}
984
986 {
987 size_t bytesTransferred = 0;
988 bool usedZeroCopy = false;
989 };
990
991 struct Result : public AsyncResultOf<AsyncFileSend, CompletionData>
992 {
993 using AsyncResultOf<AsyncFileSend, CompletionData>::AsyncResultOf;
994
996 [[nodiscard]] size_t getBytesTransferred() const { return completionData.bytesTransferred; }
997
999 [[nodiscard]] bool usedZeroCopy() const { return completionData.usedZeroCopy; }
1000
1002 [[nodiscard]] bool isComplete() const
1003 {
1004 return returnCode && completionData.bytesTransferred == getAsync().length;
1005 }
1006 };
1007
1008 using AsyncRequest::start;
1009
1019 SC::Result start(AsyncEventLoop& eventLoop, const FileDescriptor& file, const SocketDescriptor& socket,
1020 int64_t offset = 0, size_t length = 0, size_t pipeSize = 0);
1021
1023
1024 // Internal handles (set by start())
1025 FileDescriptor::Handle fileHandle = FileDescriptor::Invalid;
1026 SocketDescriptor::Handle socketHandle = SocketDescriptor::Invalid;
1027
1028 int64_t offset = 0;
1029 size_t length = 0;
1030 size_t bytesSent = 0;
1031 private:
1032 friend struct AsyncEventLoop;
1033 SC::Result validate(AsyncEventLoop&);
1034
1035#if SC_PLATFORM_WINDOWS
1036 detail::WinOverlappedOpaque overlapped;
1037#elif SC_PLATFORM_LINUX
1038 size_t pipeBufferSize = 0;
1039 PipeDescriptor splicePipe;
1040#endif
1041};
1042
1043// forward declared because it must be defined after AsyncTaskSequence
1044struct AsyncLoopWork;
1046
1048{
1049 FileDescriptor::Handle handle = FileDescriptor::Invalid; // for open
1050
1051 int code = 0; // for open/close
1052 size_t numBytes = 0; // for read
1053};
1054
1055namespace detail
1056{
1057// A simple hand-made variant of all completion types
1058struct SC_ASYNC_EXPORT AsyncCompletionVariant
1059{
1060 AsyncCompletionVariant() {}
1061 ~AsyncCompletionVariant() { destroy(); }
1062
1063 AsyncCompletionVariant(const AsyncCompletionVariant&) = delete;
1064 AsyncCompletionVariant(AsyncCompletionVariant&&) = delete;
1065 AsyncCompletionVariant& operator=(const AsyncCompletionVariant&) = delete;
1066 AsyncCompletionVariant& operator=(AsyncCompletionVariant&&) = delete;
1067
1068 bool inited = false;
1069
1070 AsyncRequest::Type type;
1071 union
1072 {
1073 AsyncCompletionData completionDataLoopWork; // Defined after AsyncCompletionVariant / AsyncTaskSequence
1074 AsyncLoopTimeout::CompletionData completionDataLoopTimeout;
1075 AsyncLoopWakeUp::CompletionData completionDataLoopWakeUp;
1076 AsyncProcessExit::CompletionData completionDataProcessExit;
1077 AsyncSignal::CompletionData completionDataSignal;
1078 AsyncSocketAccept::CompletionData completionDataSocketAccept;
1079 AsyncSocketConnect::CompletionData completionDataSocketConnect;
1080 AsyncSocketSend::CompletionData completionDataSocketSend;
1081 AsyncSocketSendTo::CompletionData completionDataSocketSendTo;
1082 AsyncSocketReceive::CompletionData completionDataSocketReceive;
1083 AsyncSocketReceiveFrom::CompletionData completionDataSocketReceiveFrom;
1084 AsyncFileRead::CompletionData completionDataFileRead;
1085 AsyncFileWrite::CompletionData completionDataFileWrite;
1086 AsyncFileSend::CompletionData completionDataFileSend;
1087 AsyncFilePoll::CompletionData completionDataFilePoll;
1088
1089 AsyncFileSystemOperationCompletionData completionDataFileSystemOperation;
1090 };
1091
1092 auto& getCompletion(AsyncLoopWork&) { return completionDataLoopWork; }
1093 auto& getCompletion(AsyncLoopTimeout&) { return completionDataLoopTimeout; }
1094 auto& getCompletion(AsyncLoopWakeUp&) { return completionDataLoopWakeUp; }
1095 auto& getCompletion(AsyncProcessExit&) { return completionDataProcessExit; }
1096 auto& getCompletion(AsyncSignal&) { return completionDataSignal; }
1097 auto& getCompletion(AsyncSocketAccept&) { return completionDataSocketAccept; }
1098 auto& getCompletion(AsyncSocketConnect&) { return completionDataSocketConnect; }
1099 auto& getCompletion(AsyncSocketSend&) { return completionDataSocketSend; }
1100 auto& getCompletion(AsyncSocketReceive&) { return completionDataSocketReceive; }
1101 auto& getCompletion(AsyncFileRead&) { return completionDataFileRead; }
1102 auto& getCompletion(AsyncFileWrite&) { return completionDataFileWrite; }
1103 auto& getCompletion(AsyncFileSend&) { return completionDataFileSend; }
1104 auto& getCompletion(AsyncFilePoll&) { return completionDataFilePoll; }
1105 auto& getCompletion(AsyncFileSystemOperation&) { return completionDataFileSystemOperation; }
1106
1107 template <typename T>
1108 auto& construct(T& t)
1109 {
1110 destroy();
1111 placementNew(getCompletion(t));
1112 inited = true;
1113 type = t.getType();
1114 return getCompletion(t);
1115 }
1116 void destroy();
1117};
1118} // namespace detail
1119
1123struct SC_ASYNC_EXPORT AsyncTaskSequence : public AsyncSequence
1124{
1125 protected:
1126 ThreadPoolTask task;
1127 ThreadPool* threadPool = nullptr;
1128
1129 friend struct AsyncEventLoop;
1130 friend struct AsyncRequest;
1131
1132 detail::AsyncCompletionVariant completion;
1133
1134 SC::Result returnCode = SC::Result(true);
1135};
1136
1142struct SC_ASYNC_EXPORT AsyncLoopWork : public AsyncRequest
1143{
1144 AsyncLoopWork() : AsyncRequest(Type::LoopWork) {}
1145
1148
1152
1153 Function<SC::Result()> work;
1155
1156 private:
1157 friend struct AsyncEventLoop;
1158 SC::Result validate(AsyncEventLoop&);
1159 AsyncTaskSequence task;
1160};
1161
1195struct SC_ASYNC_EXPORT AsyncFileSystemOperation : public AsyncRequest
1196{
1197 AsyncFileSystemOperation() : AsyncRequest(Type::FileSystemOperation) {}
1198 ~AsyncFileSystemOperation() { destroy(); }
1199#ifdef CopyFile
1200#undef CopyFile
1201#endif
1202#ifdef RemoveDirectory
1203#undef RemoveDirectory
1204#endif
1205 enum class Operation
1206 {
1207 None = 0,
1208 Open,
1209 Close,
1210 Read,
1211 Write,
1212 CopyFile,
1213 CopyDirectory,
1214 Rename,
1215 RemoveDirectory,
1216 RemoveFile,
1217 };
1218
1221
1224
1226 SC::Result stop(AsyncEventLoop& eventLoop, Function<void(AsyncResult&)>* afterStopped = nullptr);
1227
1229
1236
1241 SC::Result close(AsyncEventLoop& eventLoop, FileDescriptor::Handle handle);
1242
1249 SC::Result read(AsyncEventLoop& eventLoop, FileDescriptor::Handle handle, Span<char> buffer, uint64_t offset);
1250
1257 SC::Result write(AsyncEventLoop& eventLoop, FileDescriptor::Handle handle, Span<const char> buffer,
1258 uint64_t offset);
1259
1266 SC::Result copyFile(AsyncEventLoop& eventLoop, StringSpan path, StringSpan destinationPath,
1268
1277
1284
1291
1297
1298 private:
1299 friend struct AsyncEventLoop;
1300 Operation operation = Operation::None;
1301 AsyncLoopWork loopWork;
1302 CompletionData completionData;
1303
1304 void onOperationCompleted(AsyncLoopWork::Result& res);
1305
1306 struct FileDescriptorData
1307 {
1308 FileDescriptor::Handle handle;
1309 };
1310
1311 struct OpenData
1312 {
1313 StringSpan path;
1314 FileOpen mode;
1315 };
1316
1317 struct ReadData
1318 {
1319 FileDescriptor::Handle handle;
1320 Span<char> buffer;
1321 uint64_t offset;
1322 };
1323
1324 struct WriteData
1325 {
1326 FileDescriptor::Handle handle;
1327 Span<const char> buffer;
1328 uint64_t offset;
1329 };
1330
1331 struct CopyFileData
1332 {
1333 StringSpan path;
1334 StringSpan destinationPath;
1335 FileSystemCopyFlags copyFlags;
1336 };
1337
1338 using CopyDirectoryData = CopyFileData;
1339
1340 using CloseData = FileDescriptorData;
1341
1342 struct RenameData
1343 {
1344 StringSpan path;
1345 StringSpan newPath;
1346 };
1347
1348 struct RemoveData
1349 {
1350 StringSpan path;
1351 };
1352
1353 union
1354 {
1355 OpenData openData;
1356 CloseData closeData;
1357 ReadData readData;
1358 WriteData writeData;
1359 CopyFileData copyFileData;
1360 CopyDirectoryData copyDirectoryData;
1361 RenameData renameData;
1362 RemoveData removeData;
1363 };
1364
1365 void destroy();
1366
1367 SC::Result start(AsyncEventLoop& eventLoop, FileDescriptor::Handle fileDescriptor);
1368 SC::Result validate(AsyncEventLoop&);
1369};
1370
1374struct SC_ASYNC_EXPORT AsyncKernelEvents
1375{
1377
1378 private:
1379 int numberOfEvents = 0;
1380 friend struct AsyncEventLoop;
1381};
1382
1384struct SC_ASYNC_EXPORT AsyncEventLoopListeners
1385{
1386 Function<void(AsyncEventLoop&)> beforeBlockingPoll;
1387 Function<void(AsyncEventLoop&)> afterBlockingPoll;
1388};
1389
1396struct SC_ASYNC_EXPORT AsyncEventLoop
1397{
1399 struct Options
1400 {
1401 enum class ApiType : uint8_t
1402 {
1403 Automatic = 0,
1404 ForceUseIoUring,
1405 ForceUseEpoll,
1406 };
1408
1409 Options() { apiType = ApiType::Automatic; }
1410 };
1411
1413
1414 AsyncEventLoop(const AsyncEventLoop&) = delete;
1415 AsyncEventLoop(AsyncEventLoop&&) = delete;
1416 AsyncEventLoop& operator=(AsyncEventLoop&&) = delete;
1417 AsyncEventLoop& operator=(const AsyncEventLoop&) = delete;
1418
1421
1424
1428
1431
1433 [[nodiscard]] bool isInitialized() const;
1434
1436 [[nodiscard]] bool needsThreadPoolForFileOperations() const;
1437
1444
1455
1462
1468
1488
1495
1499
1502
1505
1508
1511
1513 Result associateExternallyCreatedSocketHandle(SocketDescriptor::Handle handle);
1514
1517
1520
1523
1525 static Result removeAllAssociationsForSocketHandle(SocketDescriptor::Handle handle);
1526
1529
1531 static Result removeAllAssociationsForFileDescriptorHandle(FileDescriptor::Handle handle);
1532
1535
1537 [[nodiscard]] TimeMs getLoopTime() const;
1538
1540 [[nodiscard]] int getNumberOfActiveRequests() const;
1541
1543 [[nodiscard]] int getNumberOfSubmittedRequests() const;
1544
1548
1551
1554
1556 void enumerateRequests(Function<void(AsyncRequest&)> enumerationCallback);
1557
1561
1563 [[nodiscard]] static bool isExcludedFromActiveCount(const AsyncRequest& async);
1564
1567 [[nodiscard]] static bool tryProbingIOUring();
1568
1571
1572 struct Internal;
1573
1575 using LoopWork = AsyncLoopWork;
1578 using Signal = AsyncSignal;
1585 using FileRead = AsyncFileRead;
1586 using FileWrite = AsyncFileWrite;
1587 using FileSend = AsyncFileSend;
1588 using FilePoll = AsyncFilePoll;
1591 using ResultType = AsyncResult;
1592
1593 public:
1594 struct SC_ASYNC_EXPORT InternalDefinition
1595 {
1596 static constexpr int Windows = 552;
1597 static constexpr int Apple = 520;
1598 static constexpr int Linux = 784;
1599 static constexpr int Default = Linux;
1600
1601 static constexpr size_t Alignment = 8;
1602
1603 using Object = Internal;
1604 };
1605
1607
1608 private:
1609 InternalOpaque internalOpaque;
1610 Internal& internal;
1611
1612 friend struct AsyncRequest;
1613 friend struct AsyncFileWrite;
1614 friend struct AsyncFileRead;
1615 friend struct AsyncFileSystemOperation;
1616 friend struct AsyncResult;
1617};
1618
1622struct SC_ASYNC_EXPORT AsyncEventLoopMonitor
1623{
1625
1629
1632
1640
1646
1647 private:
1648#if SC_COMPILER_MSVC
1649#pragma warning(push)
1650#pragma warning(disable : 4324) // useless warning on 32 bit... (structure was padded due to __declspec(align()))
1651#endif
1652 alignas(uint64_t) uint8_t eventsMemory[8 * 1024]; // 8 Kb of kernel events
1653#if SC_COMPILER_MSVC
1654#pragma warning(pop)
1655#endif
1656
1657 AsyncKernelEvents asyncKernelEvents;
1658 AsyncEventLoop* eventLoop = nullptr;
1659 AsyncLoopWakeUp eventLoopWakeUp;
1660
1661 Thread eventLoopThread;
1662 EventObject eventObjectEnterBlockingMode;
1663 EventObject eventObjectExitBlockingMode;
1664
1665 Atomic<bool> finished = false;
1666 Atomic<bool> needsWakeUp = true;
1667
1668 bool wakeUpHasBeenCalled = false;
1669
1670 Result monitoringLoopThread(Thread& thread);
1671};
1672
1673} // namespace SC
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition PrimitiveTypes.h:28
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition Compiler.h:297
struct SC_FOUNDATION_EXPORT Function
Wraps function pointers, member functions and lambdas without ever allocating.
Definition Function.h:19
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:27
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:33
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:29
short int16_t
Platform independent (2) bytes signed int.
Definition PrimitiveTypes.h:36
long long int64_t
Platform independent (8) bytes signed int.
Definition PrimitiveTypes.h:41
int int32_t
Platform independent (4) bytes signed int.
Definition PrimitiveTypes.h:37
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition Result.h:49
A buffer of bytes with given alignment.
Definition AlignedStorage.h:29
Empty base struct for all AsyncRequest-derived CompletionData (internal) structs.
Definition Async.h:259
Allow library user to provide callbacks signaling different phases of async event loop cycle.
Definition Async.h:1385
Monitors Async I/O events from a background thread using a blocking kernel function (no CPU usage on ...
Definition Async.h:1623
Function< void(void)> onNewEventsAvailable
Informs to call dispatchCompletions on GUI Event Loop.
Definition Async.h:1624
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.
Result create(AsyncEventLoop &eventLoop)
Create the monitoring thread for an AsyncEventLoop.
Options given to AsyncEventLoop::create.
Definition Async.h:1400
ApiType apiType
Criteria to choose Async IO API.
Definition Async.h:1407
ApiType
Definition Async.h:1402
Asynchronous I/O (files, sockets, timers, processes, fs events, threads wake-up) (see Async) AsyncEve...
Definition Async.h:1397
bool needsThreadPoolForFileOperations() const
Returns true if backend needs a thread pool for non-blocking fs operations (anything but io_uring bas...
Result associateExternallyCreatedFileDescriptor(FileDescriptor &outDescriptor)
Associates a previously created File Descriptor 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...
static Result removeAllAssociationsFor(SocketDescriptor &outDescriptor)
Removes association of a TCP Socket with any event loop.
void updateTime()
Updates loop time to "now".
static bool tryProbingIOUring()
Check if io_uring can be created directly (only on Linux)
static bool isExcludedFromActiveCount(const AsyncRequest &async)
Checks if excludeFromActiveCount() has been called on the given request.
Result associateExternallyCreatedSocket(SocketDescriptor &outDescriptor)
Associates a previously created TCP / UDP socket with the eventLoop.
Result associateExternallyCreatedFileDescriptorHandle(FileDescriptor::Handle handle)
Associates a previously created File Descriptor handle with the eventLoop.
Result blockingPoll(AsyncKernelEvents &kernelEvents)
Blocks until at least one event happens, ensuring forward progress, without executing completions.
void clearSequence(AsyncSequence &sequence)
Clears the sequence.
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.
TimeMs getLoopTime() const
Get Loop time (monotonic)
Result associateExternallyCreatedSocketHandle(SocketDescriptor::Handle handle)
Associates a previously created TCP / UDP socket handle with the eventLoop.
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)
static Result removeAllAssociationsForSocketHandle(SocketDescriptor::Handle handle)
Removes association of a TCP Socket handle with any event loop.
Result create(Options options=Options())
Creates the event loop kernel object.
Result createAsyncTCPSocket(SocketFlags::AddressFamily family, SocketDescriptor &outDescriptor)
Creates an async TCP (IPV4 / IPV6) socket registered with the eventLoop.
Result close()
Closes the event loop kernel object.
static Result removeAllAssociationsForFileDescriptorHandle(FileDescriptor::Handle handle)
Removes association of a File Descriptor handle with any event loop.
Result createAsyncUDPSocket(SocketFlags::AddressFamily family, SocketDescriptor &outDescriptor)
Creates an async UCP (IPV4 / IPV6) socket registered with the eventLoop.
static Result removeAllAssociationsFor(FileDescriptor &outDescriptor)
Removes association of a File Descriptor with any event loop.
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 an handle polling operation.
Definition Async.h:932
SC::Result start(AsyncEventLoop &eventLoop, FileDescriptor::Handle fileDescriptor)
Starts a file descriptor poll operation, monitoring its readiness with appropriate OS API.
Definition Async.h:782
Definition Async.h:788
Starts a file read operation, reading bytes from a file (or pipe).
Definition Async.h:778
FileDescriptor::Handle handle
The writeable span of memory where to data will be written.
Definition Async.h:806
Span< char > buffer
Callback called when some data has been read from the file into the buffer.
Definition Async.h:805
SC::Result closeHandle()
The file/pipe descriptor handle to read data from.
Definition Async.h:809
void setOffset(uint64_t fileOffset)
Sets the offset in bytes at which start reading.
Definition Async.h:816
SC::Result start(AsyncEventLoop &eventLoop, const FileDescriptor &descriptor, Span< char > data)
Sets async request members and calls AsyncEventLoop::start.
uint64_t getOffset() const
Returns the last offset set with AsyncFileRead::setOffset.
Definition Async.h:812
Definition Async.h:986
Definition Async.h:992
size_t getBytesTransferred() const
Get the number of bytes transferred.
Definition Async.h:996
bool usedZeroCopy() const
Check if zero-copy was used for this transfer.
Definition Async.h:999
bool isComplete() const
Check if the entire requested range was sent.
Definition Async.h:1002
Sends file contents to a socket using zero-copy when available (sendfile, TransmitFile).
Definition Async.h:982
Function< void(Result &)> callback
Called when send completes or fails.
Definition Async.h:1022
SC::Result start(AsyncEventLoop &eventLoop, const FileDescriptor &file, const SocketDescriptor &socket, int64_t offset=0, size_t length=0, size_t pipeSize=0)
Start the file send operation.
Starts an asynchronous file system operation (open, close, read, write, sendFile, stat,...
Definition Async.h:1196
SC::Result stop(AsyncEventLoop &eventLoop, Function< void(AsyncResult &)> *afterStopped=nullptr)
Stops the operation, including the internal thread-pool work item when used.
SC::Result copyDirectory(AsyncEventLoop &eventLoop, StringSpan path, StringSpan destinationPath, FileSystemCopyFlags copyFlags=FileSystemCopyFlags())
Copies a directory from one location to another.
SC::Result removeEmptyDirectory(AsyncEventLoop &eventLoop, StringSpan path)
Removes a directory asynchronously.
SC::Result rename(AsyncEventLoop &eventLoop, StringSpan path, StringSpan newPath)
Renames a file.
SC::Result removeFile(AsyncEventLoop &eventLoop, StringSpan path)
Removes a file asynchronously.
SC::Result setThreadPool(ThreadPool &threadPool)
Sets the thread pool to use for the operation.
SC::Result read(AsyncEventLoop &eventLoop, FileDescriptor::Handle handle, Span< char > buffer, uint64_t offset)
Reads data from a file descriptor at a given offset.
SC::Result write(AsyncEventLoop &eventLoop, FileDescriptor::Handle handle, Span< const char > buffer, uint64_t offset)
Writes data to a file descriptor at a given offset.
SC::Result close(AsyncEventLoop &eventLoop, FileDescriptor::Handle handle)
Closes a file descriptor asynchronously.
Function< void(Result &)> callback
Called after the operation is completed, on the event loop thread.
Definition Async.h:1228
SC::Result copyFile(AsyncEventLoop &eventLoop, StringSpan path, StringSpan destinationPath, FileSystemCopyFlags copyFlags=FileSystemCopyFlags())
Copies a file from one location to another.
SC::Result open(AsyncEventLoop &eventLoop, StringSpan path, FileOpen mode)
Opens a file asynchronously and returns its corresponding file descriptor.
Definition Async.h:863
Starts a file write operation, writing bytes to a file (or pipe).
Definition Async.h:854
uint64_t getOffset() const
Returns the last offset set with AsyncFileWrite::setOffset.
Definition Async.h:899
FileDescriptor::Handle handle
The file/pipe descriptor to write data to.
Definition Async.h:889
SC::Result start(AsyncEventLoop &eventLoop, Span< const char > data)
Sets async request members and calls AsyncEventLoop::start.
SC::Result start(AsyncEventLoop &eventLoop, const FileDescriptor &descriptor, Span< 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:903
Function< void(Result &)> callback
Callback called when descriptor is ready to be written with more data.
Definition Async.h:887
SC::Result start(AsyncEventLoop &eventLoop, const FileDescriptor &descriptor, Span< const char > data)
Sets async request members and calls AsyncEventLoop::start.
Span< Span< const char > > buffers
The read-only spans of memory where to read the data from.
Definition Async.h:895
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:894
Allows user to supply a block of memory that will store kernel I/O events retrieved from AsyncEventLo...
Definition Async.h:1375
Span< uint8_t > eventsMemory
User supplied block of memory used to store kernel I/O events.
Definition Async.h:1376
Starts a Timeout that is invoked only once after expiration (relative) time has passed.
Definition Async.h:310
TimeMs getExpirationTime() const
Gets computed absolute expiration time that determines when this timeout get executed.
Definition Async.h:325
SC::Result start(AsyncEventLoop &eventLoop, TimeMs relativeTimeout)
Sets async request members and calls AsyncEventLoop::start.
TimeMs relativeTimeout
First timer expiration (relative) time in milliseconds.
Definition Async.h:322
Function< void(Result &)> callback
Called after given expiration time since AsyncLoopTimeout::start has passed.
Definition Async.h:320
Options for AsyncLoopWakeUp configuration.
Definition Async.h:335
bool coalesce
Merge repeated pending wakeUp() calls into a single callback (default true, matching libuv uv_async_t...
Definition Async.h:338
Starts a wake-up operation, allowing threads to execute callbacks on loop thread.
Definition Async.h:358
SC::Result start(AsyncEventLoop &eventLoop, EventObject &eventObject, AsyncLoopWakeUpOptions options={})
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:377
SC::Result wakeUp(AsyncEventLoop &eventLoop)
Wakes up event loop, scheduling AsyncLoopWakeUp::callback on next AsyncEventLoop::run (or its variati...
SC::Result start(AsyncEventLoop &eventLoop, AsyncLoopWakeUpOptions options={})
Sets async request members and calls AsyncEventLoop::start.
Executes work in a thread pool and then invokes a callback on the event loop thread.
Definition Async.h:1143
Function< void(Result &)> callback
Called to execute the work in a background threadpool thread.
Definition Async.h:1154
SC::Result setThreadPool(ThreadPool &threadPool)
Sets the ThreadPool that will supply the thread to run the async work on.
Definition Async.h:404
Starts monitoring a process, notifying about its termination.
Definition Async.h:395
SC::Result start(AsyncEventLoop &eventLoop, FileDescriptor::Handle process)
Sets async request members and calls AsyncEventLoop::start.
Function< void(Result &)> callback
Called when process has exited.
Definition Async.h:420
Base class for all async requests, holding state and type.
Definition Async.h:123
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:163
Result start(AsyncEventLoop &eventLoop)
Shortcut for AsyncEventLoop::start.
uint16_t getUserFlags() const
Gets user flags, holding some meaningful data for the caller.
Definition Async.h:192
Function< void(AsyncResult &)> * getCloseCallback()
Returns currently set close callback (if any) passed to AsyncRequest::stop.
Definition Async.h:195
bool isActive() const
Returns true if this request is active or being reactivated.
bool isFree() const
Returns true if this request is free.
void disableThreadPool()
Disables the thread-pool usage for this request.
Type getType() const
Returns request type.
Definition Async.h:183
void setUserFlags(uint16_t externalFlags)
Sets user flags, holding some meaningful data for the caller.
Definition Async.h:189
Result executeOn(AsyncTaskSequence &task, ThreadPool &pool)
Adds the request to be executed on a specific AsyncTaskSequence.
Result stop(AsyncEventLoop &eventLoop, Function< void(AsyncResult &)> *afterStopped=nullptr)
Ask to stop current async operation.
void executeOn(AsyncSequence &sequence)
Adds the request to be executed on a specific AsyncSequence.
Type
Type of async request.
Definition Async.h:142
Helper holding CompletionData for a specific AsyncRequest-derived class.
Definition Async.h:295
Base class for all async results (argument of completion callbacks).
Definition Async.h:265
const SC::Result & isValid() const
Check if the returnCode of this result is valid.
Definition Async.h:276
AsyncResult(AsyncEventLoop &eventLoop, AsyncRequest &request, SC::Result &res, bool *hasBeenReactivated=nullptr)
Constructs an async result from a request and a result.
Definition Async.h:267
void reactivateRequest(bool shouldBeReactivated)
Ask the event loop to re-activate this request after it was already completed.
Execute AsyncRequests serially, by submitting the next one after the previous one is completed.
Definition Async.h:243
Options for AsyncSignal request configuration.
Definition Async.h:438
Mode
Mode of signal watching.
Definition Async.h:441
@ Persistent
Callback runs on every delivery until stopped (default)
@ OneShot
Request auto-stops after first successful callback dispatch.
Mode mode
Default mode is Persistent.
Definition Async.h:445
bool coalesce
Merge repeated pending deliveries (default true)
Definition Async.h:446
Definition Async.h:461
Definition Async.h:467
Starts monitoring a signal, notifying about its reception.
Definition Async.h:457
Function< void(Result &)> callback
Called when the signal is raised.
Definition Async.h:475
SC::Result start(AsyncEventLoop &eventLoop, int num, AsyncSignalOptions options={})
Sets async request members and calls AsyncEventLoop::start.
Starts a socket accept operation, obtaining a new socket from a listening socket.
Definition Async.h:554
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &socketDescriptor)
Sets async request members and calls AsyncEventLoop::start.
Starts a socket connect operation, connecting to a remote endpoint.
Definition Async.h:574
Function< void(Result &)> callback
Called after socket is finally connected to endpoint.
Definition Async.h:584
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, SocketIPAddress address)
Sets async request members and calls AsyncEventLoop::start.
Starts an unconnected socket receive from operation, receiving bytes from a remote endpoint.
Definition Async.h:743
Definition Async.h:696
SC::Result get(Span< char > &outData)
Get a Span of the actually read data.
Definition Async.h:704
Starts a socket receive operation, receiving bytes from a remote endpoint.
Definition Async.h:686
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< char > data)
Sets async request members and calls AsyncEventLoop::start.
SC::Result closeHandle()
The Socket Descriptor handle to read data from.
Definition Async.h:722
Span< char > buffer
The writeable span of memory where to data will be written.
Definition Async.h:719
Function< void(Result &)> callback
Called after data has been received.
Definition Async.h:717
Starts an unconnected socket send to operation, sending bytes to a remote endpoint.
Definition Async.h:654
Starts a socket send operation, sending bytes to a remote endpoint.
Definition Async.h:608
Function< void(Result &)> callback
Called when socket is ready to send more data.
Definition Async.h:623
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:630
Span< const char > buffer
Span of bytes to send (singleBuffer == true)
Definition Async.h:629
SC::Result start(AsyncEventLoop &eventLoop, const SocketDescriptor &descriptor, Span< Span< const char > > data)
Sets async request members and calls AsyncEventLoop::start.
An AsyncSequence using a SC::ThreadPool to execute one or more SC::AsyncRequest in a background threa...
Definition Async.h:1124
Atomic variables (only for int and bool for now).
Definition Atomic.h:42
An automatically reset event object to synchronize two threads.
Definition Threading.h:235
[UniqueHandleDeclaration2Snippet]
Definition File.h:128
Options used to open a file descriptor.
Definition File.h:99
A structure to describe copy flags.
Definition FileSystem.h:76
Hides implementation details from public headers (static PIMPL).
Definition OpaqueObject.h:31
Read / Write pipe (Process stdin/stdout and IPC communication)
Definition File.h:300
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:13
Low-level OS socket handle.
Definition Socket.h:159
AddressFamily
Sets the address family of an IP Address (IPv4 or IPV6)
Definition Socket.h:66
Native representation of an IP Address.
Definition Socket.h:106
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37
A small task containing a function to execute that can be queued in the thread pool.
Definition ThreadPool.h:16
Simple thread pool that executes tasks in a fixed number of worker threads.
Definition ThreadPool.h:38
A native OS thread.
Definition Threading.h:119
A vocabulary type representing a time interval in milliseconds since epoch.
Definition PrimitiveTypes.h:50