<ysantoso-rubytalk / jenny-gnome.dyndns.org> schrieb im Newsbeitrag
news:87n041mebw.fsf / dessyku.is-a-geek.org...
> Hi,
>
> I was wondering why a Continuation is not callable across threads.
>
> From the definition at wikipedia:
>
> "a continuation saves the execution state of a program at a given
> point so that it's possible to resume execution from that state at a
> later point in time."
>
> If one takes a thread for what it actually is, which is a
> stream-of-execution, then I fail to see a reason, beside the one described
> below, why one thread cannot call a Continuation object generated from
> another thread.
>
> Why can't the thread use the execution state information saved within
> a continuation to recreate the execution state, thus resuming the
> suspended execution.
>
> One argument against this capability is that the following code will
> may not be correct:
>
> $ = nil
> t =Thread.new {
>   until $todo != nil; end
>   $todo.call
>   $todo = nil
> }
>
> def foo
>   Thread.current[:counter] = 0
>   callcc{|cc|
>     $todo = cc
>     return
>   }
>   puts "Counter is 0: #{Thread.current[:counter]}" # --> but counter may
not be 0
>   # code depending on thread-specific storage does not operate
>   # correctly if resumed from another thread.
> end
>
> foo
> t.join
>
>
>
> However, I feel that this is more of a discipline issue on the part of
> the programmer. If your code depends on thread-specific storage, don't
> resume from another thread.

Every continuation depends on thread specific data, namely the call stack.

> So, what is the reason for the restriction? Is there some conceptual
> issue with continuations being callable from across threads, or is
> this just implementation-specific issue?

You'd have to options that seem to be equally bad:

1. One thread's complete state is cloned and resumed in another thread
context.  That means effectively that on thread disappears.  And suddenly
you would have to solve all kinds of synchronization problems you weren't
expecting: assume, you use an instance X in one thread that is thread local
and thus not seen by any other thread.  You will not synchronize access to
this instance since it's confined to a single thread.  Now, if that thread
is cloned than all of a sudden there are two threads sharing this
instance...

2. The invocation of the continuation makes the continuation's original
thread stop and resume the continuation.  This will lead to unexpected
context switches and all kinds of strange behavior.  And what happens to the
calling thread?  Where does execution resume?  Is the call suddenly
asynchronous?  That would not fit well with the rest of Ruby since all
method invocations are synchronous.  And you'd have to make sure that no
return value is used (which is normally done with continuations).  If the
call is not asynchronous the calling thread must effectively be blocked
until the cont returns - but then it's not sure that this will happen at all
plus you don't need multipe threads if you have only one thread working and
the other blocked.

In short: I don't see how continuations and threads mix well.

Regards

    robert