diff options
| author | Christopher Baines <mail@cbaines.net> | 2026-07-27 11:23:13 +0100 |
|---|---|---|
| committer | Christopher Baines <mail@cbaines.net> | 2026-07-29 09:43:08 +0100 |
| commit | dcddca760b8252474498e549b6e6ef34fc393f21 (patch) | |
| tree | ca97a934e01b6fc013039b3072354e58fccbb5a3 | |
| parent | a2ec1bcf39fdd5f083470090fb7608457c30d75b (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.mk | 1 | ||||
| -rw-r--r-- | gnu/packages/guile-xyz.scm | 3 | ||||
| -rw-r--r-- | gnu/packages/patches/guile-fibers-fix-timer-wheel-remove.patch | 117 |
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 @@ | |||
| 1 | From 68d39f3421ece06bcb5f2dffb309024214b003e3 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Christopher Baines <mail@cbaines.net> | ||
| 3 | Date: Wed, 20 May 2026 13:04:51 +0200 | ||
| 4 | Subject: [PATCH] timer-wheel: Join up removal behaviour between advance! and | ||
| 5 | remove! | ||
| 6 | |||
| 7 | timer-wheel-advance! can move entries to other wheels, but it can also | ||
| 8 | change the next pointer of the previous entry to no longer point at | ||
| 9 | the current entry, effectively removing it from the wheel. | ||
| 10 | |||
| 11 | With previous behaviour of timer-wheel-remove!, always changing the | ||
| 12 | next and previous entries next and previous values to "remove" the | ||
| 13 | current entry, and after this setting the next and previous values of | ||
| 14 | the current entry to point at the entry itself, this could result in a | ||
| 15 | wheel where there was a cycle in the next linked list. | ||
| 16 | |||
| 17 | This commit addresses this behaviour by setting the next and previous | ||
| 18 | pointers of an entry to #f when it's advanced over and when | ||
| 19 | removed. timer-wheel-remove! then can't behave | ||
| 20 | incorrectly. timer-wheel-advance! also clears the obj and time fields | ||
| 21 | to be consistent with timer-wheel-remove!. | ||
| 22 | |||
| 23 | * fibers/timer-wheel.scm (timer-wheel-remove!): Restore behaviour | ||
| 24 | checking prev and next. | ||
| 25 | (timer-wheel-advance!): Set entry fields to #f when they leave the | ||
| 26 | wheel. | ||
| 27 | * tests/timer-wheel.scm (test-remove): New procedure. | ||
| 28 | |||
| 29 | Fixes: 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 | |||
| 35 | diff --git a/fibers/timer-wheel.scm b/fibers/timer-wheel.scm | ||
| 36 | index 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) | ||
| 84 | diff --git a/tests/timer-wheel.scm b/tests/timer-wheel.scm | ||
| 85 | index 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 | -- | ||
| 116 | 2.54.0 | ||
| 117 | |||
