Skip to content

Commit 5751616

Browse files
committed
ffi/unsafe/obj: add +A' and -A' method modes
On Cocoa, a view's `drawRect:' method can be called from a heartbeat thread that animates controls. Such a call happens rarely for a `canvas%' or other class where `drawRect:' is overridden, but since it can happen, ensure that the callback runs on the Racket thread.
1 parent 3fd9df0 commit 5751616

File tree

5 files changed

+27
-14
lines changed

5 files changed

+27
-14
lines changed

collects/ffi/unsafe/objc.rkt

+12-5
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,14 @@
756756
(or (free-identifier=? #'kind #'+)
757757
(free-identifier=? #'kind #'-)
758758
(free-identifier=? #'kind #'+a)
759-
(free-identifier=? #'kind #'-a))
759+
(free-identifier=? #'kind #'-a)
760+
(free-identifier=? #'kind #'+A)
761+
(free-identifier=? #'kind #'-A))
760762
(let ([id #'id]
761763
[args (syntax->list #'(arg ...))]
762764
[in-class? (or (free-identifier=? #'kind #'+)
763-
(free-identifier=? #'kind #'+a))])
765+
(free-identifier=? #'kind #'+a)
766+
(free-identifier=? #'kind #'+A))])
764767
(when (null? args)
765768
(unless (identifier? id)
766769
(raise-syntax-error #f
@@ -787,15 +790,19 @@
787790
[_ (error "oops")])
788791
'())]
789792
[(async ...)
790-
(if (eq? (syntax-e id) 'dealloc)
791-
;; so that objects can be destroyed in foreign threads:
793+
(if (or (free-identifier=? #'kind #'+A)
794+
(free-identifier=? #'kind #'-A)
795+
;; so that objects can be destroyed in foreign threads:
796+
(eq? (syntax-e id) 'dealloc))
792797
#'(#:async-apply apply-directly)
793798
#'())]
794799
[in-cls (if in-class?
795800
#'(object-get-class cls)
796801
#'cls)]
797802
[atomic? (or (free-identifier=? #'kind #'+a)
798-
(free-identifier=? #'kind #'-a))])
803+
(free-identifier=? #'kind #'-a)
804+
(free-identifier=? #'kind #'+A)
805+
(free-identifier=? #'kind #'-A))])
799806
(quasisyntax/loc stx
800807
(let ([rt result-type]
801808
[arg-id arg-type] ...)

collects/mred/private/wx/cocoa/canvas.rkt

+4-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
(define-objc-mixin (RacketViewMixin Superclass)
6666
#:mixins (KeyMouseTextResponder CursorDisplayer FocusResponder)
6767
[wxb]
68-
(-a _void (drawRect: [_NSRect r])
68+
(-A _void (drawRect: [_NSRect r])
6969
(when wxb
7070
(let ([wx (->wx wxb)])
7171
(when wx
@@ -98,7 +98,7 @@
9898

9999
(define-objc-class CornerlessFrameView NSView
100100
[]
101-
(-a _void (drawRect: [_NSRect r])
101+
(-A _void (drawRect: [_NSRect r])
102102
(let ([ctx (tell NSGraphicsContext currentContext)])
103103
(tellv ctx saveGraphicsState)
104104
(let ([cg (tell #:type _CGContextRef ctx graphicsPort)]
@@ -129,7 +129,7 @@
129129
[on?]
130130
(-a _void (setFocusState: [_BOOL is-on?])
131131
(set! on? is-on?))
132-
(-a _void (drawRect: [_NSRect r])
132+
(-A _void (drawRect: [_NSRect r])
133133
(let ([f (tell #:type _NSRect self frame)])
134134
(tellv bezel-cell
135135
drawWithFrame: #:type _NSRect (make-NSRect (make-NSPoint 2 2)
@@ -154,7 +154,7 @@
154154
#:mixins (FocusResponder KeyMouseTextResponder CursorDisplayer)
155155
#:protocols (NSComboBoxDelegate)
156156
[wxb]
157-
(-a _void (drawRect: [_NSRect r])
157+
(-A _void (drawRect: [_NSRect r])
158158
(super-tell #:type _void drawRect: #:type _NSRect r)
159159
(let ([wx (->wx wxb)])
160160
(when wx

collects/mred/private/wx/cocoa/panel.rkt

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
(define-objc-class FrameView NSView
2424
[]
25-
(-a _void (drawRect: [_NSRect r])
25+
(-A _void (drawRect: [_NSRect r])
2626
(let ([ctx (tell NSGraphicsContext currentContext)])
2727
(tellv ctx saveGraphicsState)
2828
(let ([cg (tell #:type _CGContextRef ctx graphicsPort)]

collects/scribblings/foreign/objc.scrbl

+9-4
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Defines each @racket[protocol-id] to the protocol (a value with FFI type
138138
(eval:alts (import-protocol NSCoding) (void))
139139
]}
140140

141-
@defform/subs[#:literals (+ - +a -a)
141+
@defform/subs[#:literals (+ - +a -a +A -A)
142142
(define-objc-class class-id superclass-expr
143143
maybe-mixins
144144
maybe-protocols
@@ -150,7 +150,7 @@ Defines each @racket[protocol-id] to the protocol (a value with FFI type
150150
(code:line #:protocols (protocol-expr ...))]
151151
[method (mode result-ctype-expr (method-id) body ...+)
152152
(mode result-ctype-expr (arg ...+) body ...+)]
153-
[mode + - +a -a]
153+
[mode + - +a -a +A -A]
154154
[arg (code:line method-id [ctype-expr arg-id])])]{
155155

156156
Defines @racket[class-id] as a new, registered Objective-C class (of
@@ -167,12 +167,17 @@ directly when the method @racket[body]s. Outside the object, they can
167167
be referenced and set with @racket[get-ivar] and @racket[set-ivar!].
168168

169169
Each @racket[method] adds or overrides a method to the class (when
170-
@racket[mode] is @racket[-] or @racket[-a]) to be called on instances,
170+
@racket[mode] is @racket[-], @racket[-a], or @racket[-A]) to be called on instances,
171171
or it adds a method to the meta-class (when @racket[mode] is
172-
@racket[+] or @racket[+a]) to be called on the class itself. All
172+
@racket[+], @racket[+a], or @racket[+A]) to be called on the class itself. All
173173
result and argument types must be declared using FFI C types
174174
(@seeCtype). When @racket[mode] is @racket[+a] or @racket[-a], the
175175
method is called in atomic mode (see @racket[_cprocedure]).
176+
When @racket[mode] is @racket[+A] or @racket[-A], the
177+
method is called in atomic mode, and it may also be triggered
178+
as a result of a foreign call in a foreign thread
179+
thread, in which case the foreign thread must wait until the
180+
call completes in a Racket thread.
176181

177182
If a @racket[method] is declared with a single @racket[method-id] and
178183
no arguments, then @racket[method-id] must not end with

doc/release-notes/racket/HISTORY.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Changed initialization of current-directory to use PWD
44
racket/system: add a #:set-pwd? argument to system, etc., which
55
makes them set PWD by default
66
net/url: add support for HTTP/1.1 connections
7+
ffi/unsafe/objc: add -A and +A method modes
78

89
Version 5.3.4.2
910
Added current-environment-variables, environment-variables-ref,

0 commit comments

Comments
 (0)