a bug of CCScheduler

// main loop
void CCScheduler::tick(ccTime dt)

……

// Interate all script functions
for (tHashScriptFuncEntry **elt = m_pHashForScriptFunctions; elt != NULL; )
{
if
{
elt~~>timer~~>update;
}
elt = elt~~>hh.next;
}
}
above is part of the code of the cocos2d-1.0.1-x-0.10.0 version
the problem is If We call unscheduleScriptFunc function in the registed func, the property elt will be NULL after elt~~>timer~~>update, then elt = elt~~>hh.next; will cause a crash.
here is my test code in lua:
local count = 1
function cb
count = count + 1
if count == 10 then
cocos2d.CCScheduler:sharedScheduler:unscheduleScriptFunc
end
end
cocos2d.CCScheduler:sharedScheduler:scheduleScriptFunc
the way to solve this problem is quite simple, below is my solution

tHashScriptFuncEntry**eltTemp = (tHashScriptFuncEntry *)elt~~>hh.next;
if
{
elt~~>timer->update(dt);
}

elt = eltTemp;

sorry, If there have more then one scheduleScriptFunc, this function still might working wrong.

we should remove the null element from m_pHashForScriptFunctions.

or will unscheduleScriptFunc remove it from m_pHashForScriptFunctions?

Thank you, #942 is created for it.

Now I’m sure that my pre solution is wrong, because it will always cause “HEAP: Free Heap block * modified at* after it was freed” error.

Hi Minggo,
I sure that I have the correct solution now, which is quite similar to the original unscheduleSelector.
Below is the detail:

  1. add currentTimerSalvaged to tHashScriptFuncEntry as a flag, will delete the entry if it is true
    typedef struct _hashScriptFuncEntry
    {
    CCTimer timer;
    bool paused;
    bool currentTimerSalvaged;
    const char
    funcName;
    UT_hash_handle hh;
    } tHashScriptFuncEntry;
  2. add function void removeHashScriptFuncElement(struct _hashScriptFuncEntry pElement);
    void CCScheduler::removeHashScriptFuncElement
    {
    if
    {
    pElement~~>timer~~>release;
    pElement~~>timer = NULL;
    HASH_DEL;
    free;
    }
    }
    3.Modify function unscheduleScriptFunc. do not delete entry in here, only mark it
    if
    {
    pElement~~>currentTimerSalvaged = true;
    }
    4.modify function tick.
    // Interate all script functions
    for
    {
    tHashScriptFuncEntry
    pNextElement = (tHashScriptFuncEntry *)elt~~>hh.next;
    if
    {
    elt~~>timer->update(dt);
    if( elt->currentTimerSalvaged )
    {
    removeHashScriptFuncElement(elt);
    }
    }

elt = pNextElement;
}

Awesome.
Could you please pull a request by github?

done!
first time to use github, please check it!

I have seen it.
Thank you.