[[!meta copyright="Copyright © 2012, 2013 Free Software Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled [[GNU Free Documentation License|/fdl]]."]]"""]] [[!meta title="alarm/setitimer"]] [[!tag open_issue_glibc open_issue_hurd]] `setitimer()`, called by `alarm()` when setting a new alarm, it is not able to disable on its own the timer when the alarm is fired the first time. On the other hand, manually invoking `alarm(0)` can cancel the running timer for `SIGALRM`. See also the attached file: on other OSes (e.g. Linux) it blocks waiting for a signal, while on GNU/Hurd it gets a new alarm and exits. [[alrm.c]] This issue was recently fixed (around January 2013). # IRC, freenode, #hurd, 2012-07-29 our setitimer is bugged it seems doesn't seem to leave a timer disarmed when the interval is set to 0 (which means a one shot timer is actually periodic ..) ## IRC, freenode, #hurd, 2012-12-26 youpi: tschwinge: the setitimer issue http://www.gnu.org/software/hurd/open_issues/alarm_setitimer.html) is because of the global preemptor installed by setitimer not being run when sigalrm is catched if anyone has a good definition for a preemptor, let us know (mine is currently "something that is scanned on signal delivery and can alter this delivery") I don't have any better definition braunr: ah, that explains indeed thanks i think i found the problem :) seems to be a minor overlook from drepper (or the real author if he was only the committer) hurd_preempt_signals augments _hurdsig_preempted_set with the signals from the installed preemptor but the inline version in setitimer doesn't and post_signal actually checks that the preemptor itself looks wrong, since its sigcode range is 0, 0 whereas SI_TIMER is used when raising SIGALRM ... ah but that's a recent change, right it came with "implement SA_SIGINFO signal handlers" (e19a2fad70b187e5efe79768f86a1f05cb5e0390, Tue Feb 21 02:41:18 2012) yes, fixed :) patch committed at http://git.savannah.gnu.org/cgit/hurd/glibc.git/log/?h=rbraun/setitimer_fix and pushed to the debian package ## IRC, freenode, #hurd, 2012-12-27 do we know any application that was broken because of setitimer ? braunr: bits in the python and perl test suites ok ## IRC, freenode, #hurd, 2012-12-28 braunr: ah, also libglib-perl's testsuite is affected by the alarm/setitimer issue pinotree: only tests ? :( braunr: yeah ok, we don't win that much on this fix, but anyway, still good to have but that source is pretty quick to compile and check braunr: eh, so far that's what i found myself ## IRC, freenode, #hurd, 2013-01-04 See also [[select]]. bummer, we have broken ghc completely with the latest glibc patches youpi: what do you mean? pinotree: it just hangs on installation ## IRC, freenode, #hurd, 2013-01-05 pinotree: it seems ghc was disturbed by the setitimer patch pinotree: http://paste.debian.net/221807/ pinotree: it seems to be simply due to nested locking of _hurd_siglock :/ pinotree: I wonder whether this code has ever been really tested oops braunr: my comments above were for you actually :) braunr: see the update I've just commited to the debian patch I've added a parameter to setitimer_locked, to know whether the lock is already taken or not that does fix ghc as well as the gdb ntpdate hang, apparently I can confirm that the single-select patch breaks ntpdate for some reason I wonder whether it could be due to port set behavior being different from single reply port I believe I understand what happens [[select_vs_signals]]. I'll rebuild ntpdate with a 1s timeout that'll at least fix that rah, no, doesn't work, it insists on getting its alarm Mmm, no, the __mach_msg call doesn't even return even though MACH_RCV_TIMEOUT is set, and to is 1000 youpi: i see gnu_srs: and you, see how youpi analysed and understood the problem, instead of just guessing :p youpi: it doesn't return ? iirc, the __mach_msg wrapper deals with the interruptible flag braunr: yes, __mach_msg deals with the interruptible flag by looping ! and the info page says it: if it's interrupted too often, it may just never return that's what actually happens here (ntpdate sets an itimer more often than every 1s) youpi: ew :) I'll test a bit more, and submit a patch youpi: otoh a _locker function usually means it expects a locked mutex ;) i also i wondered whether there could be a race in the settimer mini-thread, between its mach_msg and its reading of the interval pinotree: right, we could as well just lock anyway there could be indeed youpi: i don't know much about the internals of signal dispatching, but could it happen the following: in timer thread, mach_msg expires → sig_post_request → before the main thread receives/processes the signal, the timer thread iterates again on its while(1), using the same interval previously used ? did you check the comment above __msg_sig_post_request? ah ok I'm not sure how that works, but it's supposed to :) just wonder: wouldn't it be simplier if the logic to change the timeout would be in the timer thread, instead of relying on the main thread adjusting it? maybe there are some semantic details that wouldn't be right with such approach i see i guess so if the new interval is 0, the thread can be properly suspened (or killed, if the former fails) could be something like this, yes youpi: ah, wrt your comments of tonight: at least with the current setitimer patch (in -38), a simple alarm() test app works, and i saw few python tests can be reenabled now ok so even if not totally correct, at least it had some positive effects youpi: wrt the double lock issue of _hurd_siglock, what about using the "crit" parameter of setitimer_locked? it may have various values depending whether we're already in the critical section etc. restart_itimer does not take that lock, so we could check whether crit is null, and in that case not even bothering to check the signal preemptors, since it was called as a result of own setitimer thread? I'd rather avoid binding whether the mutex is held to whether the call is coming from the actual premptor again, crit may be null if we're already in the critical section when setitimer is called setitimer already does unclean things with preemptors not a good thing to add more :) fair enough, so a simple bool should do the job i mean, the whole thing is "cheezoid" :) it probably needs a rewrite some day so "in the meantime" (of years, i know) braunr: and temporary, too but a bool is fine too, sure :)