;;;; -*- coding: utf-8; fill-column: 78 -*-
+changes relative to sbcl-1.0.35:
+ * bug fix: SB-THREAD:CONDITION-WAIT sometimes signaled a deadline twice
+ in a row even though a handler defered it long into the future.
+
changes in sbcl-1.0.35 relative to sbcl-1.0.34:
* optimization: ROUND with a single single-float or double-float argument
is properly inlined when possible.
(allow-with-interrupts
(futex-wait (waitqueue-data-address queue)
(get-lisp-obj-address me)
- ;; our way if saying "no
+ ;; our way of saying "no
;; timeout":
(or to-sec -1)
(or to-usec 0))))
;; them before entering the debugger, but this is
;; better than nothing.
(allow-with-interrupts (get-mutex mutex)))
- ;; ETIMEDOUT
- ((1) (signal-deadline))
+ ;; ETIMEDOUT; we know it was a timeout, yet we cannot
+ ;; signal a deadline unconditionally here because the
+ ;; call to GET-MUTEX may already have signaled it.
+ ((1))
;; EINTR
((2))
;; EWOULDBLOCK, -1 here, is the possible spurious wakeup
(format t "waitqueue wakeup tests done~%")
+;;; Make sure that a deadline handler is not invoked twice in a row in
+;;; CONDITION-WAIT. See LP #512914 for a detailed explanation.
+;;;
+#-sb-lutex ; See KLUDGE above: no deadlines for condition-wait+lutexes.
+(with-test (:name (:condition-wait :deadlines :LP-512914))
+ (let ((n 2) ; was empirically enough to trigger the bug
+ (mutex (sb-thread:make-mutex))
+ (waitq (sb-thread:make-waitqueue))
+ (threads nil)
+ (deadline-handler-run-twice? nil))
+ (dotimes (i n)
+ (let ((child
+ (sb-thread:make-thread
+ #'(lambda ()
+ (handler-bind
+ ((sb-sys:deadline-timeout
+ (let ((already? nil))
+ #'(lambda (c)
+ (when already?
+ (setq deadline-handler-run-twice? t))
+ (setq already? t)
+ (sleep 0.2)
+ (sb-thread:condition-broadcast waitq)
+ (sb-sys:defer-deadline 10.0 c)))))
+ (sb-sys:with-deadline (:seconds 0.1)
+ (sb-thread:with-mutex (mutex)
+ (sb-thread:condition-wait waitq mutex))))))))
+ (push child threads)))
+ (mapc #'sb-thread:join-thread threads)
+ (assert (not deadline-handler-run-twice?))))
+
(with-test (:name (:mutex :finalization))
(let ((a nil))
(dotimes (i 500000)
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.35"
+"1.0.35.1"