edbus: do not crash when dispatching signals
Make sure the next signal handler for the connection is always known and not vanish under us. Patch by: Ulisses Furquim <ulisses@profusion.mobi> SVN revision: 81847
This commit is contained in:
parent
489bbff765
commit
4f6a4e59a4
|
@ -765,13 +765,12 @@ cb_dispatch_status(DBusConnection *dbus_conn, DBusDispatchStatus new_status, voi
|
||||||
static void
|
static void
|
||||||
cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
|
cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
|
||||||
{
|
{
|
||||||
EDBus_Signal_Handler *sh;
|
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
int counter;
|
int counter;
|
||||||
char *arg_msg;
|
char *arg_msg;
|
||||||
EDBus_Message *edbus_msg;
|
EDBus_Message *edbus_msg;
|
||||||
Signal_Argument *arg;
|
Signal_Argument *arg;
|
||||||
Eina_Inlist *safe_list;
|
Eina_Inlist *next;
|
||||||
|
|
||||||
edbus_msg = edbus_message_new(EINA_FALSE);
|
edbus_msg = edbus_message_new(EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN(edbus_msg);
|
EINA_SAFETY_ON_NULL_RETURN(edbus_msg);
|
||||||
|
@ -781,10 +780,20 @@ cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
|
||||||
&edbus_msg->iterator->dbus_iterator);
|
&edbus_msg->iterator->dbus_iterator);
|
||||||
|
|
||||||
edbus_connection_ref(conn);
|
edbus_connection_ref(conn);
|
||||||
EINA_INLIST_FOREACH_SAFE(conn->signal_handlers, safe_list, sh)
|
/*
|
||||||
|
* Do the walking open-coded so we don't crash if a callback
|
||||||
|
* removes other signal handlers from the list and we don't own
|
||||||
|
* yet a reference to them.
|
||||||
|
*/
|
||||||
|
next = conn->signal_handlers;
|
||||||
|
while (next != NULL)
|
||||||
{
|
{
|
||||||
|
EDBus_Signal_Handler *sh;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
|
sh = EINA_INLIST_CONTAINER_GET(next, EDBus_Signal_Handler);
|
||||||
|
next = next->next;
|
||||||
|
|
||||||
if (sh->dangling) continue;
|
if (sh->dangling) continue;
|
||||||
if (sh->sender)
|
if (sh->sender)
|
||||||
{
|
{
|
||||||
|
@ -818,11 +827,14 @@ cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
|
||||||
}
|
}
|
||||||
edbus_signal_handler_ref(sh);
|
edbus_signal_handler_ref(sh);
|
||||||
sh->cb((void *)sh->cb_data, edbus_msg);
|
sh->cb((void *)sh->cb_data, edbus_msg);
|
||||||
|
/* update next signal handler because the list may have changed */
|
||||||
|
next = EINA_INLIST_GET(sh)->next;
|
||||||
|
edbus_signal_handler_unref(sh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rewind iterator so another signal handler matching the same signal
|
* Rewind iterator so another signal handler matching the same signal
|
||||||
* can iterate over it.
|
* can iterate over it.
|
||||||
*/
|
*/
|
||||||
edbus_signal_handler_unref(sh);
|
|
||||||
dbus_message_iter_init(edbus_msg->dbus_msg,
|
dbus_message_iter_init(edbus_msg->dbus_msg,
|
||||||
&edbus_msg->iterator->dbus_iterator);
|
&edbus_msg->iterator->dbus_iterator);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue