mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
srfi-18: Avoid call/cc.
* module/srfi/srfi-18.scm (with-exception-handlers-here): New function. (wrap): Remove. (thread-join!, mutex-lock!): Use with-exception-handlers-here instead of the call/cc+wrap mess.
This commit is contained in:
parent
c3f08aa866
commit
789a4d8d87
1 changed files with 34 additions and 28 deletions
|
@ -220,18 +220,26 @@
|
||||||
(when (> usecs 0) (usleep usecs))
|
(when (> usecs 0) (usleep usecs))
|
||||||
*unspecified*))
|
*unspecified*))
|
||||||
|
|
||||||
;; A convenience function for installing exception handlers on SRFI-18
|
;; Whereas SRFI-34 leaves the continuation of a call to an exception
|
||||||
;; primitives that resume the calling continuation after the handler is
|
;; handler unspecified, SRFI-18 has this to say:
|
||||||
;; invoked -- this resolves a behavioral incompatibility with Guile's
|
;;
|
||||||
;; implementation of SRFI-34, which uses lazy-catch and rethrows handled
|
;; When one of the primitives defined in this SRFI raises an exception
|
||||||
;; exceptions. (SRFI-18, "Primitives and exceptions")
|
;; defined in this SRFI, the exception handler is called with the same
|
||||||
|
;; continuation as the primitive (i.e. it is a tail call to the
|
||||||
|
;; exception handler).
|
||||||
|
;;
|
||||||
|
;; Therefore arrange for exceptions thrown by SRFI-18 primitives to run
|
||||||
|
;; handlers with the continuation of the primitive call, for those
|
||||||
|
;; primitives that throw exceptions.
|
||||||
|
|
||||||
(define (wrap thunk)
|
(define (with-exception-handlers-here thunk)
|
||||||
(lambda (continuation)
|
(let ((tag (make-prompt-tag)))
|
||||||
(with-exception-handler (lambda (obj)
|
(call-with-prompt tag
|
||||||
((current-exception-handler) obj)
|
(lambda ()
|
||||||
(continuation))
|
(with-exception-handler (lambda (exn) (abort-to-prompt tag exn))
|
||||||
thunk)))
|
thunk))
|
||||||
|
(lambda (k exn)
|
||||||
|
((current-exception-handler) exn)))))
|
||||||
|
|
||||||
;; A pass-thru to cancel-thread that first installs a handler that throws
|
;; A pass-thru to cancel-thread that first installs a handler that throws
|
||||||
;; terminated-thread exception, as per SRFI-18,
|
;; terminated-thread exception, as per SRFI-18,
|
||||||
|
@ -253,15 +261,14 @@
|
||||||
*unspecified*))
|
*unspecified*))
|
||||||
|
|
||||||
(define (thread-join! thread . args)
|
(define (thread-join! thread . args)
|
||||||
(define thread-join-inner!
|
(with-exception-handlers-here
|
||||||
(wrap (lambda ()
|
(lambda ()
|
||||||
(let ((v (apply threads:join-thread thread args))
|
(let ((v (apply threads:join-thread thread args))
|
||||||
(e (thread->exception thread)))
|
(e (thread->exception thread)))
|
||||||
(if (and (= (length args) 1) (not v))
|
(if (and (= (length args) 1) (not v))
|
||||||
(srfi-34:raise (condition (&join-timeout-exception))))
|
(srfi-34:raise (condition (&join-timeout-exception))))
|
||||||
(if e (srfi-34:raise e))
|
(if e (srfi-34:raise e))
|
||||||
v))))
|
v))))
|
||||||
(call/cc thread-join-inner!))
|
|
||||||
|
|
||||||
;; MUTEXES
|
;; MUTEXES
|
||||||
;; These functions are all pass-thrus to the existing Guile implementations.
|
;; These functions are all pass-thrus to the existing Guile implementations.
|
||||||
|
@ -293,14 +300,13 @@
|
||||||
(if (> (threads:mutex-level mutex) 0) 'not-owned 'not-abandoned))))
|
(if (> (threads:mutex-level mutex) 0) 'not-owned 'not-abandoned))))
|
||||||
|
|
||||||
(define (mutex-lock! mutex . args)
|
(define (mutex-lock! mutex . args)
|
||||||
(define mutex-lock-inner!
|
(with-exception-handlers-here
|
||||||
(wrap (lambda ()
|
(lambda ()
|
||||||
(catch 'abandoned-mutex-error
|
(catch 'abandoned-mutex-error
|
||||||
(lambda () (apply threads:lock-mutex mutex args))
|
(lambda () (apply threads:lock-mutex mutex args))
|
||||||
(lambda (key . args)
|
(lambda (key . args)
|
||||||
(srfi-34:raise
|
(srfi-34:raise
|
||||||
(condition (&abandoned-mutex-exception))))))))
|
(condition (&abandoned-mutex-exception))))))))
|
||||||
(call/cc mutex-lock-inner!))
|
|
||||||
|
|
||||||
(define (mutex-unlock! mutex . args)
|
(define (mutex-unlock! mutex . args)
|
||||||
(apply threads:unlock-mutex mutex args))
|
(apply threads:unlock-mutex mutex args))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue