edbus: Avoid call _on_signal_handler_free over freed object or proxy
authorJosé Roberto de Souza <zehortigoza@profusion.mobi>
Thu, 18 Oct 2012 20:11:04 +0000 (20:11 +0000)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Thu, 18 Oct 2012 20:11:04 +0000 (20:11 +0000)
If a signal handler callback remove the last reference of his parent, his parent
will unref all your childrens including signal handler, but signal handler could
not be freed until your callback was finish so a event to delete it will be
created and when this event happen the signal handler parent was already freed
and we could not call _on_signal_handler_free().

Patch by: José Roberto de Souza  <zehortigoza@profusion.mobi>

SVN revision: 78198

src/lib/edbus_object.c
src/lib/edbus_proxy.c

index 0297ff5..fb0fe66 100644 (file)
@@ -59,6 +59,7 @@ edbus_object_shutdown(void)
 static void _edbus_object_event_callback_call(EDBus_Object *obj, EDBus_Object_Event_Type type, const void *event_info);
 static void _edbus_object_context_event_cb_del(EDBus_Object_Context_Event *ce, EDBus_Object_Context_Event_Cb *ctx);
 static void _on_connection_free(void *data, const void *dead_pointer);
+static void _on_signal_handler_free(void *data, const void *dead_pointer);
 
 static void
 _edbus_object_call_del(EDBus_Object *obj)
@@ -122,6 +123,8 @@ static void
 _edbus_object_free(EDBus_Object *obj)
 {
    unsigned int i;
+   EDBus_Signal_Handler *h;
+
    if (obj->proxies)
      {
         Eina_Iterator *iterator = eina_hash_iterator_data_new(obj->proxies);
@@ -133,11 +136,11 @@ _edbus_object_free(EDBus_Object *obj)
         eina_hash_free(obj->proxies);
      }
 
-   if (obj->signal_handlers)
+   EINA_LIST_FREE (obj->signal_handlers, h)
      {
-        EDBus_Signal_Handler *h;
-        CRITICAL("Object %p released with live signal handlers!", obj);
-        EINA_LIST_FREE (obj->signal_handlers, h)
+        if (h->dangling)
+          edbus_signal_handler_cb_free_del(h, _on_signal_handler_free, obj);
+        else
           ERR("obj=%p alive handler=%p %s", obj, h,
               edbus_signal_handler_match_get(h));
      }
index 998dc36..0d33e8d 100644 (file)
@@ -84,6 +84,7 @@ edbus_proxy_shutdown(void)
 
 static void _edbus_proxy_event_callback_call(EDBus_Proxy *proxy, EDBus_Proxy_Event_Type type, const void *event_info);
 static void _edbus_proxy_context_event_cb_del(EDBus_Proxy_Context_Event *ce, EDBus_Proxy_Context_Event_Cb *ctx);
+static void _on_signal_handler_free(void *data, const void *dead_pointer);
 
 static void
 _edbus_proxy_call_del(EDBus_Proxy *proxy)
@@ -145,13 +146,15 @@ static void
 _edbus_proxy_free(EDBus_Proxy *proxy)
 {
    unsigned int i;
-   if (proxy->handlers)
+   EDBus_Signal_Handler *h;
+
+   EINA_LIST_FREE (proxy->handlers, h)
      {
-        EDBus_Signal_Handler *h;
-        CRITICAL("Proxy %p released with live signal handlers!", proxy);
-        EINA_LIST_FREE (proxy->handlers, h)
-          ERR("proxy=%p alive handler=%p %s", proxy, h,
-              edbus_signal_handler_match_get(h));
+        if (h->dangling)
+         edbus_signal_handler_cb_free_del(h, _on_signal_handler_free, proxy);
+        else
+           ERR("proxy=%p alive handler=%p %s", proxy, h,
+               edbus_signal_handler_match_get(h));
      }
 
    if (proxy->pendings)