Forgot to copy the list.

-------- Original Message --------
Subject:        Re: [rust-dev] Cloning managed memory between tasks?
Date:   Thu, 21 Feb 2013 17:12:39 -0800
From:   Brian Anderson <[email protected]>
To:     Ashish Myles <[email protected]>



On 02/20/2013 08:24 PM, Ashish Myles wrote:
On Wed, Feb 20, 2013 at 10:56 PM, Brian Anderson <[email protected] <mailto:[email protected]>> wrote:

    On 02/20/2013 06:38 PM, Ashish Myles wrote:

        I didn't much previous discussion on this topic on google.
        Sorry if I missed something and re-starting an old discussion.

        Here is an example from the manual of a standard lisp-style list.
         enum List<T> {
           Nil,
           Cons(T, @List<T>)
         }
        If one wished to move such a list to another task, a copy to
        unique
        pointers would be needed. But it seems that this data
        structure doesn't
        support any way of unique-ifying it, it would have to be copied to
        a transferable data structure (like ~[T])
        and reconstructed on the other side. As converting to another
        container
        might not be as optimal for, say a tree or more complex data
        type, is
        there another way to deal with such a use-case?
        I see a serialization/de-serialization approach was suggested
        here:
        https://github.com/mozilla/rust/issues/3836
        Perhaps, a viable alternative would be to have a cloning
        procedure (given
        two tasks specified) that creates managed memory only on the
        receiving
        side while cloning?  Something like a "copy to that task's
        heap and send
        it a pointer" functionality ?


    If you are ok with serialization (and want to implement it for
    `List`) then `std::flatpipes` should be able to send `List`.

    Without resorting to reflection, one thing we could possibly do is
    allow the current task to swap its heap with another, then just
    call the standard `.clone()` method, cloning into the new heap. At
    that point you could put that heap into another task. With some
    care such a thing could possibly by wrapped up into a safe
    interface, but it's kind of a scary notion to be swapping heaps.


As list was just an example (not needed for anything at the moment), I was indeed hoping for something general-purpose. Perhaps one could think in terms of accessing the receiving task's heap via some antiseptic intermediate task rather than swapping heaps if it seems scary. Task 2 would be blocked for the duration.

Speaking conceptually, say task 1 wanted to clone into task 2's heap and say they are connected by a channel chan. Assuming that chan has meta-information (accessible only unsafely) about the tasks to which it is connected, then one could invoke the following in task 1
    chan.send_clone(obj)
This would block both task 1 and task 2 until completed. It could create an auxiliary task connected to the heap of task 2 and invokes a deep_clone() on obj. This would, of course, mean that the deep_cone() cannot access any globals. Optionally, a post-clone sweep through the cloned object could be used ensure that no pointers point to task 1's heap.


Something like you describe could be done, though I'm not sure how to implement deep_clone without either swapping the heaps or adding some kind of factory for creating boxes in a different heap. Rust doesn't have globals yet, and when it does they will require unsafe to mutate so I don't think there's a problem with globals. You do need to prevent `deep_clone` from mutating itself and storing a pointer to the wrong heap, which may be possible with the `Const` kind, depending on how it works with @ boxes. You also need to do the opposite and avoid putting pointers to your own boxes in the opposing heap, which I don't know how to do without, as you say, some introspection.




_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to