ChibiOS/RT 7.0.5
chevents.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19/*
20 Concepts and parts of this file have been contributed by Scott (skute).
21 */
22
23/**
24 * @file rt/src/chevents.c
25 * @brief Events code.
26 *
27 * @addtogroup events
28 * @details Event Flags, Event Sources and Event Listeners.
29 * <h2>Operation mode</h2>
30 * Each thread has a mask of pending events inside its
31 * @p thread_t structure.
32 * Operations defined for events:
33 * - <b>Wait</b>, the invoking thread goes to sleep until a certain
34 * AND/OR combination of events are signaled.
35 * - <b>Clear</b>, a mask of events is cleared from the pending
36 * events, the cleared events mask is returned (only the
37 * events that were actually pending and then cleared).
38 * - <b>Signal</b>, an events mask is directly ORed to the mask of
39 * the signaled thread.
40 * - <b>Broadcast</b>, each thread registered on an Event Source is
41 * signaled with the events specified in its Event Listener.
42 * - <b>Dispatch</b>, an events mask is scanned and for each bit set
43 * to one an associated handler function is invoked. Bit masks are
44 * scanned from bit zero upward.
45 * .
46 * An Event Source is a special object that can be "broadcasted" by
47 * a thread or an interrupt service routine. Broadcasting an Event
48 * Source has the effect that all the threads registered on the
49 * Event Source will be signaled with an events mask.<br>
50 * An unlimited number of Event Sources can exists in a system and
51 * each thread can be listening on an unlimited number of
52 * them.
53 * @pre In order to use the Events APIs the @p CH_CFG_USE_EVENTS option
54 * must be enabled in @p chconf.h.
55 * @post Enabling events requires 1-4 (depending on the architecture)
56 * extra bytes in the @p thread_t structure.
57 * @{
58 */
59
60#include "ch.h"
61
62#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
63
64/*===========================================================================*/
65/* Module local definitions. */
66/*===========================================================================*/
67
68/*===========================================================================*/
69/* Module exported variables. */
70/*===========================================================================*/
71
72/*===========================================================================*/
73/* Module local types. */
74/*===========================================================================*/
75
76/*===========================================================================*/
77/* Module local variables. */
78/*===========================================================================*/
79
80/*===========================================================================*/
81/* Module local functions. */
82/*===========================================================================*/
83
84/*===========================================================================*/
85/* Module exported functions. */
86/*===========================================================================*/
87
88/**
89 * @brief Registers an Event Listener on an Event Source.
90 * @details Once a thread has registered as listener on an event source it
91 * will be notified of all events broadcasted there.
92 * @note Multiple Event Listeners can specify the same bits to be ORed to
93 * different threads.
94 *
95 * @param[in] esp pointer to the @p event_source_t structure
96 * @param[in] elp pointer to the @p event_listener_t structure
97 * @param[in] events events to be ORed to the thread when
98 * the event source is broadcasted
99 * @param[in] wflags mask of flags the listening thread is interested in
100 *
101 * @iclass
102 */
104 event_listener_t *elp,
105 eventmask_t events,
106 eventflags_t wflags) {
107 thread_t *currtp = chThdGetSelfX();
108
110 chDbgCheck((esp != NULL) && (elp != NULL));
111
112 elp->next = esp->next;
113 esp->next = elp;
114 elp->listener = currtp;
115 elp->events = events;
116 elp->flags = (eventflags_t)0;
117 elp->wflags = wflags;
118}
119
120/**
121 * @brief Registers an Event Listener on an Event Source.
122 * @details Once a thread has registered as listener on an event source it
123 * will be notified of all events broadcasted there.
124 * @note Multiple Event Listeners can specify the same bits to be ORed to
125 * different threads.
126 *
127 * @param[in] esp pointer to the @p event_source_t structure
128 * @param[in] elp pointer to the @p event_listener_t structure
129 * @param[in] events events to be ORed to the thread when
130 * the event source is broadcasted
131 * @param[in] wflags mask of flags the listening thread is interested in
132 *
133 * @api
134 */
136 event_listener_t *elp,
137 eventmask_t events,
138 eventflags_t wflags) {
139
140 chSysLock();
141 chEvtRegisterMaskWithFlagsI(esp, elp, events, wflags);
142 chSysUnlock();
143}
144
145/**
146 * @brief Unregisters an Event Listener from its Event Source.
147 * @note If the event listener is not registered on the specified event
148 * source then the function does nothing.
149 * @note For optimal performance it is better to perform the unregister
150 * operations in inverse order of the register operations (elements
151 * are found on top of the list).
152 *
153 * @param[in] esp pointer to the @p event_source_t structure
154 * @param[in] elp pointer to the @p event_listener_t structure
155 *
156 * @api
157 */
160
161 chDbgCheck((esp != NULL) && (elp != NULL));
162
163 /*lint -save -e9087 -e740 [11.3, 1.3] Cast required by list handling.*/
164 p = (event_listener_t *)esp;
165 /*lint -restore*/
166 chSysLock();
167 /*lint -save -e9087 -e740 [11.3, 1.3] Cast required by list handling.*/
168 while (p->next != (event_listener_t *)esp) {
169 /*lint -restore*/
170 if (p->next == elp) {
171 p->next = elp->next;
172 break;
173 }
174 p = p->next;
175 }
176 chSysUnlock();
177}
178
179/**
180 * @brief Clears the pending events specified in the events mask.
181 *
182 * @param[in] events the events to be cleared
183 * @return The mask of pending events that were cleared.
184 *
185 * @iclass
186 */
188 thread_t *currtp = chThdGetSelfX();
189 eventmask_t m;
190
192
193 m = currtp->epending & events;
194 currtp->epending &= ~events;
195
196 return m;
197}
198
199/**
200 * @brief Clears the pending events specified in the events mask.
201 *
202 * @param[in] events the events to be cleared
203 * @return The mask of pending events that were cleared.
204 *
205 * @api
206 */
208 eventmask_t m;
209
210 chSysLock();
211 m = chEvtGetAndClearEventsI(events);
212 chSysUnlock();
213
214 return m;
215}
216
217/**
218 * @brief Adds (OR) a set of events to the current thread, this is
219 * @b much faster than using @p chEvtBroadcast() or @p chEvtSignal().
220 *
221 * @param[in] events the events to be added
222 * @return The mask of currently pending events.
223 *
224 * @api
225 */
227 eventmask_t newevt;
228
229 chSysLock();
230 newevt = chEvtAddEventsI(events);
231 chSysUnlock();
232
233 return newevt;
234}
235
236/**
237 * @brief Returns the unmasked flags associated to an @p event_listener_t.
238 * @details The flags are returned and the @p event_listener_t flags mask is
239 * cleared.
240 *
241 * @param[in] elp pointer to the @p event_listener_t structure
242 * @return The flags added to the listener by the associated
243 * event source.
244 *
245 * @iclass
246 */
248 eventflags_t flags;
249
251 chDbgCheck(elp != NULL);
252
253 flags = elp->flags;
254 elp->flags = (eventflags_t)0;
255
256 return flags & elp->wflags;
257}
258
259/**
260 * @brief Returns the flags associated to an @p event_listener_t.
261 * @details The flags are returned and the @p event_listener_t flags mask is
262 * cleared.
263 *
264 * @param[in] elp pointer to the @p event_listener_t structure
265 * @return The flags added to the listener by the associated
266 * event source.
267 *
268 * @api
269 */
271 eventflags_t flags;
272
273 chDbgCheck(elp != NULL);
274
275 chSysLock();
276 flags = elp->flags;
277 elp->flags = (eventflags_t)0;
278 chSysUnlock();
279
280 return flags & elp->wflags;
281}
282
283/**
284 * @brief Adds a set of event flags directly to the specified @p thread_t.
285 * @post This function does not reschedule so a call to a rescheduling
286 * function must be performed before unlocking the kernel. Note that
287 * interrupt handlers always reschedule on exit so an explicit
288 * reschedule must not be performed in ISRs.
289 *
290 * @param[in] tp the thread to be signaled
291 * @param[in] events the events set to be ORed
292 *
293 * @iclass
294 */
296
298 chDbgCheck(tp != NULL);
299
300 tp->epending |= events;
301 /* Test on the AND/OR conditions wait states.*/
302 if (((tp->state == CH_STATE_WTOREVT) &&
303 ((tp->epending & tp->u.ewmask) != (eventmask_t)0)) ||
304 ((tp->state == CH_STATE_WTANDEVT) &&
305 ((tp->epending & tp->u.ewmask) == tp->u.ewmask))) {
306 tp->u.rdymsg = MSG_OK;
307 (void) chSchReadyI(tp);
308 }
309}
310
311/**
312 * @brief Adds a set of event flags directly to the specified @p thread_t.
313 *
314 * @param[in] tp the thread to be signaled
315 * @param[in] events the events set to be ORed
316 *
317 * @api
318 */
320
321 chDbgCheck(tp != NULL);
322
323 chSysLock();
324 chEvtSignalI(tp, events);
326 chSysUnlock();
327}
328
329/**
330 * @brief Signals all the Event Listeners registered on the specified Event
331 * Source.
332 * @details This function variants ORs the specified event flags to all the
333 * threads registered on the @p event_source_t in addition to the
334 * event flags specified by the threads themselves in the
335 * @p event_listener_t objects.
336 * @post This function does not reschedule so a call to a rescheduling
337 * function must be performed before unlocking the kernel. Note that
338 * interrupt handlers always reschedule on exit so an explicit
339 * reschedule must not be performed in ISRs.
340 *
341 * @param[in] esp pointer to the @p event_source_t structure
342 * @param[in] flags the flags set to be added to the listener flags mask
343 *
344 * @iclass
345 */
347 event_listener_t *elp;
348
350 chDbgCheck(esp != NULL);
351
352 elp = esp->next;
353 /*lint -save -e9087 -e740 [11.3, 1.3] Cast required by list handling.*/
354 while (elp != (event_listener_t *)esp) {
355 /*lint -restore*/
356 elp->flags |= flags;
357 /* When flags == 0 the thread will always be signaled because the
358 source does not emit any flag.*/
359 if ((flags == (eventflags_t)0) ||
360 ((flags & elp->wflags) != (eventflags_t)0)) {
361 chEvtSignalI(elp->listener, elp->events);
362 }
363 elp = elp->next;
364 }
365}
366
367/**
368 * @brief Signals all the Event Listeners registered on the specified Event
369 * Source.
370 * @details This function variants ORs the specified event flags to all the
371 * threads registered on the @p event_source_t in addition to the
372 * event flags specified by the threads themselves in the
373 * @p event_listener_t objects.
374 *
375 * @param[in] esp pointer to the @p event_source_t structure
376 * @param[in] flags the flags set to be added to the listener flags mask
377 *
378 * @api
379 */
381
382 chSysLock();
383 chEvtBroadcastFlagsI(esp, flags);
385 chSysUnlock();
386}
387
388/**
389 * @brief Invokes the event handlers associated to an event flags mask.
390 *
391 * @param[in] events mask of events to be dispatched
392 * @param[in] handlers an array of @p evhandler_t. The array must have size
393 * equal to the number of bits in eventmask_t.
394 *
395 * @api
396 */
397void chEvtDispatch(const evhandler_t *handlers, eventmask_t events) {
398 eventid_t eid;
399
400 chDbgCheck(handlers != NULL);
401
402 eid = (eventid_t)0;
403 while (events != (eventmask_t)0) {
404 if ((events & EVENT_MASK(eid)) != (eventmask_t)0) {
405 chDbgAssert(handlers[eid] != NULL, "null handler");
406 events &= ~EVENT_MASK(eid);
407 handlers[eid](eid);
408 }
409 eid++;
410 }
411}
412
413#if (CH_CFG_OPTIMIZE_SPEED == TRUE) || \
414 (CH_CFG_USE_EVENTS_TIMEOUT == FALSE) || \
415 defined(__DOXYGEN__)
416/**
417 * @brief Waits for exactly one of the specified events.
418 * @details The function waits for one event among those specified in
419 * @p events to become pending then the event is cleared and returned.
420 * @note One and only one event is served in the function, the one with the
421 * lowest event id. The function is meant to be invoked into a loop in
422 * order to serve all the pending events.<br>
423 * This means that Event Listeners with a lower event identifier have
424 * an higher priority.
425 *
426 * @param[in] events events that the function should wait
427 * for, @p ALL_EVENTS enables all the events
428 * @return The mask of the lowest event id served and cleared.
429 *
430 * @api
431 */
433 thread_t *currtp = chThdGetSelfX();
434 eventmask_t m;
435
436 chSysLock();
437 m = currtp->epending & events;
438 if (m == (eventmask_t)0) {
439 currtp->u.ewmask = events;
441 m = currtp->epending & events;
442 }
443 m ^= m & (m - (eventmask_t)1);
444 currtp->epending &= ~m;
445 chSysUnlock();
446
447 return m;
448}
449
450/**
451 * @brief Waits for any of the specified events.
452 * @details The function waits for any event among those specified in
453 * @p events to become pending then the events are cleared and
454 * returned.
455 *
456 * @param[in] events events that the function should wait
457 * for, @p ALL_EVENTS enables all the events
458 * @return The mask of the served and cleared events.
459 *
460 * @api
461 */
463 thread_t *currtp = chThdGetSelfX();
464 eventmask_t m;
465
466 chSysLock();
467 m = currtp->epending & events;
468 if (m == (eventmask_t)0) {
469 currtp->u.ewmask = events;
471 m = currtp->epending & events;
472 }
473 currtp->epending &= ~m;
474 chSysUnlock();
475
476 return m;
477}
478
479/**
480 * @brief Waits for all the specified events.
481 * @details The function waits for all the events specified in @p events to
482 * become pending then the events are cleared and returned.
483 *
484 * @param[in] events events that the function should wait
485 * for, @p ALL_EVENTS requires all the events
486 * @return The mask of the served and cleared events.
487 *
488 * @api
489 */
491 thread_t *currtp = chThdGetSelfX();
492
493 chSysLock();
494 if ((currtp->epending & events) != events) {
495 currtp->u.ewmask = events;
497 }
498 currtp->epending &= ~events;
499 chSysUnlock();
500
501 return events;
502}
503#endif /* CH_CFG_OPTIMIZE_SPEED || !CH_CFG_USE_EVENTS_TIMEOUT */
504
505#if (CH_CFG_USE_EVENTS_TIMEOUT == TRUE) || defined(__DOXYGEN__)
506/**
507 * @brief Waits for exactly one of the specified events.
508 * @details The function waits for one event among those specified in
509 * @p events to become pending then the event is cleared and returned.
510 * @note One and only one event is served in the function, the one with the
511 * lowest event id. The function is meant to be invoked into a loop
512 * in order to serve all the pending events.<br>
513 * This means that Event Listeners with a lower event identifier have
514 * an higher priority.
515 *
516 * @param[in] events events that the function should wait
517 * for, @p ALL_EVENTS enables all the events
518 * @param[in] timeout the number of ticks before the operation timeouts,
519 * the following special values are allowed:
520 * - @a TIME_IMMEDIATE immediate timeout.
521 * - @a TIME_INFINITE no timeout.
522 * .
523 * @return The mask of the lowest event id served and cleared.
524 * @retval 0 if the operation has timed out.
525 *
526 * @api
527 */
529 thread_t *currtp = chThdGetSelfX();
530 eventmask_t m;
531
532 chSysLock();
533 m = currtp->epending & events;
534 if (m == (eventmask_t)0) {
535 if (TIME_IMMEDIATE == timeout) {
536 chSysUnlock();
537 return (eventmask_t)0;
538 }
539 currtp->u.ewmask = events;
541 chSysUnlock();
542 return (eventmask_t)0;
543 }
544 m = currtp->epending & events;
545 }
546 m ^= m & (m - (eventmask_t)1);
547 currtp->epending &= ~m;
548 chSysUnlock();
549
550 return m;
551}
552
553/**
554 * @brief Waits for any of the specified events.
555 * @details The function waits for any event among those specified in
556 * @p events to become pending then the events are cleared and
557 * returned.
558 *
559 * @param[in] events events that the function should wait
560 * for, @p ALL_EVENTS enables all the events
561 * @param[in] timeout the number of ticks before the operation timeouts,
562 * the following special values are allowed:
563 * - @a TIME_IMMEDIATE immediate timeout.
564 * - @a TIME_INFINITE no timeout.
565 * .
566 * @return The mask of the served and cleared events.
567 * @retval 0 if the operation has timed out.
568 *
569 * @api
570 */
572 thread_t *currtp = chThdGetSelfX();
573 eventmask_t m;
574
575 chSysLock();
576 m = currtp->epending & events;
577 if (m == (eventmask_t)0) {
578 if (TIME_IMMEDIATE == timeout) {
579 chSysUnlock();
580 return (eventmask_t)0;
581 }
582 currtp->u.ewmask = events;
584 chSysUnlock();
585 return (eventmask_t)0;
586 }
587 m = currtp->epending & events;
588 }
589 currtp->epending &= ~m;
590 chSysUnlock();
591
592 return m;
593}
594
595/**
596 * @brief Waits for all the specified events.
597 * @details The function waits for all the events specified in @p events to
598 * become pending then the events are cleared and returned.
599 *
600 * @param[in] events events that the function should wait
601 * for, @p ALL_EVENTS requires all the events
602 * @param[in] timeout the number of ticks before the operation timeouts,
603 * the following special values are allowed:
604 * - @a TIME_IMMEDIATE immediate timeout.
605 * - @a TIME_INFINITE no timeout.
606 * .
607 * @return The mask of the served and cleared events.
608 * @retval 0 if the operation has timed out.
609 *
610 * @api
611 */
613 thread_t *currtp = chThdGetSelfX();
614
615 chSysLock();
616 if ((currtp->epending & events) != events) {
617 if (TIME_IMMEDIATE == timeout) {
618 chSysUnlock();
619 return (eventmask_t)0;
620 }
621 currtp->u.ewmask = events;
623 chSysUnlock();
624 return (eventmask_t)0;
625 }
626 }
627 currtp->epending &= ~events;
628 chSysUnlock();
629
630 return events;
631}
632#endif /* CH_CFG_USE_EVENTS_TIMEOUT == TRUE */
633
634#endif /* CH_CFG_USE_EVENTS == TRUE */
635
636/** @} */
ChibiOS/RT main include file.
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:144
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:118
#define chDbgCheckClassI()
Definition chdebug.h:99
void(* evhandler_t)(eventid_t id)
Event Handler callback function.
Definition chevents.h:83
void chEvtSignalI(thread_t *tp, eventmask_t events)
Adds a set of event flags directly to the specified thread_t.
Definition chevents.c:295
struct event_source event_source_t
Event Source structure.
void chEvtRegisterMaskWithFlagsI(event_source_t *esp, event_listener_t *elp, eventmask_t events, eventflags_t wflags)
Registers an Event Listener on an Event Source.
Definition chevents.c:103
void chEvtUnregister(event_source_t *esp, event_listener_t *elp)
Unregisters an Event Listener from its Event Source.
Definition chevents.c:158
void chEvtSignal(thread_t *tp, eventmask_t events)
Adds a set of event flags directly to the specified thread_t.
Definition chevents.c:319
eventmask_t chEvtWaitAllTimeout(eventmask_t events, sysinterval_t timeout)
Waits for all the specified events.
Definition chevents.c:612
void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags)
Signals all the Event Listeners registered on the specified Event Source.
Definition chevents.c:346
#define chEvtWaitOne(mask)
Definition chevents.h:157
eventmask_t chEvtGetAndClearEvents(eventmask_t events)
Clears the pending events specified in the events mask.
Definition chevents.c:207
static eventmask_t chEvtAddEventsI(eventmask_t events)
Adds (OR) a set of events to the current thread, this is much faster than using chEvtBroadcast() or c...
Definition chevents.h:273
eventmask_t chEvtWaitOneTimeout(eventmask_t events, sysinterval_t timeout)
Waits for exactly one of the specified events.
Definition chevents.c:528
eventmask_t chEvtWaitAnyTimeout(eventmask_t events, sysinterval_t timeout)
Waits for any of the specified events.
Definition chevents.c:571
eventflags_t chEvtGetAndClearFlags(event_listener_t *elp)
Returns the flags associated to an event_listener_t.
Definition chevents.c:270
#define EVENT_MASK(eid)
Returns an event mask from an event identifier.
Definition chevents.h:97
struct event_listener event_listener_t
Definition chevents.h:52
void chEvtDispatch(const evhandler_t *handlers, eventmask_t events)
Invokes the event handlers associated to an event flags mask.
Definition chevents.c:397
eventmask_t chEvtGetAndClearEventsI(eventmask_t events)
Clears the pending events specified in the events mask.
Definition chevents.c:187
void chEvtRegisterMaskWithFlags(event_source_t *esp, event_listener_t *elp, eventmask_t events, eventflags_t wflags)
Registers an Event Listener on an Event Source.
Definition chevents.c:135
eventmask_t chEvtAddEvents(eventmask_t events)
Adds (OR) a set of events to the current thread, this is much faster than using chEvtBroadcast() or c...
Definition chevents.c:226
void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags)
Signals all the Event Listeners registered on the specified Event Source.
Definition chevents.c:380
eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp)
Returns the unmasked flags associated to an event_listener_t.
Definition chevents.c:247
#define chEvtWaitAll(mask)
Definition chevents.h:159
#define chEvtWaitAny(mask)
Definition chevents.h:158
uint32_t eventflags_t
Definition chearly.h:91
uint32_t eventmask_t
Definition chearly.h:90
int32_t eventid_t
Definition chearly.h:89
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:133
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition chschd.c:458
#define MSG_OK
Normal wakeup message.
Definition chschd.h:39
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition chschd.c:280
void chSchGoSleepS(tstate_t newstate)
Puts the current thread to sleep into the specified state.
Definition chschd.c:305
#define CH_STATE_WTOREVT
One event.
Definition chschd.h:73
#define CH_STATE_WTANDEVT
Several events.
Definition chschd.h:74
msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout)
Puts the current thread to sleep into the specified state with timeout specification.
Definition chschd.c:359
static void chSysLock(void)
Enters the kernel lock state.
Definition chsys.h:407
static void chSysUnlock(void)
Leaves the kernel lock state.
Definition chsys.h:421
static thread_t * chThdGetSelfX(void)
Returns a pointer to the current thread_t.
Definition chthreads.h:341
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition chtime.h:47
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:119
msg_t rdymsg
Thread wakeup code.
Definition chobjects.h:242
eventmask_t epending
Pending events mask.
Definition chobjects.h:313
tstate_t state
Current thread state.
Definition chobjects.h:206
eventmask_t ewmask
Enabled events mask.
Definition chobjects.h:294
union ch_thread::@250330312022121344252011223135034045240103044261 u
State-specific fields.
eventmask_t events
Events to be set in the listening thread.
Definition chevents.h:63
event_listener_t * next
Next Event Listener registered on the event source.
Definition chevents.h:58
eventflags_t wflags
Flags that this listener interested in.
Definition chevents.h:67
eventflags_t flags
Flags added to the listener by the event source.
Definition chevents.h:65
thread_t * listener
Thread interested in the event source.
Definition chevents.h:61
event_listener_t * next
First Event Listener registered on the Event Source.
Definition chevents.h:75