improve the way errors are reported, avoid unintended multithreading

svn: r1479
This commit is contained in:
Matthew Flatt 2005-12-02 05:28:30 +00:00
parent d7029f6406
commit e86f372261

View File

@ -228,8 +228,15 @@ A test case:
(send top-level-window close-status-line 'browser:hyper.ss)) (send top-level-window close-status-line 'browser:hyper.ss))
(define/public reload (define/public reload
;; The reload function is called in a non-main thread,
;; since this class is instantiated in a non-main thread.
(opt-lambda ([progress void]) (opt-lambda ([progress void])
(when url (when url
(let ([s (make-semaphore)]
[closer-t #f]
[this-t (current-thread)])
(queue-callback
(lambda ()
(init-browser-status-line top-level-window) (init-browser-status-line top-level-window)
(update-browser-status-line (update-browser-status-line
top-level-window top-level-window
@ -237,6 +244,19 @@ A test case:
(cond (cond
[(url? url) (url->string url)] [(url? url) (url->string url)]
[else "page"]))) [else "page"])))
;; Yikes! We need to ensure that the browser status
;; line is closed, even if the reload thread dies.
;; We use the usual trick of setting up a watcher
;; thread and then killing it off if its work
;; is not needed.
(set! closer-t
(thread (lambda ()
(sync (thread-dead-evt this-t))
(queue-callback
(lambda ()
(close-browser-status-line top-level-window))))))
(semaphore-post s)))
(yield s)
(let ([headers (get-headers/read-from-port progress)]) (let ([headers (get-headers/read-from-port progress)])
;; Page is a redirection? ;; Page is a redirection?
(let ([m (regexp-match "^HTTP/[^ ]+ 301 " headers)]) (let ([m (regexp-match "^HTTP/[^ ]+ 301 " headers)])
@ -249,7 +269,12 @@ A test case:
(combine-url/relative url loc)] (combine-url/relative url loc)]
[else [else
(string->url loc)]))))))) (string->url loc)])))))))
(close-browser-status-line top-level-window)))) (queue-callback
(lambda ()
(kill-thread closer-t)
(close-browser-status-line top-level-window)
(semaphore-post s)))
(yield s)))))
(define/private (get-headers/read-from-port progress) (define/private (get-headers/read-from-port progress)
(cond (cond
@ -260,8 +285,7 @@ A test case:
(let* ([busy? #t] (let* ([busy? #t]
[stop-busy (lambda () [stop-busy (lambda ()
(when busy? (when busy?
(set! busy? #f) (set! busy? #f)))])
(end-busy-cursor)))])
(with-handlers ([(lambda (x) (and (exn:fail? x) busy?)) (with-handlers ([(lambda (x) (and (exn:fail? x) busy?))
(lambda (x) (lambda (x)
(call/input-url (call/input-url
@ -367,7 +391,6 @@ A test case:
#f ; should be calling window! #f ; should be calling window!
#f #f
orig-name))]) orig-name))])
(begin-busy-cursor) ; turn the cursor back on
(when tmp-plt-filename (when tmp-plt-filename
(let* ([d (make-object dialog% (string-constant downloading) top-level-window)] (let* ([d (make-object dialog% (string-constant downloading) top-level-window)]
[message (make-object message% [message (make-object message%
@ -450,7 +473,15 @@ A test case:
(current-load-relative-directory))]) (current-load-relative-directory))])
(parameterize ([html-status-handler (parameterize ([html-status-handler
(lambda (s) (lambda (s)
(update-browser-status-line top-level-window s))] (let ([t (current-thread)])
(queue-callback
(lambda ()
(when (thread-running? t)
;; Since t is running, the status line hasn't been
;; closed by the watcher thread (and there's no
;; race, because it can only be closed in the
;; handler thread)
(update-browser-status-line top-level-window s))))))]
[current-load-relative-directory directory] [current-load-relative-directory directory]
[html-eval-ok (url-allows-evaling? url)]) [html-eval-ok (url-allows-evaling? url)])
(html-convert p this)))] (html-convert p this)))]
@ -470,7 +501,6 @@ A test case:
(end-edit-sequence)]))) (end-edit-sequence)])))
(lambda () (lambda ()
(end-edit-sequence) (end-edit-sequence)
(end-busy-cursor)
(set! htmling? #f) (set! htmling? #f)
(set-modified #f) (set-modified #f)
(auto-wrap wrapping-on?) (auto-wrap wrapping-on?)
@ -733,21 +763,31 @@ A test case:
;; if cust is shutdown, the url will stop being loaded and a dummy editor is returned. ;; if cust is shutdown, the url will stop being loaded and a dummy editor is returned.
(define (make-editor/setup-kill cust html-editor% tlw init-url progress post-data remap-url) (define (make-editor/setup-kill cust html-editor% tlw init-url progress post-data remap-url)
(let* ([c (make-channel)] (let* ([c (make-channel)]
[progs (make-channel)]
[sent-prog? #f]
[t (parameterize ([current-custodian cust]) [t (parameterize ([current-custodian cust])
(thread (thread
(lambda () (lambda ()
(with-handlers ([exn? (lambda (exn)
(channel-put c exn))])
(channel-put (channel-put
c c
(make-editor/follow-redirections html-editor% (make-editor/follow-redirections html-editor%
tlw tlw
init-url init-url
progress (lambda (v)
(channel-put progs v))
post-data post-data
remap-url)))))] remap-url))))))]
[ans #f]) [ans #f])
(let loop ()
(yield (yield
(choice-evt (choice-evt
(handle-evt c (lambda (x) (set! ans x))) (handle-evt c (lambda (x) (set! ans x)))
(handle-evt progs (lambda (v)
(set! sent-prog? #t)
(progress v)
(loop)))
(handle-evt (thread-dead-evt t) (handle-evt (thread-dead-evt t)
(lambda (_) (lambda (_)
(let ([t (new hyper-text% (let ([t (new hyper-text%
@ -755,7 +795,9 @@ A test case:
(top-level-window tlw) (top-level-window tlw)
(progress void))]) (progress void))])
(send t insert "Stopped.") (send t insert "Stopped.")
(set! ans (cons t #f))))))) (set! ans (cons t #f))))))))
(unless sent-prog?
(progress #f))
ans)) ans))
;; make-editor/follow-redirections : editor-class frame%-instance ;; make-editor/follow-redirections : editor-class frame%-instance
@ -873,6 +915,7 @@ A test case:
(cond (cond
[on? [on?
(send stop-button enable #f) (send stop-button enable #f)
(when choice (send choice enable #t))
(update-buttons)] (update-buttons)]
[else [else
(send stop-button enable #t) (send stop-button enable #t)