Ludovic Courtès schreef op wo 23-03-2022 om 23:36 [+0100]: Thoughts? From service.scm: > + (define (sleep* n) > + ;; In general we want to use (@ (fibers) sleep) to yield to the scheduler. > + ;; However, this code might be non-suspendable--e.g., if the user calls > + ;; the 'start' method right from their config file, which is loaded with > + ;; 'primitive-load', which is a continuation barrier. Thus, this variant > + ;; checks whether it can suspend and picks the right 'sleep'. > + (if (yield-current-task) > + (begin > + (set! sleep* (@ (fibers) sleep)) > + (sleep n)) > + (begin > + (set! sleep* (@ (guile) sleep)) > + ((@ (guile) sleep) n)))) Instead of working around this limitation of Fiber's 'sleep', why not modify Fiber's sleep to detect if it is from a suspendable context or not, and depending on that, use Guile's sleep/usleep or the perform-operation+sleep-operation? Additionally, the set! can be avoided here in favour of a loop variable: (define start ...) (define (sleep n) ;; In general [...] (if (yield-current-task) (begin ((@ (fibers) sleep) n) ((@ (fibers) sleep) n)) (begin ((@ (guile) sleep) n) ((@ (guile) sleep) n)))) (let loop ((sleep sleep)) (define (try-again) ... (loop (sleep 1))) (catch ...)) FWIW, the delay can be decreased here, if Guile's sleep is replaced by an appropriate use of 'usleep'. Greetings, Maxime.