Commit graph

63 commits

Author SHA1 Message Date
Michal Sojka
7a1057604e uloop: Fix race condition in SIGCHLD handling
When uloop_process_add() is called outside of uloop_run(), i.e. not
from a callback (which is the case of at least utrace and ujail),
child events can be missed. The reason is that when SIGCHILD handler
is installed in uloop_run(), after the uloop_process_add() is called,
then an initial signal could be missed.

Commit 4e3a47a ("uloop: use a waker for notifying sigchld and loop
cancel events", 2016-06-09) solved a similar problem and introduced
uloop_init() but forgot to move a call to uloop_setup_signals() there.
This is what this commit does.

Now, uloop_process_add() can be called any time after uloop_init()
without missing any event.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
Acked-by: Yousong Zhou <yszhou4tech@gmail.com>
2017-09-15 15:39:42 +08:00
Felix Fietkau
fd57eea9f3 uloop: allow passing 0 as timeout to uloop_run
Useful for processing only immediate timers and fds

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2017-06-17 11:47:49 +02:00
Felix Fietkau
4bc3decf87 uloop: fix a regression in timeout handling
Variable confusion was breaking timers

Fixes: 368fd26458 ("uloop: allow specifying a timeout for uloop_run()")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2017-06-17 11:40:11 +02:00
Felix Fietkau
368fd26458 uloop: allow specifying a timeout for uloop_run()
This can be useful for cleanup with pending timers, or for hooking into
existing code that does not use uloop

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2017-06-01 11:24:44 +02:00
Felix Fietkau
de3f14b643 uloop: add uloop_cancelling function
Returns true if uloop_run is still running and uloop_cancelled is set

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2017-02-03 16:52:21 +01:00
Eyal Birger
d197c8ffa3 uloop: handle waker pipe write() return value
Recent glibc warns if result of read() or write() is unused.

Added a retry in case of EINTR, all other faults are silently discarded.

Signed-off-by: Eyal Birger <eyal.birger@gmail.com>

-----
- I was not able to reproduce the EINTR case, but it seems to be the right
  thing to do
- Retrying on EAGAIN in this case would be weird as there is no one to read
  from the other end of the pipe. We could call waker_consume() directly but
  since the size of the message is just one byte, I think this would be dead
  code
2016-06-26 13:05:54 +02:00
Matthias Schiffer
1ad3d93eb8 loop: make uloop_run() return the cancelling signal
When a process quits in response to a signal it handles, it should to so
be re-sending the signal to itself. This especially important for SIGINT,
as is explained in [1].

uloop currently hides the reason for quitting uloop_run(). Fix this by
returning the signal that caused the loop to quit (or 0 when uloop_end()
was used), so a program using loop an comply with [1].

[1] https://www.cons.org/cracauer/sigint.html

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
2016-06-26 12:55:31 +02:00
Felix Fietkau
c2f2c47f3e uloop: add missing waker_pipe initialization
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-06-15 15:14:51 +02:00
Yousong Zhou
4e3a47a4cb uloop: use a waker for notifying sigchld and loop cancel events
Fix a race condition when do_sigchld, uloop_cancelled were set just
before epoll_wait(timeout=-1), resulting the loop stuck in the syscall
without noticing the events just happened

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-06-15 11:54:37 +02:00
Felix Fietkau
1257a38a6e uloop: revert signalfd support for now
It hasn't fixed the reported race condition and it introduced some new
issues.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-05-19 10:59:48 +02:00
Felix Fietkau
93be9309b8 uloop: add back support for overriding signal handlers when signalfd is in use
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-05-17 13:59:05 +02:00
Felix Fietkau
b06cd8c58e uloop: retry waitpid on signal interrupt
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-05-17 13:27:44 +02:00
Felix Fietkau
6a75b3b643 uloop: try to use signalfd for signal handling if available
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-05-17 13:23:38 +02:00
Felix Fietkau
8ae74b4378 uloop: move epoll code into a separate file
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-05-17 13:23:38 +02:00
Felix Fietkau
4b0aa9ccc2 uloop: move kqueue code into a separate file
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2016-05-17 13:23:38 +02:00
John Crispin
b8d9b382e3 allow process callback to call uloop_end()
Signed-off-by: John Crispin <blogic@openwrt.org>
2015-03-21 05:50:23 +01:00
Rafał Miłecki
827ad8337e uloop: ignore SIGPIPE by default
Most app don't want to crash because of unhandled SIGPIPE. It could
happen is such trivial situations like writing to socket.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
2015-01-28 10:51:15 +01:00
Yousong Zhou
08c27ceb01 uloop: optimize uloop_timeout_set() implementaiton a bit.
Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
2015-01-21 20:02:46 +01:00
Michel Stam
464e05e33b uloop: Do not override signal handlers not installed by us
Signed-off-by: Michel Stam <m.stam@fugro.nl>
2014-10-12 13:21:20 +02:00
Michel Stam
213122a083 uloop: Remove uloop_cancelled variable, it is not used anywhere
Signed-off-by: Michel Stam <m.stam@fugro.nl>
2014-10-12 13:21:17 +02:00
Luka Perkov
f32a53f92b uloop: fix multiple calls to uloop_run()
Signed-off-by: Luka Perkov <luka@openwrt.org>
2014-05-05 11:24:07 +02:00
Felix Fietkau
73a88451dd uloop: clear uloop_fd::error on add
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2014-04-26 16:55:17 +02:00
Karl Vogel
926121113b uloop: Add flag to allow callback to be called on error conditions.
In some conditions, an application is interested in errors happening
on a file descriptor and might be able to resolve the issue in the
callback function.

This patch adds a flag to notify the uloop framework that errors
should be passed to the callback function, instead of silently
removing the fd from the polling set.

Signed-off-by: Karl Vogel <karl.vogel@gmail.com>
2014-02-23 18:18:32 +01:00
Kristian Evensen
13a9b7c709 Restore signal handler after uloop_run()
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>
2013-10-22 17:26:05 +02:00
Felix Fietkau
04f194aa8a uloop: fix deleting pending fd events on uloop_fd_del
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>
2013-08-01 00:01:40 +02:00
Helmut Schaa
510e4956e5 uloop: Fix incorrect timeout
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>
2013-07-24 15:01:19 +02:00
Felix Fietkau
b9ebdbcc64 uloop: fix corner cases with recursive uloop_run calls
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>
2013-06-18 12:05:09 +02:00
Felix Fietkau
35cee2c206 uloop: fix event flags processing on mac os x
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-06-18 12:05:09 +02:00
Felix Fietkau
e386259632 libubox: make uloop_fd::flags generic
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-06-18 12:05:09 +02:00
Felix Fietkau
cd5238b500 uloop: fix edge trigger handling on mac os x
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-06-18 11:02:20 +02:00
Felix Fietkau
ae40b66130 uloop: rework event processing, fix use-after-free issues
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>
2013-06-11 12:55:21 +02:00
Felix Fietkau
766ff98050 uloop: remove file descriptors if neither read nor write notification is requested
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-31 16:43:08 +01:00
Jo-Philipp Wich
8b0d933154 uloop: rename uloop_timeout_pending() to uloop_timeout_remaining() 2013-01-23 19:33:12 +01:00
Jo-Philipp Wich
77984bd24d uloop: add uloop_timeout_pending() function to determine the remaining time of an active timeout 2013-01-23 19:32:45 +01:00
Felix Fietkau
569bc29c5a uloop: replace copyright info (code has been completely rewritten over time), relicense to ISC
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-13 09:47:51 +01:00
Felix Fietkau
dde64e47ca uloop: use clock_gettime with the monotonic clock instead of using gettimeofday()
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-06 03:04:04 +01:00
Felix Fietkau
b7930023ee uloop: add back state tracking on mac os x, it seems to work reliably now (after the other fixes)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-05 16:04:55 +01:00
Felix Fietkau
17f4e41ecb uloop: improve edge trigger reliability on mac os x
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>
2013-01-04 03:18:42 +01:00
Felix Fietkau
c2916d7bcc uloop: ensure SIGCHLD is properly received on mac os x
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-04 03:13:29 +01:00
Felix Fietkau
6a8df07590 uloop: do less state/change tracking for kevent() on mac os x, it is unreliable
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-04 01:15:48 +01:00
Felix Fietkau
e7825661a2 uloop: fix immediate timeout processing on mac os x
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2013-01-01 23:37:22 +01:00
Felix Fietkau
9c8ab5d64c utils: move ARRAY_SIZE from uloop to utils.h
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2012-12-31 15:24:27 +01:00
Felix Fietkau
407f7a0bb3 uloop: fix tv_diff() calculation
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2012-10-31 20:28:15 +01:00
Felix Fietkau
0385cbc068 uloop: another timer fix
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
2012-10-31 20:09:47 +01:00
Felix Fietkau
33b9f3aa0b uloop: fix sub-second timer offsets for uloop_timeout_set 2012-10-31 20:03:45 +01:00
Felix Fietkau
6e7e8a1a91 uloop: fix a segfault on deleting the first active timer from within another timer 2012-10-23 03:41:45 +02:00
Felix Fietkau
e3efdcfe15 uloop: fix event delete races on mac os x 2012-10-21 03:40:35 +02:00
Felix Fietkau
cca2ed6c8c uloop: clear processes and timeouts on uloop_done() 2012-07-08 22:27:40 +02:00
Jo-Philipp Wich
0001d8ab26 uloop: handle EPOLLHUP like EPOLLERR to prevent infinite tight loops between epoll_wait() and the continue in uloop_run_events() 2012-07-07 18:17:40 +02:00
Felix Fietkau
63bc6593c3 uloop: prevent fd callbacks for unregistered fds by ensuring that pointers in the epoll array are cleared 2012-06-24 21:06:16 +02:00