Lines Matching +full:include +full:- +full:all +full:- +full:sources
13 * next paragraph) shall be included in all copies or substantial
26 #include <assert.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <errno.h>
30 #include <signal.h>
31 #include <stdlib.h>
32 #include <stdint.h>
33 #include <stdbool.h>
34 #include <string.h>
35 #include <fcntl.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <sys/epoll.h>
39 #include <sys/signalfd.h>
40 #include <sys/timerfd.h>
41 #include <unistd.h>
42 #include "wayland-util.h"
43 #include "wayland-private.h"
44 #include "wayland-server-core.h"
45 #include "wayland-os.h"
49 #define TIMER_REMOVED -2
65 /* pointers to the user-visible event sources */
103 if (ep->events & EPOLLIN) in wl_event_source_fd_dispatch()
105 if (ep->events & EPOLLOUT) in wl_event_source_fd_dispatch()
107 if (ep->events & EPOLLHUP) in wl_event_source_fd_dispatch()
109 if (ep->events & EPOLLERR) in wl_event_source_fd_dispatch()
112 return fd_source->func(fd_source->fd, mask, source->data); in wl_event_source_fd_dispatch()
125 if (source->fd < 0) { in add_source()
130 source->loop = loop; in add_source()
131 source->data = data; in add_source()
132 wl_list_init(&source->link); in add_source()
141 if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, source->fd, &ep) < 0) { in add_source()
142 close(source->fd); in add_source()
154 * \param mask A bitwise-or of which events to watch for: \c WL_EVENT_READABLE,
165 * it may be necessary to register the file descriptor source to be re-checked,
169 * buffer incoming data, possibly as a side-effect of other operations.
186 source->base.interface = &fd_source_interface; in wl_event_loop_add_fd()
187 source->base.fd = wl_os_dupfd_cloexec(fd, 0); in wl_event_loop_add_fd()
188 source->func = func; in wl_event_loop_add_fd()
189 source->fd = fd; in wl_event_loop_add_fd()
191 return add_source(loop, &source->base, mask, data); in wl_event_loop_add_fd()
197 * \param mask The new mask, a bitwise-or of: \c WL_EVENT_READABLE,
199 * \return 0 on success, -1 on failure.
207 * a dispatch callback when it is possible to write more. Once all data has
209 * busy-looping on dispatch.
217 struct wl_event_loop *loop = source->loop; in wl_event_source_fd_update()
227 return epoll_ctl(loop->epoll_fd, EPOLL_CTL_MOD, source->fd, &ep); in wl_event_source_fd_update()
284 timers->base.fd = -1; in wl_timer_heap_init()
285 timers->base.data = NULL; in wl_timer_heap_init()
286 wl_list_init(&timers->base.link); in wl_timer_heap_init()
287 timers->base.interface = &timer_heap_source_interface; in wl_timer_heap_init()
288 timers->base.loop = loop; in wl_timer_heap_init()
290 loop->timers.data = NULL; in wl_timer_heap_init()
291 loop->timers.active = 0; in wl_timer_heap_init()
292 loop->timers.space = 0; in wl_timer_heap_init()
293 loop->timers.count = 0; in wl_timer_heap_init()
299 if (timers->base.fd != -1) { in wl_timer_heap_release()
300 close(timers->base.fd); in wl_timer_heap_release()
302 free(timers->data); in wl_timer_heap_release()
311 if (timers->base.fd != -1) in wl_timer_heap_ensure_timerfd()
321 return -1; in wl_timer_heap_ensure_timerfd()
323 if (epoll_ctl(timers->base.loop->epoll_fd, in wl_timer_heap_ensure_timerfd()
326 return -1; in wl_timer_heap_ensure_timerfd()
329 timers->base.fd = timer_fd; in wl_timer_heap_ensure_timerfd()
339 if (timers->count + 1 > timers->space) { in wl_timer_heap_reserve()
340 new_space = timers->space >= 8 ? timers->space * 2 : 8; in wl_timer_heap_reserve()
341 n = realloc(timers->data, (size_t)new_space * sizeof(*n)); in wl_timer_heap_reserve()
344 return -1; in wl_timer_heap_reserve()
346 timers->data = n; in wl_timer_heap_reserve()
347 timers->space = new_space; in wl_timer_heap_reserve()
350 timers->count++; in wl_timer_heap_reserve()
359 timers->count--; in wl_timer_heap_unreserve()
361 if (timers->space >= 16 && timers->space >= 4 * timers->count) { in wl_timer_heap_unreserve()
362 n = realloc(timers->data, (size_t)timers->space / 2 * sizeof(*n)); in wl_timer_heap_unreserve()
367 timers->data = n; in wl_timer_heap_unreserve()
368 timers->space = timers->space / 2; in wl_timer_heap_unreserve()
379 tmp = a->heap_idx; in heap_set()
380 a->heap_idx = idx; in heap_set()
381 data[a->heap_idx] = a; in heap_set()
395 cursor_idx = source->heap_idx; in heap_sift_down()
396 key = source->deadline; in heap_sift_down()
407 if (time_lt(other_child->deadline, child->deadline)) in heap_sift_down()
411 if (time_lt(child->deadline, key)) in heap_sift_down()
427 cursor_idx = source->heap_idx; in heap_sift_up()
428 key = source->deadline; in heap_sift_up()
431 data[(cursor_idx - 1) / 2]; in heap_sift_up()
433 if (time_lt(key, parent->deadline)) in heap_sift_up()
449 assert(source->heap_idx >= 0); in wl_timer_heap_disarm()
451 old_source_idx = source->heap_idx; in wl_timer_heap_disarm()
452 source->heap_idx = -1; in wl_timer_heap_disarm()
453 source->deadline.tv_sec = 0; in wl_timer_heap_disarm()
454 source->deadline.tv_nsec = 0; in wl_timer_heap_disarm()
456 last_end_evt = timers->data[timers->active - 1]; in wl_timer_heap_disarm()
457 timers->data[timers->active - 1] = NULL; in wl_timer_heap_disarm()
458 timers->active--; in wl_timer_heap_disarm()
460 if (old_source_idx == timers->active) in wl_timer_heap_disarm()
463 timers->data[old_source_idx] = last_end_evt; in wl_timer_heap_disarm()
464 last_end_evt->heap_idx = old_source_idx; in wl_timer_heap_disarm()
467 * Only one of sift-down and sift-up will have any effect */ in wl_timer_heap_disarm()
468 heap_sift_down(timers->data, timers->active, last_end_evt); in wl_timer_heap_disarm()
469 heap_sift_up(timers->data, last_end_evt); in wl_timer_heap_disarm()
478 assert(source->heap_idx == -1); in wl_timer_heap_arm()
480 source->deadline = deadline; in wl_timer_heap_arm()
481 timers->data[timers->active] = source; in wl_timer_heap_arm()
482 source->heap_idx = timers->active; in wl_timer_heap_arm()
483 timers->active++; in wl_timer_heap_arm()
484 heap_sift_up(timers->data, source); in wl_timer_heap_arm()
497 while (timers->active > 0) { in wl_timer_heap_dispatch()
498 root = timers->data[0]; in wl_timer_heap_dispatch()
499 if (time_lt(now, root->deadline)) in wl_timer_heap_dispatch()
507 list_tail->next_due = root; in wl_timer_heap_dispatch()
511 list_tail->next_due = NULL; in wl_timer_heap_dispatch()
513 if (timers->active > 0) { in wl_timer_heap_dispatch()
514 if (set_timer(timers->base.fd, timers->data[0]->deadline) < 0) in wl_timer_heap_dispatch()
515 return -1; in wl_timer_heap_dispatch()
517 if (clear_timer(timers->base.fd) < 0) in wl_timer_heap_dispatch()
518 return -1; in wl_timer_heap_dispatch()
524 for (; list_cursor; list_cursor = list_cursor->next_due) { in wl_timer_heap_dispatch()
525 if (list_cursor->base.fd != TIMER_REMOVED) in wl_timer_heap_dispatch()
526 list_cursor->func(list_cursor->base.data); in wl_timer_heap_dispatch()
539 return timer->func(timer->base.data); in wl_event_source_timer_dispatch()
568 if (wl_timer_heap_ensure_timerfd(&loop->timers) < 0) in wl_event_loop_add_timer()
575 source->base.interface = &timer_source_interface; in wl_event_loop_add_timer()
576 source->base.fd = -1; in wl_event_loop_add_timer()
577 source->func = func; in wl_event_loop_add_timer()
578 source->base.loop = loop; in wl_event_loop_add_timer()
579 source->base.data = data; in wl_event_loop_add_timer()
580 wl_list_init(&source->base.link); in wl_event_loop_add_timer()
581 source->next_due = NULL; in wl_event_loop_add_timer()
582 source->deadline.tv_sec = 0; in wl_event_loop_add_timer()
583 source->deadline.tv_nsec = 0; in wl_event_loop_add_timer()
584 source->heap_idx = -1; in wl_event_loop_add_timer()
586 if (wl_timer_heap_reserve(&loop->timers) < 0) { in wl_event_loop_add_timer()
591 return &source->base; in wl_event_loop_add_timer()
598 * \return 0 on success, -1 on failure.
602 * If the timeout is non-zero, the timer is set to expire after the given
615 struct wl_timer_heap *timers = &tsource->base.loop->timers; in wl_event_source_timer_update()
625 deadline.tv_nsec -= 1000000000L; in wl_event_source_timer_update()
629 if (tsource->heap_idx == -1) { in wl_event_source_timer_update()
631 } else if (time_lt(deadline, tsource->deadline)) { in wl_event_source_timer_update()
632 tsource->deadline = deadline; in wl_event_source_timer_update()
633 heap_sift_up(timers->data, tsource); in wl_event_source_timer_update()
635 tsource->deadline = deadline; in wl_event_source_timer_update()
636 heap_sift_down(timers->data, timers->active, tsource); in wl_event_source_timer_update()
639 if (tsource->heap_idx == 0) { in wl_event_source_timer_update()
642 if (set_timer(timers->base.fd, deadline) < 0) in wl_event_source_timer_update()
643 return -1; in wl_event_source_timer_update()
646 if (tsource->heap_idx == -1) in wl_event_source_timer_update()
650 if (timers->active == 0) { in wl_event_source_timer_update()
653 if (clear_timer(timers->base.fd) < 0) in wl_event_source_timer_update()
654 return -1; in wl_event_source_timer_update()
680 len = read(source->fd, &signal_info, sizeof signal_info); in wl_event_source_signal_dispatch()
681 if (!(len == -1 && errno == EAGAIN) && len != sizeof signal_info) in wl_event_source_signal_dispatch()
685 return signal_source->func(signal_source->signal_number, in wl_event_source_signal_dispatch()
686 signal_source->base.data); in wl_event_source_signal_dispatch()
706 * It is the caller's responsibility to ensure that all other threads have
725 source->base.interface = &signal_source_interface; in wl_event_loop_add_signal()
726 source->signal_number = signal_number; in wl_event_loop_add_signal()
730 source->base.fd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); in wl_event_loop_add_signal()
733 source->func = func; in wl_event_loop_add_signal()
735 return add_source(loop, &source->base, WL_EVENT_READABLE, data); in wl_event_loop_add_signal()
782 source->base.interface = &idle_source_interface; in wl_event_loop_add_idle()
783 source->base.loop = loop; in wl_event_loop_add_idle()
784 source->base.fd = -1; in wl_event_loop_add_idle()
786 source->func = func; in wl_event_loop_add_idle()
787 source->base.data = data; in wl_event_loop_add_idle()
789 wl_list_insert(loop->idle_list.prev, &source->base.link); in wl_event_loop_add_idle()
791 return &source->base; in wl_event_loop_add_idle()
794 /** Mark event source to be re-checked
796 * \param source The event source to be re-checked.
798 * This function permanently marks the event source to be re-checked after
799 * the normal dispatch of sources in wl_event_loop_dispatch(). Re-checking
800 * will keep iterating over all such event sources until the dispatch
801 * function for them all returns zero.
803 * Re-checking is used on sources that may become ready to dispatch as a
804 * side-effect of dispatching themselves or other event sources, including idle
805 * sources. Re-checking ensures all the incoming events have been fully drained
813 wl_list_insert(source->loop->check_list.prev, &source->link); in wl_event_source_check()
831 struct wl_event_loop *loop = source->loop; in wl_event_source_remove()
835 if (source->fd >= 0) { in wl_event_source_remove()
836 epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL); in wl_event_source_remove()
837 close(source->fd); in wl_event_source_remove()
838 source->fd = -1; in wl_event_source_remove()
841 if (source->interface == &timer_source_interface && in wl_event_source_remove()
842 source->fd != TIMER_REMOVED) { in wl_event_source_remove()
846 wl_timer_heap_unreserve(&loop->timers); in wl_event_source_remove()
849 source->fd = TIMER_REMOVED; in wl_event_source_remove()
852 wl_list_remove(&source->link); in wl_event_source_remove()
853 wl_list_insert(&loop->destroy_list, &source->link); in wl_event_source_remove()
863 wl_list_for_each_safe(source, next, &loop->destroy_list, link) in wl_event_loop_process_destroy_list()
866 wl_list_init(&loop->destroy_list); in wl_event_loop_process_destroy_list()
874 * Event sources need to be explicitly added to it.
892 loop->epoll_fd = wl_os_epoll_create_cloexec(); in wl_event_loop_create()
893 if (loop->epoll_fd < 0) { in wl_event_loop_create()
897 wl_list_init(&loop->check_list); in wl_event_loop_create()
898 wl_list_init(&loop->idle_list); in wl_event_loop_create()
899 wl_list_init(&loop->destroy_list); in wl_event_loop_create()
901 wl_signal_init(&loop->destroy_signal); in wl_event_loop_create()
903 wl_timer_heap_init(&loop->timers, loop); in wl_event_loop_create()
915 * If the event loop has existing sources, those cannot be safely removed
916 * afterwards. Therefore one must call wl_event_source_remove() on all
917 * event sources before destroying the event loop context.
924 wl_signal_emit(&loop->destroy_signal, loop); in wl_event_loop_destroy()
927 wl_timer_heap_release(&loop->timers); in wl_event_loop_destroy()
928 close(loop->epoll_fd); in wl_event_loop_destroy()
940 wl_list_for_each_safe(source, next, &loop->check_list, link) { in post_dispatch_check()
943 dispatch_result = source->interface->dispatch(source, &ep); in post_dispatch_check()
946 wl_log("This would previously accidentally suppress a follow-up dispatch"); in post_dispatch_check()
954 /** Dispatch the idle sources
956 * \param loop The event loop whose idle sources are dispatched.
966 while (!wl_list_empty(&loop->idle_list)) { in wl_event_loop_dispatch_idle()
967 source = wl_container_of(loop->idle_list.next, in wl_event_loop_dispatch_idle()
969 source->func(source->base.data); in wl_event_loop_dispatch_idle()
970 wl_event_source_remove(&source->base); in wl_event_loop_dispatch_idle()
976 * \param loop The event loop whose sources to wait for.
978 * \return 0 for success, -1 for polling (or timer update) error.
980 * All the associated event sources are polled. This function blocks until
981 * any event source delivers an event (idle sources excluded), or the timeout
982 * expires. A timeout of -1 disables the timeout, causing the function to block
985 * All idle sources are dispatched before blocking. An idle source is destroyed
986 * when it is dispatched. After blocking, all other ready sources are
987 * dispatched. Then, idle sources are dispatched again, in case the dispatched
988 * events created idle sources. Finally, all sources marked with
990 * functions all return zero.
1004 count = epoll_wait(loop->epoll_fd, ep, ARRAY_LENGTH(ep), timeout); in wl_event_loop_dispatch()
1006 return -1; in wl_event_loop_dispatch()
1010 if (source == &loop->timers.base) in wl_event_loop_dispatch()
1015 /* Dispatch timer sources before non-timer sources, so that in wl_event_loop_dispatch()
1016 * the non-timer sources can not cancel (by calling in wl_event_loop_dispatch()
1018 * (Note that timer sources also can't cancel pending non-timer in wl_event_loop_dispatch()
1019 * sources, since epoll_wait has already been called) */ in wl_event_loop_dispatch()
1020 if (wl_timer_heap_dispatch(&loop->timers) < 0) in wl_event_loop_dispatch()
1021 return -1; in wl_event_loop_dispatch()
1026 if (source->fd != -1) in wl_event_loop_dispatch()
1027 source->interface->dispatch(source, &ep[i]); in wl_event_loop_dispatch()
1044 * This function returns the aggregate file descriptor, that represents all
1045 * the event sources (idle sources excluded) associated with the given event
1050 * wl_event_loop_dispatch() on the event loop context to dispatch all the
1058 return loop->epoll_fd; in wl_event_loop_get_fd()
1073 wl_signal_add(&loop->destroy_signal, listener); in wl_event_loop_add_destroy_listener()
1089 return wl_signal_get(&loop->destroy_signal, notify); in wl_event_loop_get_destroy_listener()