Fix Lua register* callback list corruption

Turns out nothing was setting the prev pointer on doubly linked list when
creating callback nodes, so Lua GC'ing any node from the middle corrupted
the list, leading to unregister* intermittently failing to actually
unregister the callback.
This commit is contained in:
Ilari Liusvaara 2021-02-09 18:35:00 +02:00
parent 6fb4e1396d
commit fb28e30fcc
2 changed files with 6 additions and 5 deletions

View file

@ -419,7 +419,7 @@ public:
* Parameter args: Arguments to pass to the callback.
*/
template<typename... T>
bool callback(std::list<char>& cblist, const char*& running_cb, bool running_cb_f, T... args)
bool callback(std::list<char>& cblist, const char*& r_cb, bool& r_cb_f, T... args)
{
bool any = false;
for(auto i = cblist.begin(); i != cblist.end();) {
@ -431,14 +431,14 @@ public:
} else {
//Note the currently running CB so that unregister treats it specially if it is
//unrgistered.
running_cb = &*i;
r_cb = &*i;
_callback(0, args...);
running_cb = NULL;
r_cb = NULL;
any = true;
}
//Currently iterated function may be erased. The memory has to be freed in that case.
if(running_cb_f) {
running_cb_f = false;
if(r_cb_f) {
r_cb_f = false;
i = cblist.erase(i);
} else {
i++;

View file

@ -269,6 +269,7 @@ namespace
if(dc->cblist.count(key))
was = dc->cblist[key];
dc->cblist[key] = this;
if(was) was->prev = this;
next = was;
L->pop(1);
}