]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-3386 add some more debug defines to sofia and avoid double destroy in nh
authorAnthony Minessale <anthm@freeswitch.org>
Sat, 16 Jul 2011 06:01:37 +0000 (01:01 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Sat, 16 Jul 2011 06:03:01 +0000 (01:03 -0500)
libs/sofia-sip/libsofia-sip-ua/nua/nua_common.c
libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h
libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h
libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c

index c3ee92d12fe1f85ee7da59ed8b3acd485e3e0eb4..bc842c242d5285b0033b07fc8bbbf7fee9692a62 100644 (file)
@@ -172,10 +172,16 @@ _nua_handle_ref_by(nua_handle_t *nh,
                   char const *file, unsigned line,
                   char const *function)
 {
-  if (nh)
-    SU_DEBUG_0(("%p - nua_handle_ref() => "MOD_ZU" by %s:%u: %s()\n",
-               nh, su_home_refcount((su_home_t *)nh) + 1, file, line, function));
-  return (nua_handle_t *)su_home_ref((su_home_t *)nh);
+
+#if (HAVE_MEMLEAK_LOG == 1) 
+       if (nh)
+               SU_DEBUG_0(("%p - nua_handle_ref() => "MOD_ZU" by %s:%u: %s()\n",
+                                       nh, su_home_refcount((su_home_t *)nh) + 1, file, line, function));
+       return (nua_handle_t *)su_home_ref((su_home_t *)nh);
+#else
+
+       return (nua_handle_t *)_su_home_ref_by((su_home_t *)nh, file, line, function);
+#endif
 }
 
 int
@@ -183,30 +189,24 @@ _nua_handle_unref_by(nua_handle_t *nh,
                    char const *file, unsigned line,
                    char const *function)
 {
-  if (nh) {
-    size_t refcount = su_home_refcount((su_home_t *)nh) - 1;
-    int freed =  su_home_unref((su_home_t *)nh);
-
-    if (freed) refcount = 0;
-    SU_DEBUG_0(("%p - nua_handle_unref() => "MOD_ZU" by %s:%u: %s()\n",
-               nh, refcount, file, line, function));
-    return freed;
-  }
 
-  return 0;
-}
+#if (HAVE_MEMLEAK_LOG == 1)
 
-#if 0
-nua_handle_t *nua_handle_ref(nua_handle_t *nh)
-{
-  return _nua_handle_ref_by(nh, "<app>", 0, "<app>")
-}
+       if (nh) {
+               size_t refcount = su_home_refcount((su_home_t *)nh) - 1;
+               int freed =  su_home_unref((su_home_t *)nh);
 
-int nua_handle_unref(nua_handle_t *nh)
-{
-  return _nua_handle_unref_by(nh, "<app>", 0, "<app>")
-}
+               if (freed) refcount = 0;
+               SU_DEBUG_0(("%p - nua_handle_unref() => "MOD_ZU" by %s:%u: %s()\n",
+                                       nh, refcount, file, line, function));
+               return freed;
+       }
+
+       return 0;
+#else
+       return _su_home_unref_by((su_home_t *)nh, file, line, function);
 #endif
+}
 
 #else
 
index b96b1f31c0cbec706925c6d8597ad55ae9365063..d2b7caf66d30d3e1440d2682533a6370371dc46a 100644 (file)
@@ -373,8 +373,11 @@ nua_dialog_usage_remove_at(nua_owner_t *own,
                           nua_client_request_t *cr0,
                           nua_server_request_t *sr0)
 {
+       int unref = 0;
+       nua_dialog_usage_t *du = NULL;
+
   if (*at) {
-    nua_dialog_usage_t *du = *at;
+    du = *at;
     sip_event_t const *o = NULL;
     nua_client_request_t *cr, *cr_next;
     nua_server_request_t *sr, *sr_next;
@@ -409,8 +412,7 @@ nua_dialog_usage_remove_at(nua_owner_t *own,
       }
     }
 
-    su_home_unref(own);
-    su_free(own, du);
+       unref = 1;
   }
 
   /* Zap dialog if there are no more usages */
@@ -419,11 +421,20 @@ nua_dialog_usage_remove_at(nua_owner_t *own,
   else if (ds->ds_usage == NULL) {
     nua_dialog_remove(own, ds, NULL);
     ds->ds_has_events = 0;
+       if (unref) {
+               su_home_unref(own);
+               su_free(own, du);
+       }
     return;
   }
   else {
     nua_dialog_log_usage(own, ds);
   }
+
+  if (unref) {
+    su_home_unref(own);
+    su_free(own, du);
+  }
 }
 
 static
index de4d2439907fb3228eb188799e2ab0e71d63f987..5fe5d221d1dbbf60a12610e244910d79d449cdf6 100644 (file)
@@ -396,7 +396,9 @@ void nua_application_event(nua_t *dummy, su_msg_r sumsg, nua_ee_data_t *ee)
                      e->e_msg ? sip_object(e->e_msg) : NULL,
                      e->e_tags);
 
-    su_msg_destroy(frame->nf_saved);
+       if (su_msg_is_non_null(frame->nf_saved)) {
+               su_msg_destroy(frame->nf_saved);
+       }
     nua->nua_current = frame->nf_next;
   }
 
@@ -417,6 +419,23 @@ msg_t *nua_current_request(nua_t const *nua)
   return NULL;
 }
 
+
+su_msg_t *nua_current_msg(nua_t const *nua, int clear)
+{
+       if (nua && nua->nua_current && su_msg_is_non_null(nua->nua_current->nf_saved)) {
+               su_msg_t *r = nua->nua_current->nf_saved[0];
+               if (clear) {
+                       nua->nua_current->nf_saved[0] = NULL;
+               }
+               return r;
+               //return su_msg_data(nua->nua_current->nf_saved)->ee_data->e_msg;
+               
+       }
+
+  return NULL;
+}
+
+
 /** Get request message from saved nua event. @NEW_1_12_4.
  *
  * @sa nua_save_event(), nua_respond(), NUTAG_WITH_SAVED(),
@@ -638,8 +657,10 @@ void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_ee_data_t *ee)
     nua_stack_respond(nua, nh, e->e_status, e->e_phrase, tags);
     break;
   case nua_r_destroy:
-    nua_stack_destroy_handle(nua, nh, tags);
-    su_msg_destroy(nua->nua_signal);
+         if (!nh->nh_destroyed) {
+                 nua_stack_destroy_handle(nua, nh, tags);
+                 su_msg_destroy(nua->nua_signal);
+         }
     return;
   default:
     break;
@@ -912,6 +933,10 @@ nua_handle_t *nh_validate(nua_t *nua, nua_handle_t *maybe)
 
 void nua_stack_destroy_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags)
 {
+  if (nh->nh_destroyed) {
+         return;
+  }
+
   if (nh->nh_notifier)
     nua_stack_terminate(nua, nh, (enum nua_event_e)0, NULL);
 
@@ -949,6 +974,12 @@ void nh_destroy(nua_t *nua, nua_handle_t *nh)
 {
   assert(nh); assert(nh != nua->nua_dhandle);
 
+  if (nh->nh_destroyed) {
+         return;
+  }
+
+  nh->nh_destroyed = 1;
+
   if (nh->nh_notifier)
     nea_server_destroy(nh->nh_notifier), nh->nh_notifier = NULL;
 
index 97c88582a3e6df7679dfc16b542858a527880d5f..ba2d69a53d127395756082d0227a7bc6f2d793d2 100644 (file)
@@ -150,6 +150,7 @@ struct nua_handle_s
   unsigned        nh_ref_by_user:1;    /**< Has user used the handle? */
   unsigned        nh_init:1;           /**< Handle has been initialized */
   unsigned        nh_used_ptags:1;     /**< Ptags has been used */
+  unsigned        nh_destroyed:1;      /**< nh_destroy already called */
   unsigned :0;
 
   nua_dialog_state_t nh_ds[1];
@@ -338,6 +339,8 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
                    nua_event_t event, int status, char const *phrase,
                    tagi_t const *tags);
 
+su_msg_t *nua_current_msg(nua_t const *nua, int clear);
+
 void nua_move_event(nua_saved_event_t a[1], nua_saved_event_t b[1]);
 
 nua_handle_t *nh_create_handle(nua_t *nua, nua_hmagic_t *hmagic, tagi_t *tags);
