Fix disconnecting not connected signals (#950)
When a function is disconnected from a signal ("disconnect_signal") that is not actually connected to the function, two things happened: 1. The attempt to remove the function from the signal array didn't do anything 2. Unreferencing the function noticed that the function wasn't referenced The second step printed a big, fat scary warning. Actually, this has the possibility of causing errors. For example, in the following code, awesome would wrongly unreference the function at the disconnect_signal() call and might later still try to call it when the "refresh" signal is emitted: do local function f() end awesome.connect_signal("refresh", f) awesome.disconnect_signal("debug::error", f) end Fix this by making signal_disconnect() return a boolean value indicating if it actually did something. All callers are fixed to use this value and only update the reference counts if something was actually disconnected. Fixes: https://github.com/awesomeWM/awesome/issues/814 Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
2d511e2ab5
commit
6f1df7a3ad
|
@ -278,8 +278,8 @@ luaA_class_disconnect_signal_from_stack(lua_State *L, lua_class_t *lua_class,
|
||||||
{
|
{
|
||||||
luaA_checkfunction(L, ud);
|
luaA_checkfunction(L, ud);
|
||||||
void *ref = (void *) lua_topointer(L, ud);
|
void *ref = (void *) lua_topointer(L, ud);
|
||||||
signal_disconnect(&lua_class->signals, name, ref);
|
if (signal_disconnect(&lua_class->signals, name, ref))
|
||||||
luaA_object_unref(L, (void *) ref);
|
luaA_object_unref(L, (void *) ref);
|
||||||
lua_remove(L, ud);
|
lua_remove(L, ud);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,8 +222,8 @@ luaA_object_disconnect_signal_from_stack(lua_State *L, int oud,
|
||||||
luaA_checkfunction(L, ud);
|
luaA_checkfunction(L, ud);
|
||||||
lua_object_t *obj = lua_touserdata(L, oud);
|
lua_object_t *obj = lua_touserdata(L, oud);
|
||||||
void *ref = (void *) lua_topointer(L, ud);
|
void *ref = (void *) lua_topointer(L, ud);
|
||||||
signal_disconnect(&obj->signals, name, ref);
|
if (signal_disconnect(&obj->signals, name, ref))
|
||||||
luaA_object_unref_item(L, oud, ref);
|
luaA_object_unref_item(L, oud, ref);
|
||||||
lua_remove(L, ud);
|
lua_remove(L, ud);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ signal_connect(signal_array_t *arr, const char *name, const void *ref)
|
||||||
* \param name The signal name.
|
* \param name The signal name.
|
||||||
* \param ref The reference to remove.
|
* \param ref The reference to remove.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline bool
|
||||||
signal_disconnect(signal_array_t *arr, const char *name, const void *ref)
|
signal_disconnect(signal_array_t *arr, const char *name, const void *ref)
|
||||||
{
|
{
|
||||||
signal_t *sigfound = signal_array_getbyid(arr,
|
signal_t *sigfound = signal_array_getbyid(arr,
|
||||||
|
@ -92,9 +92,10 @@ signal_disconnect(signal_array_t *arr, const char *name, const void *ref)
|
||||||
if(ref == *func)
|
if(ref == *func)
|
||||||
{
|
{
|
||||||
cptr_array_remove(&sigfound->sigfuncs, func);
|
cptr_array_remove(&sigfound->sigfuncs, func);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
4
dbus.c
4
dbus.c
|
@ -789,8 +789,8 @@ luaA_dbus_disconnect_signal(lua_State *L)
|
||||||
const char *name = luaL_checkstring(L, 1);
|
const char *name = luaL_checkstring(L, 1);
|
||||||
luaA_checkfunction(L, 2);
|
luaA_checkfunction(L, 2);
|
||||||
const void *func = lua_topointer(L, 2);
|
const void *func = lua_topointer(L, 2);
|
||||||
signal_disconnect(&dbus_signals, name, func);
|
if (signal_disconnect(&dbus_signals, name, func))
|
||||||
luaA_object_unref(L, func);
|
luaA_object_unref(L, func);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
luaa.c
4
luaa.c
|
@ -395,8 +395,8 @@ luaA_awesome_disconnect_signal(lua_State *L)
|
||||||
const char *name = luaL_checkstring(L, 1);
|
const char *name = luaL_checkstring(L, 1);
|
||||||
luaA_checkfunction(L, 2);
|
luaA_checkfunction(L, 2);
|
||||||
const void *func = lua_topointer(L, 2);
|
const void *func = lua_topointer(L, 2);
|
||||||
signal_disconnect(&global_signals, name, func);
|
if (signal_disconnect(&global_signals, name, func))
|
||||||
luaA_object_unref(L, (void *) func);
|
luaA_object_unref(L, (void *) func);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue