1010#include " ../Socket/Socket.h"
1111#include " ../Threading/Atomic.h"
1212#include " ../Threading/ThreadPool.h"
13-
13+ #if SC_COMPILER_MSVC
14+ #pragma warning(push)
15+ #pragma warning(disable : 4251)
16+ #endif
1417namespace SC
1518{
1619struct ThreadPool ;
@@ -70,7 +73,7 @@ struct AsyncWinWaitDefinition
7073
7174 static Result releaseHandle (Handle& waitHandle);
7275};
73- struct WinWaitHandle : public UniqueHandle <AsyncWinWaitDefinition>
76+ struct SC_COMPILER_EXPORT WinWaitHandle : public UniqueHandle<AsyncWinWaitDefinition>
7477{
7578};
7679} // namespace detail
@@ -113,7 +116,7 @@ struct WinWaitHandle : public UniqueHandle<AsyncWinWaitDefinition>
113116// / 3. Async in Active state (so after setupAsync and activateAsync) --> will receive cancelAsync and teardownAsync
114117// /
115118// / Any other case is considered an error (trying to cancel an async already being cancelled or being teardown).
116- struct AsyncRequest
119+ struct SC_COMPILER_EXPORT AsyncRequest
117120{
118121 AsyncRequest* next = nullptr ;
119122 AsyncRequest* prev = nullptr ;
@@ -231,7 +234,7 @@ struct AsyncRequest
231234// / Requests are being queued on a sequence using AsyncRequest::executeOn.
232235// / AsyncTaskSequence can be used to force running asyncs on a thread (useful for buffered files)
233236// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncFileWriteSnippet
234- struct AsyncSequence
237+ struct SC_COMPILER_EXPORT AsyncSequence
235238{
236239 AsyncSequence* next = nullptr ;
237240 AsyncSequence* prev = nullptr ;
@@ -247,13 +250,11 @@ struct AsyncSequence
247250};
248251
249252// / @brief Empty base struct for all AsyncRequest-derived CompletionData (internal) structs.
250- struct AsyncCompletionData
251- {
252- };
253+ struct SC_COMPILER_EXPORT AsyncCompletionData{};
253254
254255// / @brief Base class for all async results (argument of completion callbacks).
255256// / It holds Result (returnCode) and re-activation flag.
256- struct AsyncResult
257+ struct SC_COMPILER_EXPORT AsyncResult
257258{
258259 // / @brief Constructs an async result from a request and a result
259260 AsyncResult (AsyncEventLoop& eventLoop, AsyncRequest& request, SC::Result& res, bool * hasBeenReactivated = nullptr )
@@ -298,7 +299,7 @@ struct AsyncResultOf : public AsyncResult
298299// / @note For a periodic timeout, call AsyncLoopTimeout::Result::reactivateRequest(true) in the completion callback
299300// /
300301// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncLoopTimeoutSnippet
301- struct AsyncLoopTimeout : public AsyncRequest
302+ struct SC_COMPILER_EXPORT AsyncLoopTimeout : public AsyncRequest
302303{
303304 AsyncLoopTimeout () : AsyncRequest(Type::LoopTimeout) {}
304305
@@ -307,8 +308,7 @@ struct AsyncLoopTimeout : public AsyncRequest
307308 using AsyncRequest::start;
308309
309310 // / @brief Sets async request members and calls AsyncEventLoop::start
310- SC::Result start (AsyncEventLoop& eventLoop, TimeMs relativeTimeout);
311-
311+ SC::Result start (AsyncEventLoop& eventLoop, TimeMs relativeTimeout);
312312 Function<void (Result&)> callback; // /< Called after given expiration time since AsyncLoopTimeout::start has passed
313313
314314 TimeMs relativeTimeout; // /< First timer expiration (relative) time in milliseconds
@@ -334,7 +334,7 @@ struct AsyncLoopTimeout : public AsyncRequest
334334// / that the callback has finished its execution.
335335// /
336336// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncLoopWakeUpSnippet2
337- struct AsyncLoopWakeUp : public AsyncRequest
337+ struct SC_COMPILER_EXPORT AsyncLoopWakeUp : public AsyncRequest
338338{
339339 AsyncLoopWakeUp () : AsyncRequest(Type::LoopWakeUp) {}
340340
@@ -362,7 +362,7 @@ struct AsyncLoopWakeUp : public AsyncRequest
362362// / @ref library_process library can be used to start a process and obtain the native process handle.
363363// /
364364// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncProcessSnippet
365- struct AsyncProcessExit : public AsyncRequest
365+ struct SC_COMPILER_EXPORT AsyncProcessExit : public AsyncRequest
366366{
367367 AsyncProcessExit () : AsyncRequest(Type::ProcessExit) {}
368368
@@ -409,7 +409,7 @@ namespace detail
409409{
410410// / @brief Support object to Socket Accept.
411411// / This has been split out of AsyncSocketAccept because on Windows it's quite big to allow heap allocating it
412- struct AsyncSocketAcceptData
412+ struct SC_COMPILER_EXPORT AsyncSocketAcceptData
413413{
414414#if SC_PLATFORM_WINDOWS
415415 void (*pAcceptEx)() = nullptr;
@@ -423,7 +423,7 @@ struct AsyncSocketAcceptData
423423};
424424
425425// / @brief Base class for AsyncSocketAccept to allow dynamically allocating AsyncSocketAcceptData
426- struct AsyncSocketAcceptBase : public AsyncRequest
426+ struct SC_COMPILER_EXPORT AsyncSocketAcceptBase : public AsyncRequest
427427{
428428 AsyncSocketAcceptBase () : AsyncRequest(Type::SocketAccept) {}
429429
@@ -465,7 +465,7 @@ struct AsyncSocketAcceptBase : public AsyncRequest
465465// / @note To continue accepting new socket SC::AsyncResult::reactivateRequest must be called.
466466// /
467467// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncSocketAcceptSnippet
468- struct AsyncSocketAccept : public detail ::AsyncSocketAcceptBase
468+ struct SC_COMPILER_EXPORT AsyncSocketAccept : public detail::AsyncSocketAcceptBase
469469{
470470 AsyncSocketAccept () { AsyncSocketAcceptBase::acceptData = &data; }
471471 using AsyncSocketAcceptBase::start;
@@ -485,7 +485,7 @@ struct AsyncSocketAccept : public detail::AsyncSocketAcceptBase
485485// / Alternatively SC::AsyncEventLoop::createAsyncTCPSocket creates and associates the socket to the loop.
486486// /
487487// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncSocketConnectSnippet
488- struct AsyncSocketConnect : public AsyncRequest
488+ struct SC_COMPILER_EXPORT AsyncSocketConnect : public AsyncRequest
489489{
490490 AsyncSocketConnect () : AsyncRequest(Type::SocketConnect) {}
491491
@@ -519,7 +519,7 @@ struct AsyncSocketConnect : public AsyncRequest
519519// / Alternatively SC::AsyncEventLoop::createAsyncTCPSocket creates and associates the socket to the loop.
520520// /
521521// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncSocketSendSnippet
522- struct AsyncSocketSend : public AsyncRequest
522+ struct SC_COMPILER_EXPORT AsyncSocketSend : public AsyncRequest
523523{
524524 AsyncSocketSend () : AsyncRequest(Type::SocketSend) {}
525525 struct CompletionData : public AsyncCompletionData
@@ -563,7 +563,7 @@ struct AsyncSocketSend : public AsyncRequest
563563// / Alternatively SC::AsyncEventLoop::createAsyncUDPSocket creates and associates the socket to the loop.
564564// /
565565// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncSocketSendToSnippet
566- struct AsyncSocketSendTo : public AsyncSocketSend
566+ struct SC_COMPILER_EXPORT AsyncSocketSendTo : public AsyncSocketSend
567567{
568568 AsyncSocketSendTo () : AsyncSocketSend(Type::SocketSendTo) {}
569569
@@ -595,7 +595,7 @@ struct AsyncSocketSendTo : public AsyncSocketSend
595595// / - SC::AsyncSocketReceive::CompletionData::disconnected will be set to true when client disconnects
596596// /
597597// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncSocketReceiveSnippet
598- struct AsyncSocketReceive : public AsyncRequest
598+ struct SC_COMPILER_EXPORT AsyncSocketReceive : public AsyncRequest
599599{
600600 AsyncSocketReceive () : AsyncRequest(Type::SocketReceive) {}
601601
@@ -648,7 +648,7 @@ struct AsyncSocketReceive : public AsyncRequest
648648// / Alternatively SC::AsyncEventLoop::createAsyncUDPSocket creates and associates the socket to the loop.
649649// /
650650// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncSocketReceiveFromSnippet
651- struct AsyncSocketReceiveFrom : public AsyncSocketReceive
651+ struct SC_COMPILER_EXPORT AsyncSocketReceiveFrom : public AsyncSocketReceive
652652{
653653 AsyncSocketReceiveFrom () : AsyncSocketReceive(Type::SocketReceiveFrom) {}
654654 using AsyncSocketReceive::start;
@@ -683,7 +683,7 @@ struct AsyncSocketReceiveFrom : public AsyncSocketReceive
683683// / - `io_uring` backend will not use thread pool because that API allows proper async file read/writes
684684// /
685685// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncFileReadSnippet
686- struct AsyncFileRead : public AsyncRequest
686+ struct SC_COMPILER_EXPORT AsyncFileRead : public AsyncRequest
687687{
688688 AsyncFileRead () : AsyncRequest(Type::FileRead) { handle = FileDescriptor::Invalid; }
689689
@@ -752,7 +752,7 @@ struct AsyncFileRead : public AsyncRequest
752752// / - Call SC::AsyncEventLoop::associateExternallyCreatedFileDescriptor on the file descriptor
753753// /
754754// / \snippet Tests/Libraries/Async/AsyncTest.cpp AsyncFileWriteSnippet
755- struct AsyncFileWrite : public AsyncRequest
755+ struct SC_COMPILER_EXPORT AsyncFileWrite : public AsyncRequest
756756{
757757 AsyncFileWrite () : AsyncRequest(Type::FileWrite) { handle = FileDescriptor::Invalid; }
758758
@@ -822,7 +822,7 @@ struct AsyncFileWrite : public AsyncRequest
822822// / Uses `GetOverlappedResult` (windows), `kevent` (macOS), `epoll` (Linux) and `io_uring` (Linux).
823823// / Callback will be called when any of the three API signals readiness events on the given file descriptor.
824824// / Check @ref library_file_system_watcher for an example usage of this notification.
825- struct AsyncFilePoll : public AsyncRequest
825+ struct SC_COMPILER_EXPORT AsyncFilePoll : public AsyncRequest
826826{
827827 AsyncFilePoll () : AsyncRequest(Type::FilePoll) {}
828828
@@ -863,7 +863,7 @@ struct AsyncFileSystemOperationCompletionData : public AsyncCompletionData
863863namespace detail
864864{
865865// A simple hand-made variant of all completion types
866- struct AsyncCompletionVariant
866+ struct SC_COMPILER_EXPORT AsyncCompletionVariant
867867{
868868 AsyncCompletionVariant () {}
869869 ~AsyncCompletionVariant () { destroy (); }
@@ -924,7 +924,7 @@ struct AsyncCompletionVariant
924924// / @brief An AsyncSequence using a SC::ThreadPool to execute one or more SC::AsyncRequest in a background thread.
925925// / Calling SC::AsyncRequest::executeOn on multiple requests with the same SC::AsyncTaskSequence queues them to be
926926// / serially executed on the same thread.
927- struct AsyncTaskSequence : public AsyncSequence
927+ struct SC_COMPILER_EXPORT AsyncTaskSequence : public AsyncSequence
928928{
929929 protected:
930930 ThreadPoolTask task;
@@ -943,7 +943,7 @@ struct AsyncTaskSequence : public AsyncSequence
943943// / AsyncLoopWork::callback will be called as a completion, on the event loop thread AFTER work callback is finished.
944944// /
945945// / \snippet Tests/Libraries/Async/AsyncTestLoopWork.inl AsyncLoopWorkSnippet
946- struct AsyncLoopWork : public AsyncRequest
946+ struct SC_COMPILER_EXPORT AsyncLoopWork : public AsyncRequest
947947{
948948 AsyncLoopWork () : AsyncRequest(Type::LoopWork) {}
949949
@@ -996,7 +996,7 @@ struct AsyncLoopWork : public AsyncRequest
996996// / Example of async remove file operation:
997997// / \snippet Tests/Libraries/Async/AsyncTestFileSystemOperation.inl AsyncFileSystemOperationRemoveFileSnippet
998998// /
999- struct AsyncFileSystemOperation : public AsyncRequest
999+ struct SC_COMPILER_EXPORT AsyncFileSystemOperation : public AsyncRequest
10001000{
10011001 AsyncFileSystemOperation () : AsyncRequest(Type::FileSystemOperation) {}
10021002 ~AsyncFileSystemOperation () { destroy (); }
@@ -1172,7 +1172,7 @@ struct AsyncFileSystemOperation : public AsyncRequest
11721172// / @brief Allows user to supply a block of memory that will store kernel I/O events retrieved from
11731173// / AsyncEventLoop::runOnce. Such events can then be later passed to AsyncEventLoop::dispatchCompletions.
11741174// / @see AsyncEventLoop::runOnce
1175- struct AsyncKernelEvents
1175+ struct SC_COMPILER_EXPORT AsyncKernelEvents
11761176{
11771177 Span<uint8_t > eventsMemory; // /< User supplied block of memory used to store kernel I/O events
11781178
@@ -1182,7 +1182,7 @@ struct AsyncKernelEvents
11821182};
11831183
11841184// / @brief Allow library user to provide callbacks signaling different phases of async event loop cycle
1185- struct AsyncEventLoopListeners
1185+ struct SC_COMPILER_EXPORT AsyncEventLoopListeners
11861186{
11871187 Function<void (AsyncEventLoop&)> beforeBlockingPoll;
11881188 Function<void (AsyncEventLoop&)> afterBlockingPoll;
@@ -1352,7 +1352,7 @@ struct AsyncEventLoop
13521352
13531353 struct Internal ;
13541354
1355- private :
1355+ public :
13561356 struct InternalDefinition
13571357 {
13581358 static constexpr int Windows = 520 ;
@@ -1365,7 +1365,6 @@ struct AsyncEventLoop
13651365 using Object = Internal;
13661366 };
13671367
1368- public:
13691368 using InternalOpaque = OpaqueObject<InternalDefinition>;
13701369
13711370 private:
@@ -1382,7 +1381,7 @@ struct AsyncEventLoop
13821381// / @brief Monitors Async I/O events from a background thread using a blocking kernel function (no CPU usage on idle).
13831382// / AsyncEventLoopMonitor makes it easy to integrate AsyncEventLoop within a GUI event loop or another I/O event loop.
13841383// / This pattern avoids constantly polling the kernel, using virtually 0% of CPU time when waiting for events.
1385- struct AsyncEventLoopMonitor
1384+ struct SC_COMPILER_EXPORT AsyncEventLoopMonitor
13861385{
13871386 Function<void (void )> onNewEventsAvailable; // /< Informs to call dispatchCompletions on GUI Event Loop
13881387
@@ -1435,3 +1434,6 @@ struct AsyncEventLoopMonitor
14351434
14361435} // namespace SC
14371436// ! @}
1437+ #if SC_COMPILER_MSVC
1438+ #pragma warning(pop)
1439+ #endif
0 commit comments