From 1be19d56bd7e67319076e1cd93df9e50cde0bf13 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 May 2012 08:37:29 -0600 Subject: [PATCH] racket/draw: add `#:eventspace' argument to `open-output-text-editor' The argument is `(curent-eventspace)' by default, which makes ports work better with threads. Closes PR 12749 original commit: b30374824a7d79b96443da6e0e4223dd72da597b --- collects/mred/private/snipfile.rkt | 18 +++++++++++++----- collects/scribblings/gui/editor-funcs.scrbl | 16 ++++++++++++++-- collects/scribblings/gui/editor-overview.scrbl | 2 +- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/collects/mred/private/snipfile.rkt b/collects/mred/private/snipfile.rkt index 9a9973d2..127ccc29 100644 --- a/collects/mred/private/snipfile.rkt +++ b/collects/mred/private/snipfile.rkt @@ -10,7 +10,7 @@ (provide open-input-text-editor open-input-graphical-file text-editor-load-handler - open-output-text-editor ) + open-output-text-editor) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -312,7 +312,8 @@ p)) (define open-output-text-editor - (lambda (text [start 'end] [special-filter values] [port-name text]) + (lambda (text [start 'end] [special-filter values] [port-name text] + #:eventspace [eventspace (wx:current-eventspace)]) (define pos (if (eq? start 'end) (send text last-position) (min start @@ -322,9 +323,16 @@ (define raw-buffer (make-bytes 128)) (define utf8-buffer (make-bytes 128)) (define (show s) - (send text begin-edit-sequence) - (send text insert s pos) - (send text end-edit-sequence) + (define (insert) + (send text begin-edit-sequence) + (send text insert s pos) + (send text end-edit-sequence)) + (if (and eventspace + (and (not (eq? (current-thread) + (wx:eventspace-handler-thread eventspace))))) + (parameterize ([wx:current-eventspace eventspace]) + (wx:queue-callback insert #f)) + (insert)) (set! pos (+ (string-length s) pos))) (define (flush-text) (let ([cnt (peek-bytes-avail!* raw-buffer 0 #f in)]) diff --git a/collects/scribblings/gui/editor-funcs.scrbl b/collects/scribblings/gui/editor-funcs.scrbl index c9971fe9..d3d92a40 100644 --- a/collects/scribblings/gui/editor-funcs.scrbl +++ b/collects/scribblings/gui/editor-funcs.scrbl @@ -266,7 +266,8 @@ if using those methods are always safe.) @defproc[(open-output-text-editor [text-editor (is-a?/c text%)] [start-position (or/c exact-nonnegative-integer? (one/of 'end)) 'end] [special-filter (any/c . -> . any/c) (lambda (x) x)] - [port-name any/c text-editor]) + [port-name any/c text-editor] + [#:eventspace eventspace (or/c eventspace? #f) (current-eventspace)]) output-port]{ Creates an output port that delivers its content to @racket[text-editor]. @@ -284,9 +285,20 @@ If line counting is enabled for the resulting output port, then the port will report the line, offset from the line's start, and position within the editor at which the port writes data. +If @racket[eventspace] is not @racket[#f], then when the output port + is used in a thread other than @racket[eventspace]'s handler thread, + content is delivered to @racket[text-editor] through a low-priority + callback in @racket[eventspace]. Thus, if @racket[eventspace] + corresponds to the eventspace for the editor's @tech{displays}, + writing to the output port is safe from any thread. +If @racket[eventspace] is @racket[#f], beware that the port is only + weakly thread-safe. Content is delivered to @racket[text-editor] in + an @tech{edit sequence}, but an edit sequence is not enough + synchronization if, for example, the editor is displayed in an + enabled @racket[editor-canvas%]. See @secref["editorthreads"] for + more information.} -} @defproc[(read-editor-global-footer [in (is-a?/c editor-stream-in%)]) boolean?]{ diff --git a/collects/scribblings/gui/editor-overview.scrbl b/collects/scribblings/gui/editor-overview.scrbl index 50516d8d..f74466f4 100644 --- a/collects/scribblings/gui/editor-overview.scrbl +++ b/collects/scribblings/gui/editor-overview.scrbl @@ -735,7 +735,7 @@ An editor supports certain concurrent patterns @itemize[ @item{When an editor's @method[editor<%> refresh] method is - called during an edit sequence (which is started by + called during an @deftech{edit sequence} (which is started by @method[editor<%> begin-edit-sequence] and ended with @method[editor<%> end-edit-sequence]), the requested refresh region is recorded, but the refresh is not performed. Instead, the