summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2026-07-27 11:23:13 +0100
committerChristopher Baines <mail@cbaines.net>2026-07-29 09:43:08 +0100
commitdcddca760b8252474498e549b6e6ef34fc393f21 (patch)
treeca97a934e01b6fc013039b3072354e58fccbb5a3
parenta2ec1bcf39fdd5f083470090fb7608457c30d75b (diff)
gnu: guile-fibers: Add fix timer wheel patch.
This fixes this issue https://codeberg.org/guile/fibers/issues/183 . Patch taken from https://codeberg.org/guile/fibers/pulls/184 . * gnu/packages/patches/guile-fibers-fix-timer-wheel-remove.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/guile-xyz.scm (guile-fibers-1.4)[source]: Add patch. Change-Id: Ifbef990b183ce7aacafb9aa75d1bcc1f4f72b23d
-rw-r--r--gnu/local.mk1
-rw-r--r--gnu/packages/guile-xyz.scm3
-rw-r--r--gnu/packages/patches/guile-fibers-fix-timer-wheel-remove.patch117
3 files changed, 120 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 25e639fdbb2..948175d4134 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1571,6 +1571,7 @@ dist_patch_DATA = \
1571 %D%/packages/patches/guile-fibers-cross-build-fix.patch \ 1571 %D%/packages/patches/guile-fibers-cross-build-fix.patch \
1572 %D%/packages/patches/guile-fibers-epoll-instance-is-dead.patch \ 1572 %D%/packages/patches/guile-fibers-epoll-instance-is-dead.patch \
1573 %D%/packages/patches/guile-fibers-fd-finalizer-leak.patch \ 1573 %D%/packages/patches/guile-fibers-fd-finalizer-leak.patch \
1574 %D%/packages/patches/guile-fibers-fix-timer-wheel-remove.patch \
1574 %D%/packages/patches/guile-fibers-wait-for-io-readiness.patch \ 1575 %D%/packages/patches/guile-fibers-wait-for-io-readiness.patch \
1575 %D%/packages/patches/guile-fibers-libevent-32-bit.patch \ 1576 %D%/packages/patches/guile-fibers-libevent-32-bit.patch \
1576 %D%/packages/patches/guile-fibers-libevent-timeout.patch \ 1577 %D%/packages/patches/guile-fibers-libevent-timeout.patch \
diff --git a/gnu/packages/guile-xyz.scm b/gnu/packages/guile-xyz.scm
index 428b871e6cd..929d7c9a912 100644
--- a/gnu/packages/guile-xyz.scm
+++ b/gnu/packages/guile-xyz.scm
@@ -1222,7 +1222,8 @@ is not available for Guile 2.0.")
1222 (sha256 1222 (sha256
1223 (base32 1223 (base32
1224 "1q0a9y0cc8rld1z7mcj61fkldhd0kn9n4yq25izxslbgg4g5h9j6")) 1224 "1q0a9y0cc8rld1z7mcj61fkldhd0kn9n4yq25izxslbgg4g5h9j6"))
1225 (patches '()))) 1225 (patches
1226 (search-patches "guile-fibers-fix-timer-wheel-remove.patch"))))
1226 (arguments 1227 (arguments
1227 (if (target-aarch64?) 1228 (if (target-aarch64?)
1228 (list #:phases 1229 (list #:phases
diff --git a/gnu/packages/patches/guile-fibers-fix-timer-wheel-remove.patch b/gnu/packages/patches/guile-fibers-fix-timer-wheel-remove.patch
new file mode 100644
index 00000000000..33baeb1be4f
--- /dev/null
+++ b/gnu/packages/patches/guile-fibers-fix-timer-wheel-remove.patch
@@ -0,0 +1,117 @@
1From 68d39f3421ece06bcb5f2dffb309024214b003e3 Mon Sep 17 00:00:00 2001
2From: Christopher Baines <mail@cbaines.net>
3Date: Wed, 20 May 2026 13:04:51 +0200
4Subject: [PATCH] timer-wheel: Join up removal behaviour between advance! and
5 remove!
6
7timer-wheel-advance! can move entries to other wheels, but it can also
8change the next pointer of the previous entry to no longer point at
9the current entry, effectively removing it from the wheel.
10
11With previous behaviour of timer-wheel-remove!, always changing the
12next and previous entries next and previous values to "remove" the
13current entry, and after this setting the next and previous values of
14the current entry to point at the entry itself, this could result in a
15wheel where there was a cycle in the next linked list.
16
17This commit addresses this behaviour by setting the next and previous
18pointers of an entry to #f when it's advanced over and when
19removed. timer-wheel-remove! then can't behave
20incorrectly. timer-wheel-advance! also clears the obj and time fields
21to be consistent with timer-wheel-remove!.
22
23* fibers/timer-wheel.scm (timer-wheel-remove!): Restore behaviour
24checking prev and next.
25(timer-wheel-advance!): Set entry fields to #f when they leave the
26wheel.
27* tests/timer-wheel.scm (test-remove): New procedure.
28
29Fixes: guile/fibers#183
30---
31 fibers/timer-wheel.scm | 29 ++++++++++++++++++-----------
32 tests/timer-wheel.scm | 22 ++++++++++++++++++++++
33 2 files changed, 40 insertions(+), 11 deletions(-)
34
35diff --git a/fibers/timer-wheel.scm b/fibers/timer-wheel.scm
36index 9bede30..5ff7446 100644
37--- a/fibers/timer-wheel.scm
38+++ b/fibers/timer-wheel.scm
39@@ -154,18 +154,15 @@ from @var{wheel}."
40
41 (match entry
42 (($ <timer-entry> prev next)
43- (set-timer-entry-next! prev next)
44- (set-timer-entry-prev! entry entry)
45-
46- (set-timer-entry-prev! next prev)
47- (set-timer-entry-next! entry entry)
48+ (when (and prev next)
49+ (set-timer-entry-next! prev next)
50+ (set-timer-entry-prev! next prev)
51+ (invalidate-next-entry-time! wheel))
52
53+ (set-timer-entry-prev! entry #f)
54+ (set-timer-entry-next! entry #f)
55 (set-timer-entry-obj! entry #f)
56- (set-timer-entry-time! entry #f)
57-
58- ;; Removing ENTRY might have change the next entry time for WHEEL.
59- ;; Thus invalidate it so that it gets recomputed.
60- (invalidate-next-entry-time! wheel))))
61+ (set-timer-entry-time! entry #f))))
62
63 (define (timer-wheel-next-entry-time wheel)
64 (define (slot-min-time head)
65@@ -266,7 +263,17 @@ from @var{wheel}."
66 (push-timer-entry! entry new-head)))))
67 (advance-wheel! outer add-to-inner!))
68
69- (advance-wheel! wheel (lambda (entry t obj) (schedule! obj))))
70+ (advance-wheel! wheel (lambda (entry t obj)
71+ ;; Entry no longer needed, so clear fields.
72+ (set-timer-entry-obj! entry #f)
73+ (set-timer-entry-time! entry #f)
74+ ;; Clearing the next and prev prevents
75+ ;; timer-wheel-remove! from trying to
76+ ;; remove already removed entries.
77+ (set-timer-entry-next! entry #f)
78+ (set-timer-entry-prev! entry #f)
79+
80+ (schedule! obj))))
81
82 (match wheel
83 (($ <timer-wheel> time-base shift cur slots outer)
84diff --git a/tests/timer-wheel.scm b/tests/timer-wheel.scm
85index 8fc86d2..0b3ba96 100644
86--- a/tests/timer-wheel.scm
87+++ b/tests/timer-wheel.scm
88@@ -71,4 +71,26 @@
89 (timer-wheel-advance! wheel (timer-wheel-next-tick-end wheel) check!)
90 (unless (= count event-count) (error "what4" count event-count)))
91
92+(define (test-remove)
93+ (let* ((wheel (make-timer-wheel))
94+ (t0 (timer-wheel-next-tick-start wheel))
95+ (a (timer-wheel-add! wheel t0 'a))
96+ (b (timer-wheel-add! wheel t0 'b)))
97+ (timer-wheel-advance! wheel (timer-wheel-next-tick-end wheel)
98+ (lambda (obj) #t))
99+
100+ (timer-wheel-remove! wheel b)
101+ (timer-wheel-remove! wheel a)
102+
103+ (sigaction SIGALRM
104+ (lambda _
105+ (error "timer-wheel-next-entry-time hung")))
106+ (alarm 15)
107+ ;; slot-min-time will loop forever
108+ (timer-wheel-next-entry-time wheel)
109+ (alarm 0)))
110+
111+(display "starting timer-wheel self-test\n")
112 (self-test)
113+(display "starting timer-wheel test-remove\n")
114+(test-remove)
115--
1162.54.0
117