Anklang-0.3.0.dev551+gad1415e2 anklang-0.3.0.dev551+gad1415e2
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
loop.hh
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#ifndef __ASE_LOOP_HH__
3#define __ASE_LOOP_HH__
4
5#include <ase/utils.hh>
6
7namespace Ase {
8
9// === PollFD ===
10struct PollFD
11{
12 int fd;
13 uint16 events;
14 uint16 revents;
16 enum : uint {
17 IN = ASE_SYSVAL_POLLINIT[0],
18 PRI = ASE_SYSVAL_POLLINIT[1],
19 OUT = ASE_SYSVAL_POLLINIT[2],
20 RDNORM = ASE_SYSVAL_POLLINIT[3],
21 RDBAND = ASE_SYSVAL_POLLINIT[4],
22 WRNORM = ASE_SYSVAL_POLLINIT[5],
23 WRBAND = ASE_SYSVAL_POLLINIT[6],
24 // Event types unconditionally updated in .revents
25 ERR = ASE_SYSVAL_POLLINIT[7],
26 HUP = ASE_SYSVAL_POLLINIT[8],
27 NVAL = ASE_SYSVAL_POLLINIT[9],
28 };
29};
30
31// === Prototypes ===
32class EventSource;
33typedef std::shared_ptr<EventSource> EventSourceP;
34class TimedSource;
35typedef std::shared_ptr<TimedSource> TimedSourceP;
36class PollFDSource;
37typedef std::shared_ptr<PollFDSource> PollFDSourceP;
38class DispatcherSource;
39typedef std::shared_ptr<DispatcherSource> DispatcherSourceP;
40class USignalSource;
41typedef std::shared_ptr<USignalSource> USignalSourceP;
42class SigchldSource;
43typedef std::shared_ptr<SigchldSource> SigchldSourceP;
44class EventLoop;
45typedef std::shared_ptr<EventLoop> EventLoopP;
46class MainLoop;
47typedef std::shared_ptr<MainLoop> MainLoopP;
48struct LoopState;
49#if defined __G_LIB_H__ || defined DOXYGEN
50typedef ::GMainContext GlibGMainContext;
51#else
52struct GlibGMainContext; // dummy type
53#endif
54
55// === EventLoop ===
57class EventLoop : public virtual std::enable_shared_from_this<EventLoop>
58{
59 struct QuickPfdArray; // pseudo vector<PollFD>
60 friend class MainLoop;
61protected:
63 MainLoop *main_loop_;
64 SourceList sources_;
65 std::vector<EventSourceP> poll_sources_;
66 int16 dispatch_priority_;
67 bool primary_;
68 explicit EventLoop (MainLoop&);
69 virtual ~EventLoop ();
70 EventSourceP& find_first_L ();
71 EventSourceP& find_source_L (uint id);
72 bool has_primary_L (void);
73 void remove_source_Lm (EventSourceP source);
74 void kill_sources_Lm (void);
75 void unpoll_sources_U ();
76 void collect_sources_Lm (LoopState&);
77 bool prepare_sources_Lm (LoopState&, QuickPfdArray&);
78 bool check_sources_Lm (LoopState&, const QuickPfdArray&);
79 void dispatch_source_Lm (LoopState&);
80public:
81 typedef std::function<void (void)> VoidSlot;
82 typedef std::function<bool (void)> BoolSlot;
83 typedef std::function<void (PollFD&)> VPfdSlot;
87 typedef std::function<void (int,int)> SigchldSlot;
88 static const int16 PRIORITY_CEILING = 999;
89 static const int16 PRIORITY_NOW = 900;
90 static const int16 PRIORITY_ASCENT = 800;
91 static const int16 PRIORITY_HIGH = 700;
92 static const int16 PRIORITY_NEXT = 600;
93 static const int16 PRIORITY_NORMAL = 500;
94 static const int16 PRIORITY_UPDATE = 400;
95 static const int16 PRIORITY_IDLE = 200;
96 static const int16 PRIORITY_LOW = 100;
97 void wakeup ();
98 // source handling
99 uint add (EventSourceP loop_source, int priority
100 = PRIORITY_NORMAL);
101 void remove (uint id);
102 void remove (uint *idp);
103 bool try_remove (uint id);
104 bool clear_source (uint *id_pointer);
105 void destroy_loop (void);
106 bool has_primary (void);
107 bool flag_primary (bool on);
108 MainLoop* main_loop () const;
109 template<class BoolVoidFunctor>
110 uint exec_now (BoolVoidFunctor &&bvf);
111 template<class BoolVoidFunctor>
112 uint exec_callback (BoolVoidFunctor &&bvf, int priority
113 = PRIORITY_NORMAL);
114 template<class BoolVoidFunctor>
115 uint exec_idle (BoolVoidFunctor &&bvf);
116 uint exec_dispatcher (const DispatcherSlot &sl, int priority
117 = PRIORITY_NORMAL);
118 uint exec_usignal (int8 signum, const USignalSlot &sl, int priority
119 = PRIORITY_NOW -1);
120 uint exec_sigchld (int64_t pid, const SigchldSlot &vfunc, int priority
121 = PRIORITY_NORMAL);
122 bool exec_once (uint delay_ms, uint *once_id, const VoidSlot &vfunc, int priority
123 = PRIORITY_NORMAL);
125 template<class BoolVoidFunctor>
126 uint exec_timer (BoolVoidFunctor &&bvf, uint delay_ms, int64 repeat_ms = -1, int priority = PRIORITY_NORMAL);
128 template<class BoolVoidPollFunctor>
129 uint exec_io_handler (BoolVoidPollFunctor &&bvf, int fd, const String &mode, int priority = PRIORITY_NORMAL);
130};
131
132// === MainLoop ===
134class MainLoop : public EventLoop
135{
136 friend class EventLoop;
137 friend class SubLoop;
138 std::mutex mutex_;
139 uint rr_index_;
141 EventFd eventfd_;
142 int8 running_;
143 int8 has_quit_;
144 int16 quit_code_;
145 GlibGMainContext *gcontext_;
146 bool finishable_L ();
147 void wakeup_poll ();
148 void add_loop_L (EventLoop &loop);
149 void kill_loop_Lm (EventLoop &loop);
150 void kill_loops_Lm ();
151 bool iterate_loops_Lm (LoopState&, bool b, bool d);
152 explicit MainLoop ();
153 virtual ~MainLoop ();
155public:
156 int run ();
157 bool running ();
158 bool finishable ();
159 void quit (int quit_code = 0);
160 bool pending ();
161 bool iterate (bool block);
162 void iterate_pending ();
164 inline std::mutex& mutex () { return mutex_; }
165 static MainLoopP create ();
166 bool set_g_main_context (GlibGMainContext *glib_main_context);
167};
168
169// === LoopState ===
170struct LoopState {
171 enum Phase { NONE, COLLECT, PREPARE, CHECK, DISPATCH, DESTROY };
172 Phase phase = NONE;
173 bool seen_primary = false;
176};
177
178// === EventSource ===
180{
181 friend class EventLoop;
183protected:
184 EventLoop *loop_;
185 struct {
186 PollFD *pfd;
187 uint idx;
188 } *pfds_;
189 uint id_;
190 int16 priority_;
191 uint8 loop_state_;
192 uint may_recurse_ : 1;
193 uint dispatching_ : 1;
194 uint was_dispatching_ : 1;
195 uint primary_ : 1;
196 uint n_pfds ();
197 explicit EventSource ();
198 uint source_id () { return loop_ ? id_ : 0; }
199 virtual ~EventSource ();
200public:
201 virtual bool prepare (const LoopState &state,
202 int64 *timeout_usecs_p) = 0;
203 virtual bool check (const LoopState &state) = 0;
204 virtual bool dispatch (const LoopState &state) = 0;
205 virtual void destroy ();
206 bool recursion () const;
207 bool may_recurse () const;
208 void may_recurse (bool may_recurse);
209 bool primary () const;
210 void primary (bool is_primary);
211 void add_poll (PollFD * const pfd);
212 void remove_poll (PollFD * const pfd);
213 void loop_remove ();
214 MainLoop* main_loop () const { return loop_ ? loop_->main_loop() : NULL; }
215};
216
217// === DispatcherSource ===
218class DispatcherSource : public virtual EventSource
219{
221 DispatcherSlot slot_;
223protected:
224 virtual ~DispatcherSource ();
225 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
226 virtual bool check (const LoopState &state);
227 virtual bool dispatch (const LoopState &state);
228 virtual void destroy ();
229 explicit DispatcherSource (const DispatcherSlot &slot);
230public:
231 static DispatcherSourceP create (const DispatcherSlot &slot)
232 { return make_shared (slot); }
233};
234
235// === USignalSource ===
236class USignalSource : public virtual EventSource
237{
239 USignalSlot slot_;
240 int8 signum_ = 0, index_ = 0, shift_ = 0;
242protected:
243 virtual ~USignalSource ();
244 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
245 virtual bool check (const LoopState &state);
246 virtual bool dispatch (const LoopState &state);
247 virtual void destroy ();
248 explicit USignalSource (int8 signum, const USignalSlot &slot);
249public:
250 static void raise (int8 signum);
251 static USignalSourceP create (int8 signum, const USignalSlot &slot)
252 { return make_shared (signum, slot); }
253 static void install_sigaction (int8);
254};
255
256// === SigchldSource ===
257class SigchldSource : public virtual EventSource
258{
261 SigchldSlot slot_;
262 uint64_t sigchld_counter_ = 0;
263 int64_t pid_ = 0;
264protected:
265 virtual ~SigchldSource ();
266 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
267 virtual bool check (const LoopState &state);
268 virtual bool dispatch (const LoopState &state);
269 virtual void destroy ();
270 explicit SigchldSource (int64_t pid, const SigchldSlot &slot);
271public:
272 static SigchldSourceP create (int64_t pid, const SigchldSlot &slot)
273 { return make_shared (pid, slot); }
274};
275
276// === TimedSource ===
277class TimedSource : public virtual EventSource
278{
281 uint64 expiration_usecs_;
282 uint interval_msecs_;
283 bool first_interval_;
284 const bool oneshot_;
285 union {
286 BoolSlot bool_slot_;
287 VoidSlot void_slot_;
288 };
290protected:
291 virtual ~TimedSource ();
292 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
293 virtual bool check (const LoopState &state);
294 virtual bool dispatch (const LoopState &state);
295 explicit TimedSource (const BoolSlot &slot, uint initial_interval_msecs, uint repeat_interval_msecs);
296 explicit TimedSource (const VoidSlot &slot, uint initial_interval_msecs, uint repeat_interval_msecs);
297public:
298 static TimedSourceP create (const BoolSlot &slot, uint initial_interval_msecs = 0, uint repeat_interval_msecs = 0)
299 { return make_shared (slot, initial_interval_msecs, repeat_interval_msecs); }
300 static TimedSourceP create (const VoidSlot &slot, uint initial_interval_msecs = 0, uint repeat_interval_msecs = 0)
301 { return make_shared (slot, initial_interval_msecs, repeat_interval_msecs); }
302};
303
304// === PollFDSource ===
305class PollFDSource : public virtual EventSource
306{
309protected:
310 void construct (const String &mode);
311 virtual ~PollFDSource ();
312 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
313 virtual bool check (const LoopState &state);
314 virtual bool dispatch (const LoopState &state);
315 virtual void destroy ();
316 PollFD pfd_;
317 uint never_close_ : 1; // 'C'
318private:
319 const uint oneshot_ : 1;
320 union {
321 BPfdSlot bool_poll_slot_;
322 VPfdSlot void_poll_slot_;
323 };
324 explicit PollFDSource (const BPfdSlot &slot, int fd, const String &mode);
325 explicit PollFDSource (const VPfdSlot &slot, int fd, const String &mode);
327public:
328 static PollFDSourceP create (const BPfdSlot &slot, int fd, const String &mode)
329 { return make_shared (slot, fd, mode); }
330 static PollFDSourceP create (const VPfdSlot &slot, int fd, const String &mode)
331 { return make_shared (slot, fd, mode); }
332};
333
334// === EventLoop methods ===
335template<class BoolVoidFunctor> uint
336EventLoop::exec_now (BoolVoidFunctor &&bvf)
337{
338 typedef decltype (bvf()) ReturnType;
339 std::function<ReturnType()> slot (bvf);
340 TimedSourceP tsource = TimedSource::create (slot);
341 tsource->primary (true);
342 return add (tsource, PRIORITY_NOW);
343}
344
345template<class BoolVoidFunctor> uint
346EventLoop::exec_callback (BoolVoidFunctor &&bvf, int priority)
347{
348 typedef decltype (bvf()) ReturnType;
349 std::function<ReturnType()> slot (bvf);
350 return add (TimedSource::create (slot), priority);
351}
352
353template<class BoolVoidFunctor> uint
354EventLoop::exec_idle (BoolVoidFunctor &&bvf)
355{
356 typedef decltype (bvf()) ReturnType;
357 std::function<ReturnType()> slot (bvf);
358 return add (TimedSource::create (slot), PRIORITY_IDLE);
359}
360
361inline uint
362EventLoop::exec_dispatcher (const DispatcherSlot &slot, int priority)
363{
364 return add (DispatcherSource::create (slot), priority);
365}
366
367inline uint
368EventLoop::exec_usignal (int8 signum, const USignalSlot &slot, int priority)
369{
370 return add (USignalSource::create (signum, slot), priority);
371}
372
373inline uint
374EventLoop::exec_sigchld (int64_t pid, const SigchldSlot &slot, int priority)
375{
376 return add (SigchldSource::create (pid, slot), priority);
377}
378
379template<class BoolVoidFunctor> uint
380EventLoop::exec_timer (BoolVoidFunctor &&bvf, uint delay_ms, int64 repeat_ms, int priority)
381{
382 typedef decltype (bvf()) ReturnType;
383 std::function<ReturnType()> slot (bvf);
384 return add (TimedSource::create (slot, delay_ms, repeat_ms < 0 ? delay_ms : repeat_ms), priority);
385}
386
387template<class BoolVoidPollFunctor> uint
388EventLoop::exec_io_handler (BoolVoidPollFunctor &&bvf, int fd, const String &mode, int priority)
389{
390 using ReturnType = decltype (bvf (*std::declval<PollFD*>()));
391 std::function<ReturnType (PollFD&)> slot (bvf);
392 return add (PollFDSource::create (slot, fd, mode), priority);
393}
394
395} // Ase
396
397#endif /* __ASE_LOOP_HH__ */
EventLoop source for handler execution.
Definition loop.hh:219
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1041
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1029
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1035
Wakeup facility for IPC.
Definition utils.hh:63
Loop object, polling for events and executing callbacks in accordance.
Definition loop.hh:58
bool has_primary(void)
Indicates whether loop contains primary sources.
Definition loop.cc:172
void wakeup()
Wakeup loop from polling.
Definition loop.cc:356
void destroy_loop(void)
Remove all sources from a loop and prevent any further execution.
Definition loop.cc:342
bool clear_source(uint *id_pointer)
Remove source if id_pointer and *id_pointer are valid.
Definition loop.cc:258
uint exec_idle(BoolVoidFunctor &&bvf)
Execute a callback with priority "idle", returning true repeats callback.
Definition loop.hh:354
void remove(uint id)
Removes a source from loop, the source must be present.
Definition loop.cc:267
uint exec_usignal(int8 signum, const USignalSlot &sl, int priority=PRIORITY_NOW -1)
Execute a single dispatcher callback for prepare, check, dispatch.
Definition loop.hh:368
static const int16 PRIORITY_NORMAL
Normal importantance, GUI event processing, RPC.
Definition loop.hh:93
uint exec_sigchld(int64_t pid, const SigchldSlot &vfunc, int priority=PRIORITY_NORMAL)
Execute a signal callback for prepare, check, dispatch.
Definition loop.hh:374
static const int16 PRIORITY_CEILING
Internal upper limit, don't use.
Definition loop.hh:88
uint exec_io_handler(BoolVoidPollFunctor &&bvf, int fd, const String &mode, int priority=PRIORITY_NORMAL)
Execute a callback after polling for mode on fd, returning true repeats callback.
Definition loop.hh:388
bool exec_once(uint delay_ms, uint *once_id, const VoidSlot &vfunc, int priority=PRIORITY_NORMAL)
Execute a callback once on SIGCHLD for pid.
Definition loop.cc:274
static const int16 PRIORITY_UPDATE
Mildly important, used for GUI updates or user information.
Definition loop.hh:94
uint exec_timer(BoolVoidFunctor &&bvf, uint delay_ms, int64 repeat_ms=-1, int priority=PRIORITY_NORMAL)
Execute a callback after a specified timeout with adjustable initial timeout, returning true repeats ...
Definition loop.hh:380
static const int16 PRIORITY_HIGH
Very important, used for timers or IO handlers.
Definition loop.hh:91
MainLoop * main_loop() const
Get the main loop for this loop.
Definition loop.cc:190
uint exec_now(BoolVoidFunctor &&bvf)
Execute a callback as primary source with priority "now" (highest), returning true repeats callback.
Definition loop.hh:336
uint exec_callback(BoolVoidFunctor &&bvf, int priority=PRIORITY_NORMAL)
Execute a callback at user defined priority returning true repeats callback.
Definition loop.hh:346
static const int16 PRIORITY_IDLE
Mildly important, used for background tasks.
Definition loop.hh:95
static const int16 PRIORITY_ASCENT
Threshold for priorization across different loops.
Definition loop.hh:90
bool try_remove(uint id)
Tries to remove a source, returns if successfull.
Definition loop.cc:234
uint add(EventSourceP loop_source, int priority=PRIORITY_NORMAL)
Adds a new source to the loop with custom priority.
Definition loop.cc:198
static const int16 PRIORITY_NEXT
Important, used for async operations and callbacks.
Definition loop.hh:92
static const int16 PRIORITY_LOW
Unimportant, used when everything else done.
Definition loop.hh:96
static const int16 PRIORITY_NOW
Most important, used for immediate async execution.
Definition loop.hh:89
EventLoop source for callback execution.
Definition loop.hh:180
bool primary() const
Indicate whether this source is primary.
Definition loop.cc:950
void add_poll(PollFD *const pfd)
Add a PollFD descriptors for poll(2) and check().
Definition loop.cc:968
void loop_remove()
Remove this source from its event loop if any.
Definition loop.cc:1005
MainLoop * main_loop() const
Get the main loop for this source.
Definition loop.hh:214
void remove_poll(PollFD *const pfd)
Remove a previously added PollFD.
Definition loop.cc:982
virtual bool dispatch(const LoopState &state)=0
Dispatch source, returns if it should be kept alive.
virtual bool check(const LoopState &state)=0
Check the source and its PollFD descriptors for dispatching (true return).
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)=0
Prepare the source for dispatching (true return) or polling (false).
bool recursion() const
Indicates wether the source is currently in recursion.
Definition loop.cc:962
bool may_recurse() const
Indicates if this source may recurse.
Definition loop.cc:944
An EventLoop implementation that offers public API for running the loop.
Definition loop.hh:135
EventLoopP create_sub_loop()
Creates a new event loop that is run as part of this main loop.
Definition loop.cc:906
void quit(int quit_code=0)
Cause run() to return with quit_code.
Definition loop.cc:469
static MainLoopP create()
Create a MainLoop shared pointer handle.
Definition loop.cc:379
bool pending()
Check if iterate() needs to be called for dispatching.
Definition loop.cc:534
int run()
Run loop iterations until a call to quit() or finishable becomes true.
Definition loop.cc:446
bool set_g_main_context(GlibGMainContext *glib_main_context)
Set context to integrate with a GLib GMainContext loop.
Definition loop.cc:543
void iterate_pending()
Call iterate() until no immediate dispatching is needed.
Definition loop.cc:520
bool running()
Indicates if quit() has been called already.
Definition loop.cc:462
bool finishable()
Indicates wether this loop has no primary sources left to process.
Definition loop.cc:490
std::mutex & mutex()
Provide access to the mutex associated with this main loop.
Definition loop.hh:164
bool iterate(bool block)
Perform one loop iteration and return whether more iterations are needed.
Definition loop.cc:507
EventLoop source for IO callbacks.
Definition loop.hh:306
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1337
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1324
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1331
EventLoop source for handler execution.
Definition loop.hh:258
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1176
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1164
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1170
EventLoop source for timer execution.
Definition loop.hh:278
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1241
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1226
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1247
EventLoop source for handler execution.
Definition loop.hh:237
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1093
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1081
static void raise(int8 signum)
Flag a unix signal being raised, this function may be called from any thread at any time.
Definition loop.cc:1072
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1087
#define ASE_DEFINE_MAKE_SHARED(CLASS)
Define a member function static shared_ptr<CLASS> make_shared(ctorargs...);.
Definition cxxaux.hh:269
#define ASE_CLASS_NON_COPYABLE(ClassName)
Delete copy ctor and assignment operator.
Definition cxxaux.hh:106
The Anklang C++ API namespace.
Definition api.hh:9
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
Definition cxxaux.hh:25
int16_t int16
A 16-bit signed integer.
Definition cxxaux.hh:27
uint8_t uint8
An 8-bit unsigned integer.
Definition cxxaux.hh:22
int8_t int8
An 8-bit signed integer.
Definition cxxaux.hh:26
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
Definition cxxaux.hh:29
uint16_t uint16
A 16-bit unsigned integer.
Definition cxxaux.hh:23
uint32_t uint
Provide 'uint' as convenience type.
Definition cxxaux.hh:18
typedef uint64_t
bool seen_primary
Useful as hint for primary source presence, MainLoop::finishable() checks exhaustively.
Definition loop.hh:173
uint64 current_time_usecs
Equals timestamp_realtime() as of prepare() and check().
Definition loop.hh:174
int64 timeout_usecs
Maximum timeout for poll, queried during prepare().
Definition loop.hh:175
Mirrors struct pollfd for poll(3posix)
Definition loop.hh:11
@ RDNORM
reading data will not block
Definition loop.hh:20
@ HUP
file descriptor closed
Definition loop.hh:26
@ IN
RDNORM || RDBAND.
Definition loop.hh:17
@ WRNORM
writing data will not block
Definition loop.hh:22
@ PRI
urgent data available
Definition loop.hh:18
@ NVAL
invalid PollFD
Definition loop.hh:27
@ RDBAND
reading priority data will not block
Definition loop.hh:21
@ OUT
writing data will not block
Definition loop.hh:19
@ ERR
error condition
Definition loop.hh:25
@ WRBAND
writing priority data will not block
Definition loop.hh:23