// Bah. Resending with the correct title, in hopes this gets threaded
properly in the archives. Sorry for the duplication.

On Sat, Sep 21, 2013 at 10:37 PM, Jason E. Aten <[email protected]> wrote:

> On Fri, 20 Sep 2013 Brian Anderson  wrote:
> >> On 09/19/2013 11:40 PM, Jason E. Aten wrote:
> >> Perhaps the best thing is just to fork(2), so we get a new (OS level)
> >> process that has copy-on-write (virtual) memory, and if the
> >> compilation + run succeeds in the child, then have the child "take
> >> over". Otherwise the child dies with an fail! + location message, and
> >> we return to the parent exactly before the child was spawned.
> >
> > It seems a shame to be relying on process isolation instead of tasks. If
> > I were to just imagine the architecture of a repl that used task
> > isolation for crash recovery it might have one task for accepting input
> > and another as a sandbox that maintains the repl state and executes
> > commands in a loop.
>
> Yes, it seems a shame. It's even worse than a shame. It adds demands.
> Using fork(2) demands a single-threaded runtime. Tasks don't require a
> single threaded runtime. And tasks are more portable. Using fork(2) might
> mean only supporting Linux or Linux & OSX at first.  Windows support might
> require cygwin's fork implementation, whereas tasks are everywhere.
>
> So I agree. It seems a shame. I want to do it with tasks only. I just
> don't see how. How can we do this with tasks and get the desired rollback
> on fail!()?
>
> I'll detail the problem a little. With only tasks, how do we rollback
> changes to global state made by pre-compiled library functions that are
> called from JIT-ed and run code? The task doesn't know what the arbitrary
> code has done, so the task can't roll it back. Any functions in an
> arbitrary C library, any unsafe Rust functions, and the JIT-compilation
> itself will have updated global memory, the llvm module's symbols, etc.
> Since we've fail!-ed at the end of an arbitrarily long sequence of code,
> now we want that reverted all that cleanly and completely. How would a task
> do that?
>
> I've been down that road for syntax errors before. I've implemented
> rollback of everything that the LLVM-JIT added to an llvm module. It was a
> pain, I had to track everything that the llvm jit-compiler did, so I could
> roll back on syntax error. It was brittle, introducing a myraid of
> undersirable code-interactions and logging to the current transaction code
> intertwined with every llvm call. It was a pain, but it worked--for syntax
> error rollback.
>
> But here we're not talking about *just* rolling back on syntax error. We
> want to roll back not only the effects of a partial JIT-compilation, but to
> also rollback after *running that code*.  That code can call into
> *arbitrary global memory modifying code*. All that we know is that an
> arbitrary set of changes to the process image has ended in a fail!().
>
> I'm certainly open to alternatives.  How will that alternative address the
> rollback on fail!() problem?
>
> Process isolation and using the copy-on-write/hardware (MMU) support for
> copy-on-write virtual memory has been engineered for just this job. It fits
> the situation like a glove. As a bonus: we get rollback of file handle
> changes and all the other OS objects that are duplicated by fork(2).
>
> Jason
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to