Giter Site home page Giter Site logo

Unexpected drop about ipc-channel HOT 6 OPEN

servo avatar servo commented on July 3, 2024
Unexpected drop

from ipc-channel.

Comments (6)

antrik avatar antrik commented on July 3, 2024

@kvark is there a specific situation where you are running into this problem? If so, let's discuss that first before considering the general case...

The pseudo-move semantics for ipc-channel are intended to allow its use as a more or less drop-in replacement for mpsc channels. Admittedly, these semantics are not always ideal for IPC; and there has been some discussion about adding other options. (See #138 etc.)

For the existing interface, I can see how dropping can be unexpected, if your Drop handler does things that affect the "world" across process boundaries. On the other hand, I suspect the majority of Drop handlers actually deal with things that are local to the process -- in which case we do want to drop... So I think users just need to be aware of the drop, and make sure they work around it when necessary. (Probably by wrapping the object in question in an Arc<>; cloning it before the send; and mem::forget() afterwards.)

from ipc-channel.

kvark avatar kvark commented on July 3, 2024

@antrik thanks for taking your time to respond!

is there a specific situation where you are running into this problem?

I don't think the specifics are important here. The API mimics mpsc with a move semantics. The API ends up doing copy semantics, while allowing Drop, which reads like broken semantics to me.

In my case, the destructor was sending an IPC message (somewhat ironically?). So I ended up receiving a message twice with no apparent indicator of why. That wasted quite a bit of my time.

from ipc-channel.

antrik avatar antrik commented on July 3, 2024

@kvark you are right that we aren't implementing perfect move semantics here. The problem is, as I already pointed out, that many objects do need to be destroyed when leaving the process -- so I don't think there is a solution that is correct in all situations, without discriminating per type.

I believe this ultimately boils down to a limitation in the Serde API: it always treats serialisation as a kind of deep-clone; passing only a shared reference to the type-specific serialize() method implementations. To solve this properly, we would need a way to do a "consuming" serialisation instead, where the implementations can decide individually whether to just let the object drop at the end, or to mem::forget() it. (Or maybe yet something different...)

This problem actually comes up in ipc-channel itself: OsIpcReceiver has to emulate a consuming serialisation, by wrapping the data in an interior mutability container; the serialize() method then uses this to unset the value, so the drop handler isn't invoked later on. This is a hack though, which breaks all uses of Serde on the type in question in contexts that do actually want the deep clone semantics...

(It might be possible to enhance this workaround so it only emulates move semantics in an IPC context -- I have a rough idea how to do that, which might or might not work -- but this would be even more hacky...)

It seems to me the only way to solve this properly is by extending Serde, to provide consuming serialisation officially as an option. I think this could probably be done in a pretty non-invasive fashion: in addition to the existing deep-cloning serialize() function, it could expose a consuming_serialize() or serialize_by_value() function, for any type that implements a corresponding ConsumingSerialize/SerializeByValue trait. Just like the existing Serialize trait, this would be available by default for all primitive types and containers (when the inner type has it in turn); and it could be auto-derived for aggregate types if all constituents have it; while other types would have to implement it manually. (Maybe the trait method could even have a default implementation that defers to the ordinary serialize() method, and only needs to be overridden for types that need special handling or want to optimise the move case? Not sure about the details...)

This actually sounds like a pretty interesting task. Unfortunately, I still have a lot of other stuff on my ToDo list for ipc-channel -- so it's not something I could work on myself any time soon...

from ipc-channel.

kvark avatar kvark commented on July 3, 2024

many objects do need to be destroyed when leaving the process

Do you mean the standard library objects (Vec, Arc, etc) or the actual Servo's primitives?

If move semantics can't be safely provided, it shouldn't be exposed. Just drop the mpsc compatibility and have the API taking &object instead of consuming it.

from ipc-channel.

antrik avatar antrik commented on July 3, 2024

@kvark I mean any object referencing process-local resources: be it memory (whether in standard containers or custom types), or system resources such as file descriptors.

The current semantics are quirky, but not unsafe. I totally agree that it would be good to fix them -- and I outlined a way to do so -- but I don't agree that it's so bad that it has to go away entirely.

As for the alternative API, it's a bit more complex than that, since some objects -- including OsIpcReceiver -- need move semantics to avoid other quirks. In #138 (especially the latest comment), I outlined an approach that should work reasonably well I believe -- it's again "just" a matter of implementing it...

from ipc-channel.

gterzian avatar gterzian commented on July 3, 2024

If move semantics can't be safely provided, it shouldn't be exposed. Just drop the mpsc compatibility and have the API taking &object instead of consuming it.

I had never though about it before, and to me having two drops in the above example makes sense.
The "move vs copy" semantics are I think intra-process concepts, and so is Drop. So sending a message indeed moves it into the channel, where it is processed so that the data can then be sent over to another process. The "object" then drops, since it won't have a use in that process after that. The "copy" that is received on the other side is from my perspective not the result of Copy, it's the result of (de)serialization, and in that context it makes sense to think of the two objects as separate, each with their own drops.

Lastly, I think the move on send is not just about compat with mpsc. One could also imagine a send(&msg) mpsc API, however it's not one I would want to use. To me the "move" semantics in both cases are not about the underlying implementation details of cross-thread/process communication. I just wouldn't want to have code still able to do anything with msg after it has been sent, that's all. What "sent" means might differ, and the semantics appear the same to me.

from ipc-channel.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.