index 8af6ddebd55ae12d5be4c54979aa768c9595ca67..8e4815f33e4ecb24282c93d59770532de3abc589 100644 (file)
@@ -64,8 +64,33 @@ struct su_home_s {
 
 SU_DLL void *su_home_new(isize_t size)
      __attribute__((__malloc__));
+
+#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
+
+int _su_home_mutex_lock(su_home_t *home, const char *file, unsigned int line, const char *function);
+int _su_home_mutex_lock(su_home_t *home, const char *file, unsigned int line, const char *function);
+
+#define su_home_mutex_lock(home) \
+  _su_home_mutex_lock((home), __FILE__, __LINE__, __func__)
+
+#define su_home_mutex_unlock(home) \
+  _su_home_mutex_unlock((home), __FILE__, __LINE__, __func__)
+
+
+su_home_t *_su_home_ref_by(
+  su_home_t *home, char const *file, unsigned line, char const *by);
+int _su_home_unref_by(
+  su_home_t *home, char const *file, unsigned line, char const *by);
+
+#define su_home_ref(home) \
+  _su_home_ref_by((home), __FILE__, __LINE__, __func__)
+#define su_home_unref(home) \
+  _su_home_unref_by((home), __FILE__, __LINE__, __func__)
+
+#else
 SU_DLL void *su_home_ref(su_home_t const *);
 SU_DLL int su_home_unref(su_home_t *);
+#endif
 
 SU_DLL size_t su_home_refcount(su_home_t *home);
 
@@ -107,9 +132,11 @@ SU_DLL void su_home_check(su_home_t const *home);
 
 SU_DLL int su_home_check_alloc(su_home_t const *home, void const *data);
 
+#if (!defined(HAVE_MEMLEAK_LOG) || (HAVE_MEMLEAK_LOG != 1))
 SU_DLL int su_home_mutex_lock(su_home_t *home);
 
 SU_DLL int su_home_mutex_unlock(su_home_t *home);
+#endif
 
 SU_DLL int su_home_lock(su_home_t *home);
 SU_DLL int su_home_trylock(su_home_t *home);
index 51259ade1a7802a4218abade642bd6b665c6d951..cc0b9603f5fcceefe6ffcddec3dfcecc8fad912e 100644 (file)
@@ -569,28 +569,6 @@ void *su_home_new(isize_t size)
   return home;
 }
 
