X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftimer.lisp;h=774ee2b4a6f768e0b039c1d565f836562f764b64;hb=617d4fa1db5a4a11564e7c59bfb684c7eb25633d;hp=3ad04ea8cb20d570f873f3bce02a2ef1783f9e0a;hpb=18aa51db1d51cb20eb35a8e34c36cd78446c6bdd;p=sbcl.git diff --git a/src/code/timer.lisp b/src/code/timer.lisp index 3ad04ea..774ee2b 100644 --- a/src/code/timer.lisp +++ b/src/code/timer.lisp @@ -135,8 +135,6 @@ ;; FUNCTION until the other is called, from when it does nothing. (let ((mutex (sb!thread:make-mutex)) (cancelled-p nil)) - #!-sb-thread - (declare (ignore mutex)) (list #'(lambda () (sb!thread:with-recursive-lock (mutex) @@ -203,9 +201,7 @@ from now. For timers with a repeat interval it returns true." (defmacro with-scheduler-lock ((&optional) &body body) ;; don't let the SIGALRM handler mess things up - `(sb!sys:without-interrupts - (sb!thread:with-mutex (*scheduler-lock*) - ,@body))) + `(sb!thread::call-with-system-mutex (lambda () ,@body) *scheduler-lock*)) (defun under-scheduler-lock-p () #!-sb-thread @@ -338,7 +334,8 @@ triggers." (sb!thread:interrupt-thread thread function) (sb!thread:interrupt-thread-error (c) (declare (ignore c)) - (warn "Timer ~S failed to interrupt thread ~S." timer thread))))))) + (warn "Timer ~S failed to interrupt thread ~S." + timer thread))))))) ;; Called from the signal handler. (defun run-expired-timers () @@ -360,8 +357,26 @@ triggers." (defmacro sb!ext:with-timeout (expires &body body) #!+sb-doc - "Execute the body, asynchronously interrupting it and signalling a -TIMEOUT condition after at least EXPIRES seconds have passed." + "Execute the body, asynchronously interrupting it and signalling a TIMEOUT +condition after at least EXPIRES seconds have passed. + +Note that it is never safe to unwind from an asynchronous condition. Consider: + + (defun call-with-foo (function) + (let (foo) + (unwind-protect + (progn + (setf foo (get-foo)) + (funcall function foo)) + (when foo + (release-foo foo))))) + +If TIMEOUT occurs after GET-FOO has executed, but before the assignment, then +RELEASE-FOO will be missed. While individual sites like this can be made proof +against asynchronous unwinds, this doesn't solve the fundamental issue, as all +the frames potentially unwound through need to be proofed, which includes both +system and application code -- and in essence proofing everything will make +the system uninterruptible." (with-unique-names (timer) ;; FIXME: a temporary compatibility workaround for CLX, if unsafe ;; unwinds are handled revisit it.