summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUlisses Furquim <ulisses@profusion.mobi>2012-12-28 21:05:57 +0000
committerLucas De Marchi <lucas.demarchi@profusion.mobi>2012-12-28 21:05:57 +0000
commit4f6a4e59a4e7774fe55ae3ecf37d42faabec07e4 (patch)
treea35d30664aea7cc7e22c3699409d6c85aac53324 /src
parent489bbff7657d480311b2827599bb21f42aac9582 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/lib/edbus/edbus_core.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/lib/edbus/edbus_core.c b/src/lib/edbus/edbus_core.c
index b7a9f2871e..32cfd66fa6 100644
--- a/src/lib/edbus/edbus_core.c
+++ b/src/lib/edbus/edbus_core.c
@@ -765,13 +765,12 @@ cb_dispatch_status(DBusConnection *dbus_conn, DBusDispatchStatus new_status, voi
765static void 765static void
766cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg) 766cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
767{ 767{
768 EDBus_Signal_Handler *sh;
769 DBusMessageIter iter; 768 DBusMessageIter iter;
770 int counter; 769 int counter;
771 char *arg_msg; 770 char *arg_msg;
772 EDBus_Message *edbus_msg; 771 EDBus_Message *edbus_msg;
773 Signal_Argument *arg; 772 Signal_Argument *arg;
774 Eina_Inlist *safe_list; 773 Eina_Inlist *next;
775 774
776 edbus_msg = edbus_message_new(EINA_FALSE); 775 edbus_msg = edbus_message_new(EINA_FALSE);
777 EINA_SAFETY_ON_NULL_RETURN(edbus_msg); 776 EINA_SAFETY_ON_NULL_RETURN(edbus_msg);
@@ -781,10 +780,20 @@ cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
781 &edbus_msg->iterator->dbus_iterator); 780 &edbus_msg->iterator->dbus_iterator);
782 781
783 edbus_connection_ref(conn); 782 edbus_connection_ref(conn);
784 EINA_INLIST_FOREACH_SAFE(conn->signal_handlers, safe_list, sh) 783 /*
784 * Do the walking open-coded so we don't crash if a callback
785 * removes other signal handlers from the list and we don't own
786 * yet a reference to them.
787 */
788 next = conn->signal_handlers;
789 while (next != NULL)
785 { 790 {
791 EDBus_Signal_Handler *sh;
786 int type = 0; 792 int type = 0;
787 793
794 sh = EINA_INLIST_CONTAINER_GET(next, EDBus_Signal_Handler);
795 next = next->next;
796
788 if (sh->dangling) continue; 797 if (sh->dangling) continue;
789 if (sh->sender) 798 if (sh->sender)
790 { 799 {
@@ -818,11 +827,14 @@ cb_signal_dispatcher(EDBus_Connection *conn, DBusMessage *msg)
818 } 827 }
819 edbus_signal_handler_ref(sh); 828 edbus_signal_handler_ref(sh);
820 sh->cb((void *)sh->cb_data, edbus_msg); 829 sh->cb((void *)sh->cb_data, edbus_msg);
830 /* update next signal handler because the list may have changed */
831 next = EINA_INLIST_GET(sh)->next;
832 edbus_signal_handler_unref(sh);
833
821 /* 834 /*
822 * Rewind iterator so another signal handler matching the same signal 835 * Rewind iterator so another signal handler matching the same signal
823 * can iterate over it. 836 * can iterate over it.
824 */ 837 */
825 edbus_signal_handler_unref(sh);
826 dbus_message_iter_init(edbus_msg->dbus_msg, 838 dbus_message_iter_init(edbus_msg->dbus_msg,
827 &edbus_msg->iterator->dbus_iterator); 839 &edbus_msg->iterator->dbus_iterator);
828 } 840 }