[racket] DrRacket locking up on errors in non-GUI worker threads

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Wed Aug 24 20:08:04 EDT 2011

On Wed, Aug 24, 2011 at 7:07 PM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> What is "the GUI thread"? Do you mean the DrRacket's eventspace
> handler thread, or the user's eventspace handler thread?
>
> If you mean DrRacket's, then that's wrong, unless the errors are
> internal errors that aren't supposed to happen-- if they are errors
> that are potentially due to the user's program having a bug, then you
> should do that.

(sorry: should not)

> Did you use a kill-safe async channel? What do you do when the user's
> side gets killed and the requests pile up?
>
> You might try a program like this:
>
>  #lang racket/gui
>  (thread (lambda () (sleep (random 10)) (custodian-shutdown-all)))
>  ... produce one of the snips ...
>
> and see if you can get things to crash.
>
> Robby
>
> On Wed, Aug 24, 2011 at 7:01 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
>> FWIW, here's what worked:
>>
>>  - A synchronous command channel
>>  - An asynchronous result channel
>>  - Raising errors only on the GUI thread
>>
>> Having one asynchronous channel for commands and results was bad, as it was
>> too easy for the GUI thread to read its own commands before the renderer
>> could get and process them. Caused weird errors. Raising errors on the
>> renderer threads killed their command loops.
>>
>> Neil T
>>
>> On 08/24/2011 04:48 PM, Jay McCarthy wrote:
>>>
>>> async-channel-put is the one that doesn't block
>>>
>>> Sent from my iPhone
>>>
>>> On 2011/08/24, at 16:42, Neil Toronto<neil.toronto at gmail.com>  wrote:
>>>
>>>> Oh! I've been laboring under the delusion that channel-put doesn't block,
>>>> only channel-get. That would explain a lot.
>>>>
>>>> I'll try some of this kill safety stuff. Where's the paper?
>>>>
>>>> Neil T
>>>>
>>>> On 08/24/2011 03:47 PM, Robby Findler wrote:
>>>>>
>>>>> It seems like the exception stops the render-thread from doing a
>>>>> channel-get so the channel-put that drracket does blocks forever.
>>>>> Right?
>>>>>
>>>>> Have you read the kill safety paper? I think that you'd need to use a
>>>>> pattern like that to make this really work. After all, the user's
>>>>> program can be terminated at any time and the repl might still contain
>>>>> those snips that are trying to draw themselves without someone to talk
>>>>> to on the other side.
>>>>>
>>>>> Assuming you've read that paper, then I think the thing you want to do
>>>>> is set up a thread that just listens for requests for user-side state
>>>>> and answers them. This thread will be on the user's thread and subject
>>>>> to random killing (so use the kill safety stuff to deal with that).
>>>>> Then, do everything else on the DrRacket side where you're safe from
>>>>> killing.
>>>>>
>>>>> Robby
>>>>>
>>>>> On Wed, Aug 24, 2011 at 4:27 PM, Neil Toronto<neil.toronto at gmail.com>
>>>>> wrote:
>>>>>>
>>>>>> I can't keep DrRacket from locking up whenever an exception is raised
>>>>>> on a
>>>>>> non-GUI thread that does work in response to a channel-put from the GUI
>>>>>> thread.
>>>>>>
>>>>>> I've attached simplified code for a custom snip% and its non-GUI render
>>>>>> thread. The code contains commented-out attempts at solving the lock-up
>>>>>> problem and comments underneath that say what the solutions actually
>>>>>> did.
>>>>>>
>>>>>> Details:
>>>>>>
>>>>>> I've got a descendant of image-snip% that needs to be updated
>>>>>> periodically.
>>>>>> Rendering the update depends on a zillion parameters, which I MUST get
>>>>>> from
>>>>>> the program thread, not the GUI thread. If I got parameters from the
>>>>>> GUI
>>>>>> thread, setting parameters in the program thread before creating the
>>>>>> snip
>>>>>> wouldn't affect later rendering, which would be bad.
>>>>>>
>>>>>> To ensure that rendering uses parameters from the program thread, I
>>>>>> start a
>>>>>> rendering thread upon creating the snip. The rendering thread inherits
>>>>>> the
>>>>>> program thread's current parameters.
>>>>>>
>>>>>> When the snip updates, it uses channel-put on the GUI thread to tell
>>>>>> the
>>>>>> rendering thread to render. When the rendering thread finishes, it uses
>>>>>> channel-put to return the result.
>>>>>>
>>>>>> When the snip is copied, the copy needs a new rendering thread. I have
>>>>>> the
>>>>>> old rendering thread create a new rendering thread for the copy. The
>>>>>> new
>>>>>> thread's parameters are what the program thread's parameters were when
>>>>>> the
>>>>>> original snip was created.
>>>>>>
>>>>>> This all works just great, no problems.
>>>>>>
>>>>>> Until there's an error. Then I can't keep this silly tower of threads
>>>>>> from
>>>>>> locking up DrRacket, even if I catch the errors and silently ignore
>>>>>> them!
>>>>>>
>>>>>> Help, please?
>>>>>>
>>>>>> Neil T
>>>>>>
>>>>>>
>>>>>> _________________________________________________
>>>>>>  For list-related administrative tasks:
>>>>>>  http://lists.racket-lang.org/listinfo/users
>>>>>>
>>>> _________________________________________________
>>>> For list-related administrative tasks:
>>>> http://lists.racket-lang.org/listinfo/users
>>
>>
>



Posted on the users mailing list.