<div dir="ltr">This won't work I don't think.<div><br></div><div>You can't move a computation to another thread like that unless the computation is willing to be moved (and random Racket programs will not have set themselves up to be moved).</div>
<div><br></div><div>If you're not worried about running in unix headless contexts, then I think all you need is a way to avoid the "bring the newly created GUI racket presence to the front" under mac os x. And then you should just always do things on an eventspace.</div>
<div><br></div><div>Robby</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Apr 5, 2014 at 1:12 PM, Greg Hendershott <span dir="ltr"><<a href="mailto:greghendershott@gmail.com" target="_blank">greghendershott@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Yes, that aspect of it -- attaching the racket/gui/base module, if<br>
any, from the old namespace to the new one -- I figured out fairly<br>
fast and it has been working fine in my testing so far.<br>
<br>
The tricky part is that I seem to need a hypothetical<br>
"custodian-shutdown-all-except-the-root-main-eventspace-in-queue.rkt",<br>
or, a "please-revive-the-main-eventspace".<br>
<br>
Either that, or, I need to insinuate myself into the load process so I<br>
can notice that racket/gui/base is about to be required for the first<br>
time, setup a separate custodian and require it msyelf, then set<br>
_another_ custodian for the user module. That way I could do a<br>
custodian-shutdown-all with the latter custodian, leaving the main<br>
eventspace untouched. I think.<br>
<br>
Or I could just punt it onto the user with a "hey I'm going to run a<br>
GUI" command or flag they need to use. Which might be the sane thing<br>
to do. I'm just not quite ready to give up and settle for that.<br>
<div class="HOEnZb"><div class="h5"><br>
On Sat, Apr 5, 2014 at 10:04 AM, Robby Findler<br>
<<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>> wrote:<br>
> Oh, and I see a second issue that you're probably getting at: in the case<br>
> you decide you are going to run GUI programs (via the emacs-level variable<br>
> if you don't find a better way than my recommendation) you need to share<br>
> '(lib "mred/mred.rkt") (or maybe it is okay to share racket/gui/base)<br>
> between the original namespace that your code created and the user program<br>
> you wish to run.<br>
><br>
> This library is designed to support this form of sharing and is carefully<br>
> implemented not to leak, no matter what nastiness the user program might try<br>
> to do to it (most libraries do not provide such guarantees).<br>
><br>
> Robby<br>
><br>
><br>
> On Sat, Apr 5, 2014 at 8:25 AM, Greg Hendershott <<a href="mailto:greghendershott@gmail.com">greghendershott@gmail.com</a>><br>
> wrote:<br>
>><br>
>> Thank you Robby. I've spent some time thinking about your response,<br>
>> trying to make use of it, and even looking at some<br>
>> mred/private/common/wx code.<br>
>><br>
>> First, I don't grok the need for an extra thread. This is for an Emacs<br>
>> mode REPL. It's quite similar to Racket's xrepl, which doesn't use an<br>
>> extra thread. Although I could create one if necessary, I think it<br>
>> would complicate things when I have a more basic issue regarding<br>
>> `main-eventspace`, custodians, and how/when racket/gui/base gets<br>
>> loaded:<br>
>><br>
>> As an Emacs mode (unlike DrRacket, which is a GUI that needs<br>
>> racket/gui/base itself), I don't want to statically `require`<br>
>> racket/gui/base, because I don't want it loaded until/unless it's<br>
>> actually needed by a user program. (Otherwise, e.g. on OS X, running a<br>
>> non-GUI program, you would get a weird windowless menu bar, and it<br>
>> steals the focus from Emacs.)  So the way that racket/gui/base _first_<br>
>> gets required, is via the dynamic-require of the first user program<br>
>> that happens to require it. As a result the `main-eventspace` state in<br>
>> mred/private/wx/common/queue.rkt (IIUC) is associated with<br>
>> `user-cust`, not `orig-cust`. As a result, custodian-shutdown-all<br>
>> blows that away. And I don't know how to recreate it correctly.<br>
>> Symptom: Subsequent runs of a user program like `(require plot) (plot<br>
>> __)`, result in windows that sit there un-drawn and/or unresponsive to<br>
>> mouse input.<br>
>><br>
>><br>
>> Seems like it could be solved on either "end":<br>
>><br>
>> 1. Somehow try to manage the load process so that the first-ever load<br>
>> of racket/gui/base gets its stuff on orig-cust but the user's stuff on<br>
>> user-cust.<br>
>><br>
>> 2. Somehow re-initialize the main eventspace sufficiently.<br>
>><br>
>> Although 2 seems more plausible and less kludgy, I can't work out how<br>
>> to do it either way.<br>
>><br>
>><br>
>> Some code snippets that might be more understandable than prose:<br>
>><br>
>> ;; (or/c #f path?) -> any<br>
>> (define (run path-str)<br>
>>   (define-values (mod load-dir) (path-string->mod-path&load-dir path-str))<br>
>><br>
>>   ;; Use custodian to release resources.<br>
>>   ;;<br>
>>   ;; The problem here is that this seems to be "too thorough" -- it<br>
>>   ;; boinks `main-eventspace` in mred/private/queue.rkt. Why?  How<br>
>>   ;; racket/gui/base first got loaded was at end of this function,<br>
>>   ;; in the dynamic-require of whatever user module first happened to<br>
>>   ;; use racket/gui/base. (We don't want to load racket/gui/base<br>
>>   ;; in the Emacs mode until/unless it's actually needed). Therefore<br>
>>   ;; `main-eventspace` is created on `user-cust`, and gets blown away<br>
>>   ;; here. Ideally, instead `main-eventspace` would be managed by<br>
>>   ;; `orig-cust`, and everything else about the user program would be<br>
>>   ;; on `user-cust`. But how to do that??<br>
>>   (custodian-shutdown-all user-cust)<br>
>>   ;; New custodian<br>
>>   (set! user-cust (make-custodian orig-cust))<br>
>>   (current-custodian user-cust)<br>
>><br>
>>   ;; Save the current namespace. Save whether it uses racket/gui/base.<br>
>>   (define orig-ns (current-namespace))<br>
>>   (define had-gui? (module-declared? 'racket/gui/base))<br>
>>   ;; Fresh, clear racket/base namespace.<br>
>>   (current-namespace (make-base-namespace))<br>
>><br>
>>   (when had-gui?<br>
>>     (displayln "had-gui? #t")<br>
>>     ;; If racket/gui/base module was instantiated in orig-ns, attach<br>
>>     ;; and require it into the new namespace, and _before_ requiring<br>
>>     ;; the new module. Avoids "cannot instantiate `racket/gui/base' a<br>
>>     ;; second time in the same process" problem.<br>
>>     (namespace-attach-module orig-ns 'racket/gui/base)<br>
>>     (namespace-require 'racket/gui/base)<br>
>><br>
>>     ;; Also need to create an eventspace.  FIXME: Not working with<br>
>>     ;; plot.rkt example. custodian-shutdown-all seems to have borked<br>
>>     ;; the original main eventspace state, and our newly-created one<br>
>>     ;; ain't good enough.<br>
>>     (define (gdr sym)<br>
>>       (dynamic-require 'racket/gui/base sym))<br>
>>     (define current-eventspace (gdr 'current-eventspace))<br>
>>     (define make-eventspace    (gdr 'make-eventspace))<br>
>>     (current-eventspace (make-eventspace)))<br>
>><br>
>>   ;; Load the user module, if any<br>
>>   (when mod<br>
>>     (parameterize ([current-load-relative-directory load-dir])<br>
>>       (dynamic-require mod 0)<br>
>>       (current-namespace (module->namespace mod))))<br>
>>   (current-prompt-read (make-prompt-read mod)))<br>
>><br>
>> Example GUI user program:<br>
>><br>
>> #lang racket<br>
>> (require plot math)<br>
>> (plot-new-window? #t)<br>
>> (plot (function sin (- pi) pi #:label "y = sin(x)"))<br>
>><br>
>><br>
>><br>
>> On Thu, Apr 3, 2014 at 5:49 PM, Robby Findler<br>
>> <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>> wrote:<br>
>> > I think the main missing thing is that the thread you're requiriing the<br>
>> > user's program on should be under the control of the custodian. In other<br>
>> > words, you'll want to create a new eventspace (under the new custodian)<br>
>> > and<br>
>> > queue a callback over to it to require the user's program.<br>
>> ><br>
>> > Robby<br>
>> ><br>
>> ><br>
>> > On Thu, Apr 3, 2014 at 4:26 PM, Greg Hendershott<br>
>> > <<a href="mailto:greghendershott@gmail.com">greghendershott@gmail.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >> So the background for Spencer's question was a problem with my Emacs<br>
>> >> racket-mode when using racket/gui/base.<br>
>> >><br>
>> >> There's a long-ish bug report comment thread. If you want to read it,<br>
>> >> at all, you might want to skip to the last few comments, here:<br>
>> >><br>
>> >><br>
>> >><br>
>> >> <a href="https://github.com/greghendershott/racket-mode/issues/26#issuecomment-39494285" target="_blank">https://github.com/greghendershott/racket-mode/issues/26#issuecomment-39494285</a><br>
>> >><br>
>> >> Or the TL;DR: I probably don't need racket/sandbox at all. I probably<br>
>> >> just need a new namespace and a custodian -- in order to do a<br>
>> >> DrRacket-style "reset the REPL to the source file".<br>
>> >><br>
>> >> Matthew and Robby I know you're both incredibly busy, but if either of<br>
>> >> you had a chance to look at this code, I'd be grateful. Although part<br>
>> >> of me hopes you'll say "perfect!", the older/wiser part of me hopes<br>
>> >> you'll point out X Y and Z problems I don't yet realize I have. It's<br>
>> >> just these 30 lines of code here:<br>
>> >><br>
>> >><br>
>> >><br>
>> >> <a href="https://github.com/greghendershott/racket-mode/blob/experimental/sandbox.rkt#L30-L66" target="_blank">https://github.com/greghendershott/racket-mode/blob/experimental/sandbox.rkt#L30-L66</a><br>

>> >><br>
>> >> On Sun, Mar 23, 2014 at 8:35 PM, Robby Findler<br>
>> >> <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>> wrote:<br>
>> >> > It is safe, however, to share the racket/gui/base that you get with<br>
>> >> > the<br>
>> >> > one<br>
>> >> > in the sandbox.<br>
>> >> ><br>
>> >> > Robby<br>
>> >> ><br>
>> >> ><br>
>> >> > On Sun, Mar 23, 2014 at 7:25 PM, Matthew Flatt <<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>><br>
>> >> > wrote:<br>
>> >> >><br>
>> >> >> Yes, this is a limitation of `racket/gui/base`. On initialization,<br>
>> >> >> the<br>
>> >> >> library must register in various non-composable ways with an<br>
>> >> >> underlying<br>
>> >> >> GUI toolkit (callbacks, Objective-C classes, Win32 classes, etc.),<br>
>> >> >> and<br>
>> >> >> so `racket/gui/base` cannot be instantiated multiple times.<br>
>> >> >><br>
>> >> >> At Sun, 23 Mar 2014 20:12:43 -0400, Spencer Florence wrote:<br>
>> >> >> > I'm attempting to launch multiple evaluators which require<br>
>> >> >> > `racket/gui`,<br>
>> >> >> > however I get the error:<br>
>> >> >> ><br>
>> >> >> > cannot instantiate `racket/gui/base` a second time in the same<br>
>> >> >> > process<br>
>> >> >> ><br>
>> >> >> > Is `racket/gui/base` maintaining some kind of state thats escaping<br>
>> >> >> > the<br>
>> >> >> > sandbox?<br>
>> >> >> ><br>
>> >> >> ><br>
>> >> >> ><br>
>> >> >> ><br>
>> >> >> ><br>
>> >> >> > Example of the problem:<br>
>> >> >> ><br>
>> >> >> > #lang racket/base<br>
>> >> >> > (require racket/sandbox)<br>
>> >> >> ><br>
>> >> >> > (call-with-trusted-sandbox-configuration<br>
>> >> >> >  (lambda ()<br>
>> >> >> >    (define (make)<br>
>> >> >> >      (make-evaluator 'racket/base<br>
>> >> >> >                      #:requires '(racket/gui/base)))<br>
>> >> >> ><br>
>> >> >> >    (make)<br>
>> >> >> >    (make)))<br>
>> >> >> > ____________________<br>
>> >> >> >   Racket Users list:<br>
>> >> >> >   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>> >> >> ____________________<br>
>> >> >>   Racket Users list:<br>
>> >> >>   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>> >> ><br>
>> >> ><br>
>> >> ><br>
>> >> > ____________________<br>
>> >> >   Racket Users list:<br>
>> >> >   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>> >> ><br>
>> ><br>
>> ><br>
><br>
><br>
</div></div></blockquote></div><br></div></div>