A concurrent control structure acts like a control structure (synchronous - closures passed to it do not escape, non-local return makes sense), but it may execute in multiple threads.
This is fundamentally hard to do safely in the Java thread model, but that's a problem for the person writing the control structure, not the user. Except that synchronization must be handled explicitly by the user, so it's not entirely transparent when concurrency is happening.
Non-local control flow (non-local return, break or continue (even goto?)) must be handled "correctly" in a concurrent setting too. If one concurrent thread executes a non-local return (as it should be allowed to, since it is a synchroneous control structure), the control structure should exit gracefully, including stopping its other threads, and allow the non-local return to proceed from the originating thread. If more than one thread tries to do a non-local return, the control structure must ensure that only one of them takes effect.
Its clear that a non-local return from one thread to another will need to end the returning thread abruptly. It also needs to pass this information to its creator, so that the creator can clean up properly, and it will eventually reach the thread that the closure came from, so that the non-local return can be executed.
Currently, when a thread does something non-local that either doesn't exist any more, or not on the current thread, a
UnmathedNonlocalTransfer exception is thrown.This allows noticing a non-local return, but not propagating it to its appropriate thread.
Idea: When a non-local control transfer fails, create a synthetic closure (one that doesn't correspond to a closure literal in the program) that only contains the execution of the non-local return itself. It will have type
{=> Unreachable}.This is passed in the
UnmatchedNonlocalTranfer, so that the exception not only reports that an operation failed, but also provides the operation so that it can be retried.Anybody reacting to the thread's death can get this closure and reactivate the non-local return. Only in the correct thread, the one with the stack frame actually being returned from, will it work and perform the non-local return. In all other threads it will just cause that thread to die too with a new
UnmatchedNonlocalTransfer. Caveat Invocator.
No comments:
Post a Comment