Here is some logic:
A::~A() {
b.foo(this)
}
void B::foo(A*) {
.. try to get lock ..
.. remove the A object from some state ...
}
void B::bar() {
... try to get lock ...
... do some work on the A objects ...
}
This isn't a design question. The above could potentially be done differently.
Suppose that we have some thread of execution that has called bar()
. One of the A
objects goes out of scope and its destructor is called. Is it valid to continue to make use of that A
object in bar()
, knowing that it's destructor would attempt to get the same lock that you hold?
In other words, is it valid to continue to use an object during its destructor?
I read several threads and the answer was inconclusive.
foo
function removes the relevantA
object from the state thatbar
accesses @user17732522 – DieciousA
has avirtual
member function, then, while the destructor runs, it should behave as if it wasn'tvirtual
. However, to achieve that in a typical implementation the vtable ptr must be overwritten at the beginning of the destructor call. That overwrite is unsynchronized with your use inB::bar()
and a race. Tools like thread sanitizer will tell you that, too. – Flavourfulvirtual
member function inB::bar
(and other similar operations) must cause undefined behavior and I suspect that the other cases currently are underspecified. – FlavourfulA *pa
inB::bar
? How you ensured thatpa
is valid during you use it, and you not try use it afterpa
delete at all ? I be say code/description incomplete for answer – Mountstatic
or ashared_ptr
. Don't sendreference_wraper
instances to threads and don't capture references in lambdas that threads run. – Ferryboat