Arc Forumnew | comments | leaders | submitlogin
Can ccc raise the dead?
4 points by dido 4702 days ago | 2 comments
I think I may have found another possible bug in Arc that relates to the interaction of ccc with threading. What happens when you invoke a continuation created by a thread that is already dead? For instance:

    arc> (= thr (do (= x nil) (thread (do (ccc (fn (c) (= x c))) (prn "alive") (sleep 5) (prn "dead")))))
    #<thread: thr>
    arc> alive
    (dead thr)
    nil
    ;; five seconds later
    arc> dead
    (dead thr)
    t
    arc> (x 1)
    alive
    > (dead thr)
    reference to undefined identifier: dead
    
    === context ===
    /usr/local/racket/lib/racket/collects/racket/private/misc.rkt:85:7
    
    > 
I suppose something odd is happening here to say the least. I also wonder what would happen in general if a continuation is invoked from a different thread than the one that created it. Trying to do the same thing in Arc 3.1, by extending the sleep time in the thread above to say, 300 seconds, and then invoking the continuation before the timeout, again drops me into a Racket prompt, after printing 'alive' and 'dead' twice.

What do you guys suppose should be the proper behavior in this case? I am for the moment disallowing the invocation of continuations from any thread except the one that created them in Arcueid, but I would also like to hear other opinions on what to do in this case. For instance, what does Racket do when faced with the same situation of continuations escaping from their threads?



3 points by rocketnia 4702 days ago | link

I Googled [racket continuation thread] and got lucky: (http://docs.racket-lang.org/reference/cont.html#(def._((quot...)

"A continuation can be invoked from the thread (see Threads) other than the one where it was captured."

Okay, that's not very helpful on its own.... The rest of the Racket docs don't seem to help either.

---

Based on nothing but intuition, what I expect to happen in your example is for the REPL thread to print "alive", sleep for the specified amount of time, print "dead", and terminate.

Now that I mention it, that could be what you're seeing. XD I don't know why "dead" didn't print in the full transcript you posted, but maybe the thread terminated before it got a chance to flush? How long did it take for the Racket REPL to appear?

By the way, you say "Trying to do the same thing in Arc 3.1," but what was the first attempt in? I'm guessing Anarki, but maybe it was some member of the Nu family. :)

If you say (thread (x 1)), does that act the same as the first thread? At the least, I'm guessing it won't wipe out the REPL.

-----

3 points by dido 4702 days ago | link

Hmm, considering the behavior we're seeing, I think that the following is true: a continuation captured from a different thread will execute in the thread that invokes it, not in the thread it comes from, thus ccc doesn't have the ability to resurrect the dead, nor will it interrupt execution of the thread that is already running. This is the reason why invoking the continuation above from the REPL kills the REPL. The REPL thread was "possessed by the spirit of the continuation" so to speak, so when the continuation terminated so did it, and thus we got dumped into the Racket REPL. I suppose that what Arcueid should do in order to emulate this behavior is terminate when the continuation finishes execution, because its REPL thread would then exit when the continuation returned to nowhere.

I suppose endowing ccc with the power of necromancy is a little too much. XD

-----