I was thinking about a function I've written which does some multithreaded magic in its implementation. The main logic of this function can be implemented in two ways:
- By initializing new data structures for each call
- By reusing cached data in
self
The benefit of the latter is that it is slightly faster. The downside, which the first design doesn't have, is that I need to protect against multiple simultaneous calls on the same object.
... or do I?
I think I came to a realization: A method which has &mut self
has an an interesting side effect that it can not be called simultaneously. Even if someone puts the object in an Arc
and passes it to another thread and tries to call it it won't work because it violates the mut
constraint. And if one puts it in an Mutex
.. well, locking etc.
So assuming:
impl Foo {
pub fn send(&mut self, blah: Blah) {
}
}
.. is it conceptually correct to read the &mut self
as "will never be called reentrantly"? (Sans unsafe
hackery). I really want this to hold true for all non-unsafe
cases, because it greatly simplifies one method I'm currently working on.
How future proof would an "&mut self
=> never reentrant" invariant assumption be?