Comments (6)
@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.
@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.
@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.
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.
@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.
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)
- macos::OsIpcSharedMemory::from_bytes aborts if passed an empty slice
- Implement `std::error::Error` on error types
- IpcBytesSender::send will hang up when receiver is not work. HOT 1
- Panic on large data transfer HOT 1
- IpcReceiver hang, forking leaks file descriptors, problem/discussion HOT 1
- Release a new version HOT 2
- panic when some conditions
- Could you please publish a new version to crates.io?
- cargo-careful panics due to `stat` being left uninitialized
- Channel between 64-bit and 32-bit process
- Trivial Example Not Working HOT 6
- Why can I only connect to IpcSender and not IpcReceiver? HOT 8
- IpcOneShotServer::accept is blocking and has no non-blocking version HOT 2
- Vulnerability in crossbeam-utils dependency HOT 1
- Apple recommends against direct use of Mach
- Sending an IpcReceiver over a previously sent IpcChannel doesn't work on Windows
- macOS builds are broken with recent rustc HOT 2
- Doc page not being updated HOT 1
- Panic post upgrading from rustc 1.66 to later versions on MacOS
- Ability to set custom name for the server
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ipc-channel.