On 05/07/2017 02:29 AM, Marcel Mueller wrote:
> Who destroyed the old object at old_ptr before this placement new?
>
> Can no one else access the object behind obj_ptr which is still an entry
> in _effect_object_buf at this point?
>
>
>> The report Valgrind is giving on the crash is that I'm performing
>> invalid reads on blocks that are already free-d.
>
> Probably. This explains the pure function exception, but a race with
> placement new could result in a similar problem.
>
>
> Marcel
Thanks, the reason for the segfault appears to be indeed that I was,
like a dummy, not destructing the old objects prior to placing the new ones.
The reason I'm recycling the pointers from back to front is basically
because those addresses have already been allocated and "handed off" to
the display thread in the form of weak_ptrs at startup prior to
initialization of the logic thread. This buffer of "effect objects" is
contained within another object that handles the logic of the main
object to which the motion blur effect is being applied; a pointer to
its sprite object is also handed off to the display thread in the same
fashion.
I don't think I can dynamically allocate new blocks of the buffer with
new addresses without having to implement some observer for the display
thread that watches every object for whenever anything changes.
If the containing object is destroyed then the use count of all those
shared_ptrs drops to zero, and the display thread can simply check that
to dump them from its list of active objects on the display. If I then
want to resurrect Super Mario and make him appear back on the screen
then yeah I will need to have the display-thread re-acquire a new set of
pointers, but I can have it simply observe the logic thread as a whole
for when things change, rather than every individual type of object.
That's the idea.
If I perform the operations in this sequence:
auto obj_ptr = _effect_object_buf.back().get();
obj_ptr->~DisplayObject2D();
new (obj_ptr) DisplayObject2D(*_effect_target);
_effect_object_buf.push_front(std::move(_effect_object_buf.back()));
_effect_object_buf.pop_back();
everything seems to work fine with no lock on these operations required,
only the weak_ptr lock when the display thread accesses them. It hasn't
happened in testing at least, but I'm not experienced enough with
threading to know if there's actually a race hazard doing it this way,
or not.