I have modelled the behaviour of 2 threads:
Looking at just the first thread, my initial thought was to do Box::from_raw(load_data);
to remove the obsolete pointer.
In line:
let mut load_data = self.ptr.load(Acquire);
I create a lazy pointer that has no lifetime, so there should be a moment later where I explicitly delete it to avoid memory leaks.
What I have planned: In the loop I clone the T
data, which I then make immortal and try to shift the shared pointer to it. If the pointer is not shifted (the second thread did it earlier between load
and compare_exchange
of the first thread), then I don't need this new data anymore, so I delete it:
Err(e) => {
load_data = e;
unsafe {
// leakage prevention
Box::from_raw(new_ptr);
}
}
If I succeeded, we do the same (in a loop) with the pointer to the new data (which was produced by another thread and successfully pointed to it). I don't need the old pointer now, so I delete it:
Ok(load_data) => {
unsafe {
// leakage prevention
Box::from_raw(load_data);
}
break;
}
But then I realised that the moment the old pointer was reset, the parallel thread, could have used it in the moment from ptr
and change
:
in line:
let mut changed_data = unsafe { &mut *load_data }.clone();
which could now indicate non-existent data.
Removed:
unsafe {
// leakage prevention
Box::from_raw(load_data);
}
the tests worked
But it's still a mystery to me: Why would resetting the pointer affect it?
If the reset went through:
Box::from_raw(load_data);
then it means that self.ptr.compare_exchange
was successful and the pointer was shifted. And this in turn should mean that no matter what the parallel thread does with the old ptr
, if it sees on its self.ptr.compare_exchange
that the pointer has been changed by another thread, it will do it all over again (in a loop) with the new pointer. That is, one way or another it will have to achieve its goal with the latest actual data.
At the end of the day I don't understand why pointer resetting affects the fact that the pointer to inactive data is saved in the main shared pointer.