FS-3386 add some more debug defines to sofia and avoid double destroy in nh

This commit is contained in:
Anthony Minessale 2011-07-16 01:01:37 -05:00
parent 06fa4eee78
commit b0e076a74f
6 changed files with 238 additions and 51 deletions

View 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;
}
#if (HAVE_MEMLEAK_LOG == 1)
return 0;
}
if (nh) {
size_t refcount = su_home_refcount((su_home_t *)nh) - 1;
int freed = su_home_unref((su_home_t *)nh);
#if 0
nua_handle_t *nua_handle_ref(nua_handle_t *nh)
{
return _nua_handle_ref_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;
}
int nua_handle_unref(nua_handle_t *nh)
{
return _nua_handle_unref_by(nh, "<app>", 0, "<app>")
}
return 0;
#else
return _su_home_unref_by((su_home_t *)nh, file, line, function);
#endif
}
#else

View 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

View 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;

View 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);

View 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);

View 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;
}