-/** Create a new reference to a home object. */
-void *su_home_ref(su_home_t const *home)
-{
-  if (home) {
-    su_block_t *sub = MEMLOCK(home);
-
-    if (sub == NULL || sub->sub_ref == 0) {
-      assert(sub && sub->sub_ref != 0);
-      UNLOCK(home);
-      return NULL;
-    }
-
-    if (sub->sub_ref != REF_MAX)
-      sub->sub_ref++;
-    UNLOCK(home);
-  }
-  else
-    su_seterrno(EFAULT);
-
-  return (void *)home;
-}
-
 /** Set destructor function.
  *
  * The destructor function is called after the reference count of a
@@ -637,6 +615,123 @@ int su_home_desctructor(su_home_t *home, void (*destructor)(void *))
   return su_home_destructor(home, destructor);
 }
 
+
+#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
+#include "sofia-sip/su_debug.h"
+
+
+static void *real_su_home_ref(su_home_t const *home)
+{
+  if (home) {
+    su_block_t *sub = MEMLOCK(home);
+
+    if (sub == NULL || sub->sub_ref == 0) {
+      assert(sub && sub->sub_ref != 0);
+      UNLOCK(home);
+      return NULL;
+    }
+
+    if (sub->sub_ref != REF_MAX)
+      sub->sub_ref++;
+    UNLOCK(home);
+  }
+  else
+    su_seterrno(EFAULT);
+
+  return (void *)home;
+}
+
+
+static int real_su_home_unref(su_home_t *home)
+{
+  su_block_t *sub;
+
+  if (home == NULL)
+    return 0;
+
+  sub = MEMLOCK(home);
+
+  if (sub == NULL) {
+    /* Xyzzy */
+    return 0;
+  }
+  else if (sub->sub_ref == REF_MAX) {
+    UNLOCK(home);
+    return 0;
+  }
+  else if (--sub->sub_ref > 0) {
+    UNLOCK(home);
+    return 0;
+  }
+  else if (sub->sub_parent) {
+    su_home_t *parent = sub->sub_parent;
+    UNLOCK(home);
+    su_free(parent, home);
+    return 1;
+  }
+  else {
+    int hauto = sub->sub_hauto;
+    _su_home_deinit(home);
+    if (!hauto)
+      safefree(home);
+    /* UNLOCK(home); */
+    return 1;
+  }
+}
+
+su_home_t *
+_su_home_ref_by(su_home_t *home,
+                  char const *file, unsigned line,
+                  char const *function)
+{
+  if (home)
+         SU_DEBUG_0(("%ld %p - su_home_ref() => "MOD_ZU" by %s:%u: %s()\n", pthread_self(),
+               home, su_home_refcount(home) + 1, file, line, function));
+  return (su_home_t *)real_su_home_ref(home);
+}
+
+int
+_su_home_unref_by(su_home_t *home,
+                   char const *file, unsigned line,
+                   char const *function)
+{
+  if (home) {
+    size_t refcount = su_home_refcount(home) - 1;
+    int freed =  real_su_home_unref(home);
+
+    if (freed) refcount = 0;
+    SU_DEBUG_0(("%ld %p - su_home_unref() => "MOD_ZU" by %s:%u: %s()\n", pthread_self(),
+               home, refcount, file, line, function));
+    return freed;
+  }
+
+  return 0;
+}
+#else
+
+/** Create a new reference to a home object. */
+void *su_home_ref(su_home_t const *home)
+{
+  if (home) {
+    su_block_t *sub = MEMLOCK(home);
+
+    if (sub == NULL || sub->sub_ref == 0) {
+      assert(sub && sub->sub_ref != 0);
+      UNLOCK(home);
+      return NULL;
+    }
+
+    if (sub->sub_ref != REF_MAX)
+      sub->sub_ref++;
+    UNLOCK(home);
+  }
+  else
+    su_seterrno(EFAULT);
+
+  return (void *)home;
+}
+
+
 /**Unreference a su_home_t object.
  *
  * Decrements the reference count on home object and destroys and frees it
@@ -683,6 +778,7 @@ int su_home_unref(su_home_t *home)
     return 1;
   }
 }
+#endif
 
 /** Return reference count of home. */
 size_t su_home_refcount(su_home_t *home)
@@ -1546,14 +1642,24 @@ int su_home_is_threadsafe(su_home_t const *home)
  * Otherwise the su_home_mutex_lock() will just increase the reference
  * count.
  */
+
+#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
+int _su_home_mutex_lock(su_home_t *home, const char *file, unsigned int line, const char *function)
+#else
 int su_home_mutex_lock(su_home_t *home)
+#endif
+
 {
   int error;
 
   if (home == NULL)
     return su_seterrno(EFAULT);
 
+#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
+  if (home->suh_blocks == NULL || !_su_home_ref_by(home, file, line, function))
+#else
   if (home->suh_blocks == NULL || !su_home_ref(home))
+#endif
     return su_seterrno(EINVAL);  /* Uninitialized home */
 
   if (!home->suh_lock)
@@ -1570,7 +1676,12 @@ int su_home_mutex_lock(su_home_t *home)
  *
  * @sa su_home_unlock().
  */
+
+#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
+int _su_home_mutex_unlock(su_home_t *home, const char *file, unsigned int line, const char *function)
+#else
 int su_home_mutex_unlock(su_home_t *home)
+#endif
 {
   if (home == NULL)
     return su_seterrno(EFAULT);
@@ -1584,7 +1695,11 @@ int su_home_mutex_unlock(su_home_t *home)
   if (home->suh_blocks == NULL)
     return su_seterrno(EINVAL), -1; /* Uninitialized home */
 
+#if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1))
+  _su_home_unref_by(home, file, line, function);
+#else
   su_home_unref(home);
+#endif
 
   return 0;
 }