uloop_run calls uloop_setup_signals() to set up signal handling before the while
loop, but does not remove the signal handling after the loop has ended. This can
cause problems for for example applications using the ubus file descriptor in
their own event loops, and perhaps with their own signal handling.
This patch stores the signal handle that was in place when the initial
uloop_run() call was made, and restores the handle when this call returns.
For recursive calls, the signal handler is not updated.
One use-case I experienced was an application that subscribed to several ubus
objects and used the ubus file descriptor in its own event loop. Even though
ubus_register_subscriber() (which calls uloop_run()) had returned, the signal
handler was not removed. This caused SIGINT not to be caught by the application.
Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
When a fd gets deleted internally due to errors, fd->registered gets set
to false before events are moved to the staging array.
This leads to pending events not getting cleared properly when the fd
user finally calls uloop_fd_del.
Fix this by moving the check down and always checking for pending
events.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
uloop timeouts are calculated based on a time value that was fetched
before any callbacks were executed. Hence, the next timeout is off by
the time the callback execution took which can lead to strange side
effects.
Fix this by calculating the next timeout based on a fresh time value.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
With multiple recursive calls to uloop_run, the callback for the same fd
can be run multiple times from different levels in the stack.
Prevent this by tracking the stack of uloop_fd callbacks and buffering new
incoming events for fds already on the stack.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Recursive calls to uloop_run() need to process already fetched events
first, before running kqueue/epoll to get more.
The state of cur_fd/cur_nfds and the event list needs to be maintained
properly to prevent accidental running of events pointing at deleted
uloop_fd structs.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Sometimes after re-arming a fd, an initial event for reads is not generated,
even though there is data pending. Work around this by making the trigger
level-triggered first, then switching to edge trigger after processing the first
event.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>