Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
WaitForIOReady.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "TimeOutException.h"
5
7
8 /*
9 ********************************************************************************
10 ************************** Execution::WaitForIOReady ***************************
11 ********************************************************************************
12 */
13 template <typename T, typename TRAITS>
14 inline WaitForIOReady<T, TRAITS>::WaitForIOReady (const Traversal::Iterable<pair<T, TypeOfMonitorSet>>& fds,
15 optional<pair<SDKPollableType, TypeOfMonitorSet>> pollable2Wakeup)
16 // Containers::Collection{} to force CLONE/FREEZE of data, since elsewise it chould change without this class knowing (iterables not necessarily COW)
17 : fPollData_{Containers::Collection<pair<T, TypeOfMonitorSet>>{fds}}
18 , fPollable2Wakeup_{pollable2Wakeup}
19 {
20 //DbgTrace ("WaitForIOReady::CTOR ({}, {})"_f, fds, pollable2Wakeup);
21 }
22 template <typename T, typename TRAITS>
23 WaitForIOReady<T, TRAITS>::WaitForIOReady (const Traversal::Iterable<T>& fds, const TypeOfMonitorSet& flags,
24 optional<pair<SDKPollableType, TypeOfMonitorSet>> pollable2Wakeup)
25 : WaitForIOReady{fds.template Map<Traversal::Iterable<pair<T, TypeOfMonitorSet>>> ([&] (const T& t) { return make_pair (t, flags); }), pollable2Wakeup}
26 {
27 }
28 template <typename T, typename TRAITS>
29 WaitForIOReady<T, TRAITS>::WaitForIOReady (T fd, const TypeOfMonitorSet& flags, optional<pair<SDKPollableType, TypeOfMonitorSet>> pollable2Wakeup)
30 : WaitForIOReady{Containers::Collection<pair<T, TypeOfMonitorSet>>{make_pair (fd, flags)}, pollable2Wakeup}
31 {
32 }
33 template <typename T, typename TRAITS>
34 inline auto WaitForIOReady<T, TRAITS>::GetDescriptors () const -> Traversal::Iterable<pair<T, TypeOfMonitorSet>>
35 {
36 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
37 return fPollData_;
38 }
39 template <typename T, typename TRAITS>
40 inline auto WaitForIOReady<T, TRAITS>::Wait (Time::DurationSeconds waitFor) -> Containers::Set<T>
41 {
42 return WaitUntil (waitFor + Time::GetTickCount ());
43 }
44 template <typename T, typename TRAITS>
45 inline auto WaitForIOReady<T, TRAITS>::WaitQuietly (Time::DurationSeconds waitFor) -> Containers::Set<T>
46 {
47 return WaitQuietlyUntil (waitFor + Time::GetTickCount ());
48 }
49 template <typename T, typename TRAITS>
50 auto WaitForIOReady<T, TRAITS>::WaitUntil (Time::TimePointSeconds timeoutAt) -> Containers::Set<T>
51 {
52 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
53 Containers::Set<T> result = WaitQuietlyUntil (timeoutAt);
54 if (result.empty ()) {
55 Execution::ThrowTimeoutExceptionAfter (timeoutAt); // maybe returning 0 entries without timeout, because of fPollable2Wakeup_
56 }
57 return result;
58 }
59 template <typename T, typename TRAITS>
60 auto WaitForIOReady<T, TRAITS>::WaitQuietlyUntil (Time::TimePointSeconds timeoutAt) -> Containers::Set<T>
61 {
62 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
63 // Fill two buffers, one with the data needed to pass to _WaitQuietlyUntil, and the other with
64 // corresponding 'T' smart wrapper objects, which we map back to and return as our API result (in same order)
65 auto fillBuffer = [this] (vector<pair<SDKPollableType, TypeOfMonitorSet>>* pollBuffer, vector<T>* mappedObjectBuffer) -> void {
66 RequireNotNull (pollBuffer);
67 RequireNotNull (mappedObjectBuffer);
68 Require (pollBuffer->size () == 0);
69 Require (mappedObjectBuffer->size () == 0);
70 pollBuffer->reserve (fPollData_.size ());
71 mappedObjectBuffer->reserve (fPollData_.size ());
72 for (const auto& i : fPollData_) {
73 pollBuffer->push_back (pair<SDKPollableType, TypeOfMonitorSet>{TRAITS::GetSDKPollable (i.first), i.second});
74 mappedObjectBuffer->push_back (i.first);
75 }
76 if (fPollable2Wakeup_) {
77 pollBuffer->push_back (pair<SDKPollableType, TypeOfMonitorSet>{fPollable2Wakeup_.value ().first, fPollable2Wakeup_.value ().second});
78 }
79 };
80
81 Thread::CheckForInterruption ();
82 vector<pair<SDKPollableType, TypeOfMonitorSet>> pollBuffer;
83 vector<T> mappedObjectBuffer;
84 // @todo REDO THIS calling FillBuffer_ from CTOR (since always used at least once, but could be more than once.
85 fillBuffer (&pollBuffer, &mappedObjectBuffer);
86 Assert (pollBuffer.size () == mappedObjectBuffer.size () or pollBuffer.size () == mappedObjectBuffer.size () + 1);
87 Containers::Set<T> result;
88 for (size_t i : _WaitQuietlyUntil (Containers::Start (pollBuffer), Containers::End (pollBuffer), timeoutAt)) {
89 if (i == mappedObjectBuffer.size ()) {
90 Assert (fPollable2Wakeup_); // externally signalled to wakeup
91 }
92 else {
93 Assert (i < mappedObjectBuffer.size ());
94 result.Add (mappedObjectBuffer[i]);
95 }
96 }
97 return result;
98 }
99
100}
101
103 template <>
104 constexpr EnumNames<Execution::WaitForIOReady_Support::WaitForIOReady_Base::TypeOfMonitor>
105 DefaultNames<Execution::WaitForIOReady_Support::WaitForIOReady_Base::TypeOfMonitor>::k{{{
106 {Execution::WaitForIOReady_Support::WaitForIOReady_Base::TypeOfMonitor::eRead, L"Read"},
107 {Execution::WaitForIOReady_Support::WaitForIOReady_Base::TypeOfMonitor::eWrite, L"Write"},
108 {Execution::WaitForIOReady_Support::WaitForIOReady_Base::TypeOfMonitor::eError, L"Error"},
109 {Execution::WaitForIOReady_Support::WaitForIOReady_Base::TypeOfMonitor::eHUP, L"HUP"},
110 }}};
111}
#define RequireNotNull(p)
Definition Assertions.h:347
CONTAINER::value_type * End(CONTAINER &c)
For a contiguous container (such as a vector or basic_string) - find the pointer to the end of the co...
CONTAINER::value_type * Start(CONTAINER &c)
For a contiguous container (such as a vector or basic_string) - find the pointer to the start of the ...