Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
UpdatableWaitForIOReady.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Execution_UpdatableWaitForIOReady_h_
5#define _Stroika_Foundation_Execution_UpdatableWaitForIOReady_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
10
11/**
12 * \file
13 *
14 * TODO:
15 * @todo NYI Remove/RemoveAll - easy but not used yet, so low priority
16 *
17 */
18
20
21 /**
22 * \brief Simple wrapper on WaitForIOReady (POSIX select/poll/etc API) - except it allows for the list
23 * if polled descriptors to be updated dynamically from any thread, and have that automatically wakeup any
24 * waiters to restart waiting
25 *
26 * \note Calls to Add/Remove/clear/SetDescriptors () cause Wait() to return prematurely, almost as if a timeout, except that
27 * a timeout exception won't be caused by this return (per-se). This means wait can legitimately return zero items
28 * without throwing a timeout exception
29 *
30 * \par Example Usage
31 * \code
32 * ...INSIDE CLASS DECLARATION
33 * struct MyWaitForIOReady_Traits_ {
34 * using HighLevelType = shared_ptr<Connection>;
35 * static inline auto GetSDKPollable (const HighLevelType& t)
36 * {
37 * return t->GetSocket ().GetNativeSocket ();
38 * }
39 * };
40 * UpdatableWaitForIOReady<shared_ptr<Connection>, MyWaitForIOReady_Traits_> fSockSetPoller_{};
41 * ...
42 *
43 * loopWaitingForWorkTodo()
44 * while (true) {
45 * for (shared_ptr<Connection> readyConnection : fSockSetPoller_.WaitQuietly ()) {
46 * ... handle ready connection
47 *
48 * ... elsewhere
49 * onAccept(shared_ptr<Connection) c) {
50 * fSockSetPoller_.Add (c);
51 * }
52 *
53 * \endcode
54 *
55 * \note \em Thread-Safety <a href="Thread-Safety.md#Internally-Synchronized-Thread-Safety">Internally-Synchronized-Thread-Safety</a>
56 *
57 * \todo @todo DECIDE IF T is a KEY - that is - if allowed to appear more than once in the list.
58 * Update the logic for Add/Remove and constructors accordingly!!!
59 * PROBABLY best definition is that its a KEY, but you can in constructor/add pass in more than once, and they get merged together like a set.
60 * (NOTE - NYI but easy). Then Remove functions need overloads letting you specify the POLL params too.
61 *
62 */
63 template <typename T = WaitForIOReady_Support::SDKPollableType, typename TRAITS = WaitForIOReady_Support::WaitForIOReady_Traits<T>>
64 class UpdatableWaitForIOReady : public WaitForIOReady_Support::WaitForIOReady_Base {
65 public:
66 /**
67 */
70 UpdatableWaitForIOReady (const Traversal::Iterable<pair<T, TypeOfMonitorSet>>& fds);
71 UpdatableWaitForIOReady (const Traversal::Iterable<T>& fds, const TypeOfMonitorSet& flags = kDefaultTypeOfMonitor);
72 UpdatableWaitForIOReady (const T& fd, const TypeOfMonitorSet& flags = kDefaultTypeOfMonitor);
73
74 public:
75 ~UpdatableWaitForIOReady () = default;
76
77 public:
78 nonvirtual UpdatableWaitForIOReady& operator= (const UpdatableWaitForIOReady&) = delete;
79
80 public:
81 /**
82 */
83 nonvirtual void Add (T fd, const TypeOfMonitorSet& flags = kDefaultTypeOfMonitor);
84
85 public:
86 /**
87 */
88 nonvirtual void AddAll (const Traversal::Iterable<pair<T, TypeOfMonitorSet>>& fds);
89 nonvirtual void AddAll (const Traversal::Iterable<T>& fds, const TypeOfMonitorSet& flags = kDefaultTypeOfMonitor);
90
91 public:
92 /**
93 */
94 nonvirtual void Remove (T fd);
95
96 public:
97 /**
98 */
99 nonvirtual void RemoveAll (const Traversal::Iterable<T>& fds);
100
101 public:
102 /**
103 */
104 nonvirtual Containers::Collection<pair<T, TypeOfMonitorSet>> GetDescriptors () const;
105
106 public:
107 /**
108 */
109 nonvirtual void SetDescriptors (const Traversal::Iterable<pair<T, TypeOfMonitorSet>>& fds);
110 nonvirtual void SetDescriptors (const Traversal::Iterable<T>& fds, const TypeOfMonitorSet& flags = kDefaultTypeOfMonitor);
111
112 public:
113 /**
114 * Clear the set of watched file descriptors, and cause any waiters to wake immediately to re-examine the situation.
115 */
116 nonvirtual void clear ();
117
118 public:
119 /*
120 * Waits the given amount of time, and returns as soon as any one (or more) requires service (see TypeOfMonitor), or possibly zero if pollable2Wakeup Set.
121 *
122 * \note Throws TimeOutException () on timeout.
123 *
124 * \note ***Cancelation Point***
125 *
126 * @see WaitQuietly
127 * @see WaitUntil
128 * @see WaitQuietlyUntil
129 */
130 nonvirtual Containers::Set<T> Wait (Time::DurationSeconds waitFor = Time::kInfinity);
131 nonvirtual Containers::Set<T> Wait (const Time::Duration& waitFor);
132
133 public:
134 /*
135 * Waits the given amount of time, and returns as soon as any one (or more) requires service (see TypeOfMonitor), or possibly zero if pollable2Wakeup Set.
136 *
137 * Returns set of file descriptors which are ready, or empty set if timeout.
138 *
139 * \note ***Cancelation Point***
140 *
141 * @see Wait
142 * @see WaitUntil
143 * @see WaitQuietlyUntil
144 */
145 nonvirtual Containers::Set<T> WaitQuietly (Time::DurationSeconds waitFor = Time::kInfinity);
146 nonvirtual Containers::Set<T> WaitQuietly (const Time::Duration& waitFor);
147
148 public:
149 /*
150 * Waits until the given timeoutAt, and returns as soon as any one (or more) requires service (see TypeOfMonitor), or possibly zero if pollable2Wakeup Set.
151 *
152 * \note Throws TimeOutException () on timeout.
153 *
154 * \note ***Cancelation Point***
155 *
156 * @see Wait
157 * @see WaitQuietly
158 * @see WaitQuietlyUntil
159 */
160 nonvirtual Containers::Set<T> WaitUntil (Time::TimePointSeconds timeoutAt = Time::TimePointSeconds{Time::kInfinity});
161
162 public:
163 /*
164 * Waits until the given timeoutAt, and returns as soon as any one (or more) requires service (see TypeOfMonitor), or possibly zero if pollable2Wakeup Set.
165 *
166 * Returns set of file descriptors which are ready, or an empty set if time expired before any became ready.
167 *
168 * if timeout is <= 0, this will not wait (but may still find some file descriptors ready).
169 *
170 * \note ***Cancelation Point***
171 *
172 * @see Wait
173 * @see WaitQuietly
174 * @see WaitUntil
175 */
176 nonvirtual Containers::Set<T> WaitQuietlyUntil (Time::TimePointSeconds timeoutAt = Time::TimePointSeconds{Time::kInfinity});
177
178 private:
179 /*
180 * note: lock design - keep short locks on fData_, and make a new 'waiter' with a copy of the FDs list (COW copy)
181 * so don't hold fData synchronized lock during wait on 'select'
182 */
183
184 private:
185 nonvirtual WaitForIOReady<T, TRAITS> mkWaiter_ ();
186
187 private:
188 unique_ptr<WaitForIOReady_Support::EventFD> fEventFD_;
189 pair<SDKPollableType, TypeOfMonitorSet> fPollable2Wakeup_;
191 };
192
193}
194
195/*
196 ********************************************************************************
197 ***************************** Implementation Details ***************************
198 ********************************************************************************
199 */
200#include "UpdatableWaitForIOReady.inl"
201
202#endif /*_Stroika_Foundation_Execution_UpdatableWaitForIOReady_h_*/
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
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
Definition Collection.h:102
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition Set.h:105
Wrap any object with Synchronized<> and it can be used similarly to the base type,...
Simple wrapper on WaitForIOReady (POSIX select/poll/etc API) - except it allows for the list if polle...
Duration is a chrono::duration<double> (=.
Definition Duration.h:96
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237