I’ve got a polymorphic object o and two threads T1 and T2.
The destructor of o‘s most derived class waits for the termination of T2 before returning.
Is it safe to let T1 delete o while T2 is calling some virtual functions of o? (I mean without using mutual exclusion or any other kind of synchronization mechanisms)
I believe it should be safe unless delete is allowed to modify o (like its pointer to the vtable) even before the completion of the first destructor called. Is this the case?
First, if you can avoid this, it is fragile and error prone. You can make it work, but small changes in the code can break it.
If the only thing that the block in the complete object destructor does is waiting for the completion of the other thread, and assuming that the base objects have virtual destructors or that the complete object is destroyed directly, then it is safe to do so. None of the members of the object are destroyed before the body of the destructor completes, and neither are the bases. That means that none of the subobjects that the other thread is using will be destroyed before it completes (and lets the first thread complete the body of the destructor).
That being said, again, try to redesign the code.