From: Gabor Melis Date: Thu, 7 Jul 2005 13:27:55 +0000 (+0000) Subject: 0.9.2.35: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=f16e090088c6aa6178ecf50a8b74ff41cce73640;p=sbcl.git 0.9.2.35: * bug fix: inner with-recursive-lock no longer releases the mutex --- diff --git a/NEWS b/NEWS index 4f76b01..3d4329f 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ changes in sbcl-0.9.3 relative to sbcl-0.9.2: ** bug fix: debugger doesn't hang on session lock if interrupted at an inappropriate moment ** bug fix: run-program is now thread safe(r) + ** bug fix: inner with-recursive-lock no longer releases the mutex * fixed some bugs revealed by Paul Dietz' test suite: ** TYPE-ERRORs from signalled by COERCE now have DATUM and EXPECTED-TYPE slots filled. diff --git a/src/code/thread.lisp b/src/code/thread.lisp index 19f14be..cd4ca4f 100644 --- a/src/code/thread.lisp +++ b/src/code/thread.lisp @@ -12,6 +12,10 @@ (in-package "SB!THREAD") (sb!xc:defmacro with-mutex ((mutex &key value (wait-p t)) &body body) + #!+sb-doc + "Acquire MUTEX for the dynamic scope of BODY, setting it to +NEW-VALUE or some suitable default value if NIL. If WAIT-P is non-NIL +and the mutex is in use, sleep until it is available" #!-sb-thread (declare (ignore mutex value wait-p)) #!+sb-thread (with-unique-names (got) @@ -28,14 +32,21 @@ `(locally ,@body)) (sb!xc:defmacro with-recursive-lock ((mutex) &body body) + #!+sb-doc + "Acquires MUTEX for the dynamic scope of BODY. Within that scope +further recursive lock attempts for the same mutex succeed. However, +it is an error to mix WITH-MUTEX and WITH-RECURSIVE-LOCK for the same +mutex." #!-sb-thread (declare (ignore mutex)) #!+sb-thread - (with-unique-names (cfp) - `(let ((,cfp (sb!kernel:current-fp))) - (unless (and (mutex-value ,mutex) - (sb!vm:control-stack-pointer-valid-p - (sb!sys:int-sap - (sb!kernel:get-lisp-obj-address (mutex-value ,mutex))))) + (with-unique-names (cfp inner-lock) + `(let ((,cfp (sb!kernel:current-fp)) + (,inner-lock + (and (mutex-value ,mutex) + (sb!vm:control-stack-pointer-valid-p + (sb!sys:int-sap + (sb!kernel:get-lisp-obj-address (mutex-value ,mutex))))))) + (unless ,inner-lock ;; this punning with MAKE-LISP-OBJ depends for its safety on ;; the frame pointer being a lispobj-aligned integer. While ;; it is, then MAKE-LISP-OBJ will always return a FIXNUM, so @@ -46,10 +57,7 @@ (get-mutex ,mutex (sb!kernel:make-lisp-obj (sb!sys:sap-int ,cfp)))) (unwind-protect (locally ,@body) - (when (sb!sys:sap= (sb!sys:int-sap - (sb!kernel:get-lisp-obj-address - (mutex-value ,mutex))) - ,cfp) + (unless ,inner-lock (release-mutex ,mutex))))) #!-sb-thread `(locally ,@body)) diff --git a/tests/threads.impure.lisp b/tests/threads.impure.lisp index fc917b4..4be11bc 100644 --- a/tests/threads.impure.lisp +++ b/tests/threads.impure.lisp @@ -77,6 +77,20 @@ (assert (eql (mutex-lock l) 0) nil "6") (describe l)) +(labels ((ours-p (value) + (sb-vm:control-stack-pointer-valid-p + (sb-sys:int-sap (sb-kernel:get-lisp-obj-address value))))) + (let ((l (make-mutex :name "rec"))) + (assert (eql (mutex-value l) nil) nil "1") + (assert (eql (mutex-lock l) 0) nil "2") + (sb-thread:with-recursive-lock (l) + (assert (ours-p (mutex-value l)) nil "3") + (sb-thread:with-recursive-lock (l) + (assert (ours-p (mutex-value l)) nil "4")) + (assert (ours-p (mutex-value l)) nil "5")) + (assert (eql (mutex-value l) nil) nil "6") + (assert (eql (mutex-lock l) 0) nil "7"))) + (let ((l (make-waitqueue :name "spinlock")) (p *current-thread*)) (assert (eql (waitqueue-lock l) 0) nil "1") diff --git a/version.lisp-expr b/version.lisp-expr index a028091..170c71e 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; 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".) -"0.9.2.34" +"0.9.2.35"