chan: fix crash when AnimControl is destroyed in threaded pipeline

See #254 for related discussion.
This commit is contained in:
rdb 2018-02-24 12:15:56 +01:00
parent b72d1c198f
commit a5beccc99e
3 changed files with 22 additions and 1 deletions

View File

@ -103,7 +103,7 @@ fail_anim(PartBundle *part) {
*/
AnimControl::
~AnimControl() {
get_part()->set_control_effect(this, 0.0f);
get_part()->control_removed(this);
}
/**

View File

@ -539,6 +539,25 @@ control_activated(AnimControl *control) {
}
}
/**
* Called by the AnimControl when it destructs. This needs to remove the
* AnimControl pointer from all pipeline stages.
*/
void PartBundle::
control_removed(AnimControl *control) {
nassertv(control->get_part() == this);
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
ChannelBlend::iterator cbi = cdata->_blend.find(control);
if (cbi != cdata->_blend.end()) {
cdata->_blend.erase(cbi);
cdata->_anim_changed = true;
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
/**
* The internal implementation of bind_anim(), this receives a pointer to an
* uninitialized AnimControl and fills it in if the bind is successful.

View File

@ -149,6 +149,7 @@ public:
// The following functions aren't really part of the public interface;
// they're just public so we don't have to declare a bunch of friends.
virtual void control_activated(AnimControl *control);
void control_removed(AnimControl *control);
INLINE void set_update_delay(double delay);
bool do_bind_anim(AnimControl *control, AnimBundle *anim,
@ -204,6 +205,7 @@ private:
typedef CycleDataLockedReader<CData> CDLockedReader;
typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageWriter<CData> CDStageWriter;
public:
static void register_with_read_factory();