This works around a subtle memory corruption.
Consider the following chain of events:
- KikiAction::finished() is called
- This method calls KikiActionObject::actionFinished(), a virtual method
- Some implementations of this method (e.g. KikiBotFume's) delete
themselves ("delete this;")
- The destructor of KikiActionObject deletes all associated actions,
which includes the KikiAction whose finished() method is still executing!
- And this finished() method goes on to read/write freed memory.
I haven't found a proper fix, so this hack will have to do.
Peter De Wachter (pdewacht@gmail.com)
placed in the public domain
Status: in upstream CVS
--- a/src/base/KikiAction.cpp
+++ b/src/base/KikiAction.cpp
@@ -19,6 +19,8 @@
mode = m;
duration = d;
event = NULL;
+
+ delete_flag_ptr = NULL;
reset();
}
@@ -32,6 +34,8 @@
duration = d;
event = NULL;
+ delete_flag_ptr = NULL;
+
reset();
}
@@ -40,6 +44,7 @@
{
if (event) event->removeAction(this);
if (action_object) action_object->removeAction(this);
+ if (delete_flag_ptr) *delete_flag_ptr = true;
}
// --------------------------------------------------------------------------------------------------------
@@ -50,9 +55,18 @@
void KikiAction::finish () { action_object->finishAction (this); }
// --------------------------------------------------------------------------------------------------------
void KikiAction::finished ()
-{
+{
+ bool delete_flag = false;
+ delete_flag_ptr = &delete_flag;
+
action_object->actionFinished(this);
+ if (delete_flag)
+ {
+ return;
+ }
+ delete_flag_ptr = NULL;
+
if (current == getDuration()) // if keepRest wasn't called -> reset start and current values
{
reset();
--- a/src/base/KikiAction.h
+++ b/src/base/KikiAction.h
@@ -68,6 +68,8 @@
int duration;
int mode;
KikiEvent * event;
+
+ bool * delete_flag_ptr;
};
// __________________________________________________________________________________________________