Anklang 0.3.0-460-gc4ef46ba
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 bool try_remove (uint id);
103 bool clear_source (uint *id_pointer);
104 void destroy_loop (void);
105 bool has_primary (void);
106 bool flag_primary (bool on);
107 MainLoop* main_loop () const;
108 template<class BoolVoidFunctor>
109 uint exec_now (BoolVoidFunctor &&bvf);
110 template<class BoolVoidFunctor>
111 uint exec_callback (BoolVoidFunctor &&bvf, int priority
112 = PRIORITY_NORMAL);
113 template<class BoolVoidFunctor>
114 uint exec_idle (BoolVoidFunctor &&bvf);
115 uint exec_dispatcher (const DispatcherSlot &sl, int priority
116 = PRIORITY_NORMAL);
117 uint exec_usignal (int8 signum, const USignalSlot &sl, int priority
118 = PRIORITY_NOW -1);
119 uint exec_sigchld (int64_t pid, const SigchldSlot &vfunc, int priority
120 = PRIORITY_NORMAL);
121 bool exec_once (uint delay_ms, uint *once_id, const VoidSlot &vfunc, int priority
122 = PRIORITY_NORMAL);
124 template<class BoolVoidFunctor>
125 uint exec_timer (BoolVoidFunctor &&bvf, uint delay_ms, int64 repeat_ms = -1, int priority = PRIORITY_NORMAL);
127 template<class BoolVoidPollFunctor>
128 uint exec_io_handler (BoolVoidPollFunctor &&bvf, int fd, const String &mode, int priority = PRIORITY_NORMAL);
129};
130
131// === MainLoop ===
133class MainLoop : public EventLoop
134{
135 friend class EventLoop;
136 friend class SubLoop;
137 std::mutex mutex_;
138 uint rr_index_;
140 EventFd eventfd_;
141 int8 running_;
142 int8 has_quit_;
143 int16 quit_code_;
144 GlibGMainContext *gcontext_;
145 bool finishable_L ();
146 void wakeup_poll ();
147 void add_loop_L (EventLoop &loop);
148 void kill_loop_Lm (EventLoop &loop);
149 void kill_loops_Lm ();
150 bool iterate_loops_Lm (LoopState&, bool b, bool d);
151 explicit MainLoop ();
152 virtual ~MainLoop ();
154public:
155 int run ();
156 bool running ();
157 bool finishable ();
158 void quit (int quit_code = 0);
159 bool pending ();
160 bool iterate (bool block);
161 void iterate_pending ();
163 inline std::mutex& mutex () { return mutex_; }
164 static MainLoopP create ();
165 bool set_g_main_context (GlibGMainContext *glib_main_context);
166};
167
168// === LoopState ===
169struct LoopState {
170 enum Phase { NONE, COLLECT, PREPARE, CHECK, DISPATCH, DESTROY };
171 Phase phase = NONE;
172 bool seen_primary = false;
175};
176
177// === EventSource ===
179{
180 friend class EventLoop;
182protected:
183 EventLoop *loop_;
184 struct {
185 PollFD *pfd;
186 uint idx;
187 } *pfds_;
188 uint id_;
189 int16 priority_;
190 uint8 loop_state_;
191 uint may_recurse_ : 1;
192 uint dispatching_ : 1;
193 uint was_dispatching_ : 1;
194 uint primary_ : 1;
195 uint n_pfds ();
196 explicit EventSource ();
197 uint source_id () { return loop_ ? id_ : 0; }
198 virtual ~EventSource ();
199public:
200 virtual bool prepare (const LoopState &state,
201 int64 *timeout_usecs_p) = 0;
202 virtual bool check (const LoopState &state) = 0;
203 virtual bool dispatch (const LoopState &state) = 0;
204 virtual void destroy ();
205 bool recursion () const;
206 bool may_recurse () const;
207 void may_recurse (bool may_recurse);
208 bool primary () const;
209 void primary (bool is_primary);
210 void add_poll (PollFD * const pfd);
211 void remove_poll (PollFD * const pfd);
212 void loop_remove ();
213 MainLoop* main_loop () const { return loop_ ? loop_->main_loop() : NULL; }
214};
215
216// === DispatcherSource ===
217class DispatcherSource : public virtual EventSource
218{
220 DispatcherSlot slot_;
222protected:
223 virtual ~DispatcherSource ();
224 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
225 virtual bool check (const LoopState &state);
226 virtual bool dispatch (const LoopState &state);
227 virtual void destroy ();
228 explicit DispatcherSource (const DispatcherSlot &slot);
229public:
230 static DispatcherSourceP create (const DispatcherSlot &slot)
231 { return make_shared (slot); }
232};
233
234// === USignalSource ===
235class USignalSource : public virtual EventSource
236{
238 USignalSlot slot_;
239 int8 signum_ = 0, index_ = 0, shift_ = 0;
241protected:
242 virtual ~USignalSource ();
243 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
244 virtual bool check (const LoopState &state);
245 virtual bool dispatch (const LoopState &state);
246 virtual void destroy ();
247 explicit USignalSource (int8 signum, const USignalSlot &slot);
248public:
249 static void raise (int8 signum);
250 static USignalSourceP create (int8 signum, const USignalSlot &slot)
251 { return make_shared (signum, slot); }
252 static void install_sigaction (int8);
253};
254
255// === SigchldSource ===
256class SigchldSource : public virtual EventSource
257{
260 SigchldSlot slot_;
261 uint64_t sigchld_counter_ = 0;
262 int64_t pid_ = 0;
263protected:
264 virtual ~SigchldSource ();
265 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
266 virtual bool check (const LoopState &state);
267 virtual bool dispatch (const LoopState &state);
268 virtual void destroy ();
269 explicit SigchldSource (int64_t pid, const SigchldSlot &slot);
270public:
271 static SigchldSourceP create (int64_t pid, const SigchldSlot &slot)
272 { return make_shared (pid, slot); }
273};
274
275// === TimedSource ===
276class TimedSource : public virtual EventSource
277{
280 uint64 expiration_usecs_;
281 uint interval_msecs_;
282 bool first_interval_;
283 const bool oneshot_;
284 union {
285 BoolSlot bool_slot_;
286 VoidSlot void_slot_;
287 };
289protected:
290 virtual ~TimedSource ();
291 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
292 virtual bool check (const LoopState &state);
293 virtual bool dispatch (const LoopState &state);
294 explicit TimedSource (const BoolSlot &slot, uint initial_interval_msecs, uint repeat_interval_msecs);
295 explicit TimedSource (const VoidSlot &slot, uint initial_interval_msecs, uint repeat_interval_msecs);
296public:
297 static TimedSourceP create (const BoolSlot &slot, uint initial_interval_msecs = 0, uint repeat_interval_msecs = 0)
298 { return make_shared (slot, initial_interval_msecs, repeat_interval_msecs); }
299 static TimedSourceP create (const VoidSlot &slot, uint initial_interval_msecs = 0, uint repeat_interval_msecs = 0)
300 { return make_shared (slot, initial_interval_msecs, repeat_interval_msecs); }
301};
302
303// === PollFDSource ===
304class PollFDSource : public virtual EventSource
305{
308protected:
309 void construct (const String &mode);
310 virtual ~PollFDSource ();
311 virtual bool prepare (const LoopState &state, int64 *timeout_usecs_p);
312 virtual bool check (const LoopState &state);
313 virtual bool dispatch (const LoopState &state);
314 virtual void destroy ();
315 PollFD pfd_;
316 uint never_close_ : 1; // 'C'
317private:
318 const uint oneshot_ : 1;
319 union {
320 BPfdSlot bool_poll_slot_;
321 VPfdSlot void_poll_slot_;
322 };
323 explicit PollFDSource (const BPfdSlot &slot, int fd, const String &mode);
324 explicit PollFDSource (const VPfdSlot &slot, int fd, const String &mode);
326public:
327 static PollFDSourceP create (const BPfdSlot &slot, int fd, const String &mode)
328 { return make_shared (slot, fd, mode); }
329 static PollFDSourceP create (const VPfdSlot &slot, int fd, const String &mode)
330 { return make_shared (slot, fd, mode); }
331};
332
333// === EventLoop methods ===
334template<class BoolVoidFunctor> uint
335EventLoop::exec_now (BoolVoidFunctor &&bvf)
336{
337 typedef decltype (bvf()) ReturnType;
338 std::function<ReturnType()> slot (bvf);
339 TimedSourceP tsource = TimedSource::create (slot);
340 tsource->primary (true);
341 return add (tsource, PRIORITY_NOW);
342}
343
344template<class BoolVoidFunctor> uint
345EventLoop::exec_callback (BoolVoidFunctor &&bvf, int priority)
346{
347 typedef decltype (bvf()) ReturnType;
348 std::function<ReturnType()> slot (bvf);
349 return add (TimedSource::create (slot), priority);
350}
351
352template<class BoolVoidFunctor> uint
353EventLoop::exec_idle (BoolVoidFunctor &&bvf)
354{
355 typedef decltype (bvf()) ReturnType;
356 std::function<ReturnType()> slot (bvf);
357 return add (TimedSource::create (slot), PRIORITY_IDLE);
358}
359
360inline uint
361EventLoop::exec_dispatcher (const DispatcherSlot &slot, int priority)
362{
363 return add (DispatcherSource::create (slot), priority);
364}
365
366inline uint
367EventLoop::exec_usignal (int8 signum, const USignalSlot &slot, int priority)
368{
369 return add (USignalSource::create (signum, slot), priority);
370}
371
372inline uint
373EventLoop::exec_sigchld (int64_t pid, const SigchldSlot &slot, int priority)
374{
375 return add (SigchldSource::create (pid, slot), priority);
376}
377
378template<class BoolVoidFunctor> uint
379EventLoop::exec_timer (BoolVoidFunctor &&bvf, uint delay_ms, int64 repeat_ms, int priority)
380{
381 typedef decltype (bvf()) ReturnType;
382 std::function<ReturnType()> slot (bvf);
383 return add (TimedSource::create (slot, delay_ms, repeat_ms < 0 ? delay_ms : repeat_ms), priority);
384}
385
386template<class BoolVoidPollFunctor> uint
387EventLoop::exec_io_handler (BoolVoidPollFunctor &&bvf, int fd, const String &mode, int priority)
388{
389 using ReturnType = decltype (bvf (*std::declval<PollFD*>()));
390 std::function<ReturnType (PollFD&)> slot (bvf);
391 return add (PollFDSource::create (slot, fd, mode), priority);
392}
393
394} // Ase
395
396#endif /* __ASE_LOOP_HH__ */
EventLoop source for handler execution.
Definition loop.hh:218
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1031
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1019
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1025
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:346
void destroy_loop(void)
Definition loop.cc:332
bool clear_source(uint *id_pointer)
Remove source if id_pointer and *id_pointer are valid.
Definition loop.cc:248
uint exec_idle(BoolVoidFunctor &&bvf)
Execute a callback with priority "idle", returning true repeats callback.
Definition loop.hh:353
void remove(uint id)
Removes a source from loop, the source must be present.
Definition loop.cc:257
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:367
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:373
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:387
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:264
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:379
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:335
uint exec_callback(BoolVoidFunctor &&bvf, int priority=PRIORITY_NORMAL)
Execute a callback at user defined priority returning true repeats callback.
Definition loop.hh:345
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:179
bool primary() const
Indicate whether this source is primary.
Definition loop.cc:940
void add_poll(PollFD *const pfd)
Add a PollFD descriptors for poll(2) and check().
Definition loop.cc:958
void loop_remove()
Remove this source from its event loop if any.
Definition loop.cc:995
MainLoop * main_loop() const
Get the main loop for this source.
Definition loop.hh:213
void remove_poll(PollFD *const pfd)
Remove a previously added PollFD.
Definition loop.cc:972
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:952
bool may_recurse() const
Indicates if this source may recurse.
Definition loop.cc:934
An EventLoop implementation that offers public API for running the loop.
Definition loop.hh:134
EventLoopP create_sub_loop()
Creates a new event loop that is run as part of this main loop.
Definition loop.cc:896
void quit(int quit_code=0)
Cause run() to return with quit_code.
Definition loop.cc:459
static MainLoopP create()
Create a MainLoop shared pointer handle.
Definition loop.cc:369
bool pending()
Check if iterate() needs to be called for dispatching.
Definition loop.cc:524
int run()
Run loop iterations until a call to quit() or finishable becomes true.
Definition loop.cc:436
bool set_g_main_context(GlibGMainContext *glib_main_context)
Set context to integrate with a GLib GMainContext loop.
Definition loop.cc:533
void iterate_pending()
Call iterate() until no immediate dispatching is needed.
Definition loop.cc:510
bool running()
Indicates if quit() has been called already.
Definition loop.cc:452
bool finishable()
Indicates wether this loop has no primary sources left to process.
Definition loop.cc:480
std::mutex & mutex()
Provide access to the mutex associated with this main loop.
Definition loop.hh:163
bool iterate(bool block)
Perform one loop iteration and return whether more iterations are needed.
Definition loop.cc:497
EventLoop source for IO callbacks.
Definition loop.hh:305
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1327
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1314
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1321
EventLoop source for handler execution.
Definition loop.hh:257
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1166
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1154
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1160
EventLoop source for timer execution.
Definition loop.hh:277
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1231
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1216
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1237
EventLoop source for handler execution.
Definition loop.hh:236
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Definition loop.cc:1083
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
Definition loop.cc:1071
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:1062
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Definition loop.cc:1077
#define ASE_DEFINE_MAKE_SHARED(CLASS)
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:172
uint64 current_time_usecs
Equals timestamp_realtime() as of prepare() and check().
Definition loop.hh:173
int64 timeout_usecs
Maximum timeout for poll, queried during prepare().
Definition loop.hh:174
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