racket/draw: fix gl-context<%> locking
The optional arguments for `call-as-current' for `gl-context<%>' were not implemented, and the locking implementation didn't match the documentation in other ways.
This commit is contained in:
parent
e71cbbe7a9
commit
f729c6441c
|
@ -15,12 +15,13 @@
|
||||||
(define lock-ch (make-channel))
|
(define lock-ch (make-channel))
|
||||||
(define lock-holder-ch (make-channel))
|
(define lock-holder-ch (make-channel))
|
||||||
(define (lock-manager)
|
(define (lock-manager)
|
||||||
|
(define none '#(#f #f #f))
|
||||||
(let loop ()
|
(let loop ()
|
||||||
(sync (handle-evt
|
(sync (handle-evt
|
||||||
lock-ch
|
lock-ch
|
||||||
(lambda (p)
|
(lambda (p)
|
||||||
(let ([t (car p)]
|
(let ([t (vector-ref p 0)]
|
||||||
[ch (cdr p)])
|
[ch (vector-ref p 2)])
|
||||||
(let waiting-loop ()
|
(let waiting-loop ()
|
||||||
(sync (handle-evt
|
(sync (handle-evt
|
||||||
(thread-dead-evt t)
|
(thread-dead-evt t)
|
||||||
|
@ -29,43 +30,52 @@
|
||||||
ch
|
ch
|
||||||
(lambda (v) (loop)))
|
(lambda (v) (loop)))
|
||||||
(handle-evt
|
(handle-evt
|
||||||
(channel-put-evt lock-holder-ch t)
|
(channel-put-evt lock-holder-ch p)
|
||||||
(lambda (v) (waiting-loop))))))))
|
(lambda (v) (waiting-loop))))))))
|
||||||
(handle-evt
|
(handle-evt
|
||||||
(channel-put-evt lock-holder-ch #f)
|
(channel-put-evt lock-holder-ch none)
|
||||||
(lambda (v) (loop))))))
|
(lambda (v) (loop))))))
|
||||||
(define manager-t (thread/suspend-to-kill lock-manager))
|
(define manager-t (thread/suspend-to-kill lock-manager))
|
||||||
|
|
||||||
(define gl-context<%>
|
(define gl-context<%>
|
||||||
(interface ()
|
(interface ()
|
||||||
[call-as-current (->*m [(-> any)] any)]
|
[call-as-current (->*m [(-> any)] [evt? any/c] any)]
|
||||||
[ok? (->m boolean?)]
|
[ok? (->m boolean?)]
|
||||||
[swap-buffers (->m any)]))
|
[swap-buffers (->m any)]))
|
||||||
|
|
||||||
;; Implemented by subclasses:
|
;; Implemented by subclasses:
|
||||||
(define gl-context%
|
(define gl-context%
|
||||||
(class* object% (gl-context<%>)
|
(class* object% (gl-context<%>)
|
||||||
(define/private (with-gl-lock t)
|
(define/private (with-gl-lock t alternate-evt enable-break?)
|
||||||
(thread-resume manager-t (current-thread))
|
(thread-resume manager-t (current-thread))
|
||||||
(if (eq? (current-thread) (channel-get lock-holder-ch))
|
(define current (channel-get lock-holder-ch))
|
||||||
|
(if (and (eq? (vector-ref current 0) (current-thread))
|
||||||
|
(eq? (vector-ref current 1) this))
|
||||||
(t)
|
(t)
|
||||||
(let ([ch (make-channel)])
|
((if enable-break? sync/enable-break sync)
|
||||||
(dynamic-wind
|
(let ([ch (make-channel)])
|
||||||
(lambda ()
|
(handle-evt (channel-put-evt lock-ch (vector (current-thread) this ch))
|
||||||
(channel-put lock-ch (cons (current-thread) ch)))
|
(lambda (val)
|
||||||
t
|
(dynamic-wind
|
||||||
(lambda ()
|
void
|
||||||
(channel-put ch #t))))))
|
t
|
||||||
|
(lambda ()
|
||||||
(define/public (call-as-current t)
|
(channel-put ch #t))))))
|
||||||
|
alternate-evt)))
|
||||||
|
|
||||||
|
(define/public (call-as-current t [alternate-evt never-evt] [enable-breaks? #f])
|
||||||
(with-gl-lock
|
(with-gl-lock
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(do-call-as-current t))))
|
(do-call-as-current t))
|
||||||
|
alternate-evt
|
||||||
|
enable-breaks?))
|
||||||
|
|
||||||
(define/public (swap-buffers)
|
(define/public (swap-buffers)
|
||||||
(with-gl-lock
|
(with-gl-lock
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(do-swap-buffers))))
|
(do-swap-buffers))
|
||||||
|
never-evt
|
||||||
|
#f))
|
||||||
|
|
||||||
(define/public (ok?) #t)
|
(define/public (ok?) #t)
|
||||||
|
|
||||||
|
|
|
@ -569,4 +569,32 @@
|
||||||
|
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
|
|
||||||
|
(let ()
|
||||||
|
(define config (new gl-config%))
|
||||||
|
(define bm1 (make-gl-bitmap 100 100 config))
|
||||||
|
(define bm2 (make-gl-bitmap 100 100 config))
|
||||||
|
(define dc1 (make-object bitmap-dc% bm1))
|
||||||
|
(define dc2 (make-object bitmap-dc% bm2))
|
||||||
|
(define gl1 (send dc1 get-gl-context))
|
||||||
|
(define gl2 (send dc2 get-gl-context))
|
||||||
|
(send gl1 call-as-current
|
||||||
|
(lambda ()
|
||||||
|
(test 5 'alt (send gl2 call-as-current
|
||||||
|
(lambda () (error "not in this context!"))
|
||||||
|
(wrap-evt always-evt (lambda (v) 5))))
|
||||||
|
(sync
|
||||||
|
(thread
|
||||||
|
(lambda ()
|
||||||
|
(test 8 'thread/alts
|
||||||
|
(send gl1 call-as-current
|
||||||
|
(lambda () (error "not in this thread!"))
|
||||||
|
(wrap-evt always-evt (lambda (v) 8)))))))
|
||||||
|
(test 8 'reenter (send gl1 call-as-current
|
||||||
|
(lambda () 8)))))
|
||||||
|
(with-handlers ([exn? void])
|
||||||
|
(send gl1 call-as-current (lambda () (error "fail"))))
|
||||||
|
(test 12 'post-exn (send gl1 call-as-current (lambda () 12))))
|
||||||
|
|
||||||
|
;; ----------------------------------------
|
||||||
|
|
||||||
(report-errs)
|
(report-errs)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user