Commit 8633f69c authored by Pekka Pessi's avatar Pekka Pessi

nua: fixed problem where a final error response to initial request destroyed...

nua: fixed problem where a final error response to initial request destroyed handle while application still had a reference.

darcs-hash:20070206131119-65a35-e057f9e0bb738800bb98c4c64e14ce7cb1e2545d.gz
parent 06a1b5e5
......@@ -955,16 +955,13 @@ void nua_signal(nua_t *nua, nua_handle_t *nh, msg_t *msg, int always,
e->e_status = status;
e->e_phrase = phrase;
if (nua_log->log_level >= 7) {
char const *name = nua_event_name(event) + 4;
SU_DEBUG_7(("nua(%p): signal %s\n", nh, name));
}
SU_DEBUG_7(("nua(%p): signal %s\n", nh, nua_event_name(event) + 4));
if (su_msg_send(sumsg) != 0 && event != nua_r_destroy)
nua_handle_unref(nh);
}
else {
/* XXX - we should return error code to application */
/* XXX - we should return error code to application but we just abort() */
assert(ENOMEM == 0);
}
......@@ -992,7 +989,11 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
SU_DEBUG_7(("nua(%p): event %s dropped\n", nh, name));
}
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) {
#if HAVE_NUA_HANDLE_DEBUG
SU_DEBUG_0(("nua(%p): freed by application\n", nh));
#else
SU_DEBUG_9(("nua(%p): freed by application\n", nh));
#endif
}
if (e->e_msg)
msg_destroy(e->e_msg), e->e_msg = NULL;
......@@ -1021,7 +1022,11 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
e->e_tags);
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) {
#if HAVE_NUA_HANDLE_DEBUG
SU_DEBUG_0(("nua(%p): freed by application\n", nh));
#else
SU_DEBUG_9(("nua(%p): freed by application\n", nh));
#endif
}
if (!su_msg_is_non_null(nua->nua_current))
......
......@@ -251,6 +251,9 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg,
if (event == nua_r_ack || event == nua_i_none)
return event;
if (nh == nua->nua_dhandle)
nh = NULL;
if (nua_log->log_level >= 5) {
char const *name = nua_event_name(event) + 4;
char const *p = phrase ? phrase : "";
......@@ -704,12 +707,10 @@ void nua_stack_destroy_handle(nua_t *nua, nua_handle_t *nh, tagi_t const *tags)
nua_dialog_shutdown(nh, nh->nh_ds);
#if 0
if (nh->nh_ref_by_user) {
nh->nh_ref_by_user = 0;
nua_handle_unref(nh);
}
#endif
nh_destroy(nua, nh);
}
......@@ -1552,6 +1553,7 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
char const *phrase = sr->sr_phrase;
int terminated;
int handle_can_be_terminated = initial && !sr->sr_event;
assert(nh);
......@@ -1598,6 +1600,9 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
return 3;
}
else if (!handle_can_be_terminated) {
return 3;
}
else {
if (nh != nh->nh_nua->nua_dhandle)
nh_destroy(nh->nh_nua, nh);
......
......@@ -103,6 +103,8 @@ typedef struct register_usage nua_registration_t;
TAG_IF((include) && (soa) && soa_is_remote_chat_active(soa) >= 0, \
SOATAG_ACTIVE_CHAT(soa_is_remote_chat_active(soa)))
#define HAVE_NUA_HANDLE_DEBUG 1
#if HAVE_NUA_HANDLE_DEBUG
#define nua_handle_ref(nh) nua_handle_ref_by((nh), __func__)
......@@ -111,13 +113,19 @@ typedef struct register_usage nua_registration_t;
static inline nua_handle_t *nua_handle_ref_by(nua_handle_t *nh,
char const *by)
{
SU_DEBUG_0(("nua_handle_ref(%p) by %s\n", nh, by));
if (nh)
SU_DEBUG_0(("nua_handle_ref(%p) => "MOD_ZU" by %s\n", nh,
su_home_refcount((su_home_t *)nh) + 1,
by));
return (nua_handle_t *)su_home_ref((su_home_t *)nh);
}
static inline int nua_handle_unref_by(nua_handle_t *nh, char const *by)
{
SU_DEBUG_0(("nua_handle_unref(%p) by %s\n", nh, by));
if (nh)
SU_DEBUG_0(("nua_handle_unref(%p) => "MOD_ZU" by %s\n", nh,
su_home_refcount((su_home_t *)nh) - 1,
by));
return su_home_unref((su_home_t *)nh);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment