[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 10/17: srfi-18: Avoid call/cc.
From: |
Andy Wingo |
Subject: |
[Guile-commits] 10/17: srfi-18: Avoid call/cc. |
Date: |
Mon, 31 Oct 2016 21:39:37 +0000 (UTC) |
wingo pushed a commit to branch master
in repository guile.
commit 789a4d8d87ecdef9e785e04de4b57e01e762b36e
Author: Andy Wingo <address@hidden>
Date: Mon Oct 31 20:52:08 2016 +0100
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.
---
module/srfi/srfi-18.scm | 64 ++++++++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 29 deletions(-)
diff --git a/module/srfi/srfi-18.scm b/module/srfi/srfi-18.scm
index d2a7fc0..46c069e 100644
--- a/module/srfi/srfi-18.scm
+++ b/module/srfi/srfi-18.scm
@@ -220,18 +220,26 @@
(when (> usecs 0) (usleep usecs))
*unspecified*))
-;; A convenience function for installing exception handlers on SRFI-18
-;; primitives that resume the calling continuation after the handler is
-;; invoked -- this resolves a behavioral incompatibility with Guile's
-;; implementation of SRFI-34, which uses lazy-catch and rethrows handled
-;; exceptions. (SRFI-18, "Primitives and exceptions")
-
-(define (wrap thunk)
- (lambda (continuation)
- (with-exception-handler (lambda (obj)
- ((current-exception-handler) obj)
- (continuation))
- thunk)))
+;; Whereas SRFI-34 leaves the continuation of a call to an exception
+;; handler unspecified, SRFI-18 has this to say:
+;;
+;; When one of the primitives defined in this SRFI raises an exception
+;; 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 (with-exception-handlers-here thunk)
+ (let ((tag (make-prompt-tag)))
+ (call-with-prompt tag
+ (lambda ()
+ (with-exception-handler (lambda (exn) (abort-to-prompt tag exn))
+ thunk))
+ (lambda (k exn)
+ ((current-exception-handler) exn)))))
;; A pass-thru to cancel-thread that first installs a handler that throws
;; terminated-thread exception, as per SRFI-18,
@@ -253,15 +261,14 @@
*unspecified*))
(define (thread-join! thread . args)
- (define thread-join-inner!
- (wrap (lambda ()
- (let ((v (apply threads:join-thread thread args))
- (e (thread->exception thread)))
- (if (and (= (length args) 1) (not v))
- (srfi-34:raise (condition (&join-timeout-exception))))
- (if e (srfi-34:raise e))
- v))))
- (call/cc thread-join-inner!))
+ (with-exception-handlers-here
+ (lambda ()
+ (let ((v (apply threads:join-thread thread args))
+ (e (thread->exception thread)))
+ (if (and (= (length args) 1) (not v))
+ (srfi-34:raise (condition (&join-timeout-exception))))
+ (if e (srfi-34:raise e))
+ v))))
;; MUTEXES
;; 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))))
(define (mutex-lock! mutex . args)
- (define mutex-lock-inner!
- (wrap (lambda ()
- (catch 'abandoned-mutex-error
- (lambda () (apply threads:lock-mutex mutex args))
- (lambda (key . args)
- (srfi-34:raise
- (condition (&abandoned-mutex-exception))))))))
- (call/cc mutex-lock-inner!))
+ (with-exception-handlers-here
+ (lambda ()
+ (catch 'abandoned-mutex-error
+ (lambda () (apply threads:lock-mutex mutex args))
+ (lambda (key . args)
+ (srfi-34:raise
+ (condition (&abandoned-mutex-exception))))))))
(define (mutex-unlock! mutex . args)
(apply threads:unlock-mutex mutex args))
- [Guile-commits] branch master updated (c957ec7 -> eeeee32), Andy Wingo, 2016/10/31
- [Guile-commits] 05/17: srfi-18: Simplify thread-sleep!, thread-terminate!., Andy Wingo, 2016/10/31
- [Guile-commits] 04/17: srfi-18: Use `match' in thread-start!., Andy Wingo, 2016/10/31
- [Guile-commits] 06/17: srfi-18: Use lambda* optional arguments., Andy Wingo, 2016/10/31
- [Guile-commits] 07/17: srfi-18: Use parameters., Andy Wingo, 2016/10/31
- [Guile-commits] 10/17: srfi-18: Avoid call/cc.,
Andy Wingo <=
- [Guile-commits] 11/17: Rationalize exception handling in srfi-18, Andy Wingo, 2016/10/31
- [Guile-commits] 17/17: Remove thread cleanup facility, Andy Wingo, 2016/10/31
- [Guile-commits] 02/17: Fix srfi-34 indentation, Andy Wingo, 2016/10/31
- [Guile-commits] 12/17: Refactor thread-join! to use optional args., Andy Wingo, 2016/10/31
- [Guile-commits] 13/17: Trim srfi-18 thread startup machinery, Andy Wingo, 2016/10/31
- [Guile-commits] 14/17: cancel-thread can take arguments, Andy Wingo, 2016/10/31
- [Guile-commits] 03/17: srfi-18: Improve style., Andy Wingo, 2016/10/31
- [Guile-commits] 15/17: srfi-18: thread-terminate! without cleanup handlers, Andy Wingo, 2016/10/31
- [Guile-commits] 01/17: cancel-thread via asyncs, not pthread_cancel, Andy Wingo, 2016/10/31
- [Guile-commits] 08/17: srfi-18: Use srfi-35 conditions., Andy Wingo, 2016/10/31