diff --git a/repos/dde_linux/src/lib/lxip/timer_handler.cc b/repos/dde_linux/src/lib/lxip/timer_handler.cc index 8cd83ce30e..76f3384af5 100644 --- a/repos/dde_linux/src/lib/lxip/timer_handler.cc +++ b/repos/dde_linux/src/lib/lxip/timer_handler.cc @@ -306,10 +306,20 @@ class Lx::Timer void wait(unsigned long timeo = 0) { + /** + * XXX + * in contrast to wait_uninterruptible(), wait() should be interruptible + * although we return immediately once we dispatched any signal, we + * need to reflect this via signal_pending() + */ + if (timeo > 0) _wait_one_shot.schedule(Genode::Microseconds(jiffies_to_usecs(timeo))); _ep.wait_and_dispatch_one_io_signal(); + /* update jiffies if we dispatched another signal */ + if (_wait_one_shot.scheduled()) + update_jiffies(); } void wait_uninterruptible(unsigned long timeo) @@ -400,9 +410,24 @@ signed long schedule_timeout(signed long timeout) { unsigned long expire = timeout + jiffies; + /** + * XXX + * schedule_timeout is called from sock_wait_for_wmem() (UDP) and + * sk_stream_wait_memory() (TCP) if sk_wmem_alloc (UDP) resp. + * sk_wmem_queued (TCP) reaches are certain threshold + * unfortunately, recovery from this state seems to be broken + * so that we land here for every skb once we hit the threshold + */ + static bool warned = false; + if (!warned) { + Genode::warning(__func__, " called (tx throttled?)"); + warned = true; + } + long start = jiffies; _timer->wait(timeout); timeout -= jiffies - start; + return timeout < 0 ? 0 : timeout; }