Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
WaitForIOReady.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Foundation/Execution/Timeout.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>
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::AssertExternallySynchronizedChecker::ReadContext declareContext{fThisAssertExternallySynchronized_};
37 return fPollData_;
38 }
39 template <typename T, typename TRAITS>
41 {
42 return WaitUntil (waitFor + Time::GetTickCount ());
43 }
44 template <typename T, typename TRAITS>
46 {
47 return WaitQuietlyUntil (waitFor + Time::GetTickCount ());
48 }
49 template <typename T, typename TRAITS>
51 {
52 Debug::AssertExternallySynchronizedChecker::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>
61 {
62 Debug::AssertExternallySynchronizedChecker::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
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::ePriority, L"Priority"},
109 }}};
110}
#define RequireNotNull(p)
Definition Assertions.h:350
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
Definition Realtime.h:82
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
nonvirtual void Add(ArgByValueType< value_type > item)
Definition Set.inl:138
unique_lock< AssertExternallySynchronizedChecker > WriteContext
Instantiate AssertExternallySynchronizedChecker::WriteContext to designate an area of code where prot...
shared_lock< const AssertExternallySynchronizedChecker > ReadContext
Instantiate AssertExternallySynchronizedChecker::ReadContext to designate an area of code where prote...
nonvirtual Containers::Set< T > WaitQuietlyUntil(Time::TimePointSeconds timeoutAt=Time::TimePointSeconds{Time::kInfinity})
nonvirtual Containers::Set< T > WaitQuietly(Time::DurationSeconds waitFor=Time::kInfinity)
WaitForIOReady(const Traversal::Iterable< pair< T, TypeOfMonitorSet > > &fds, optional< pair< SDKPollableType, TypeOfMonitorSet > > pollable2Wakeup=nullopt)
Watch each of fds for the events paired with it - or, in the other overloads, all of fds (or the one ...
nonvirtual Containers::Set< T > WaitUntil(Time::TimePointSeconds timeoutAt=Time::TimePointSeconds{Time::kInfinity})
nonvirtual Containers::Set< T > Wait(Time::DurationSeconds waitFor=Time::kInfinity)
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:234
nonvirtual bool empty() const
Returns true iff size() == 0.
Definition Iterable.inl:317
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 ...
void ThrowTimeoutExceptionAfter(Time::TimePointSeconds afterTickCount, EXCEPTION &&exception2Throw)
How Stroika reports a timeout.
Definition Timeout.inl:21