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