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

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

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.

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.