Commit 41996867 authored by Pekka Pessi's avatar Pekka Pessi
Browse files

nua.c: nua event callback does not use nua_t object after nua_destroy() call. sf.net bug #1803686

darcs-hash:20071008115424-65a35-c4782d6a15123a780dccb865a92aff8cc517894c.gz
parent ab39c089
...@@ -195,6 +195,13 @@ void nua_shutdown(nua_t *nua) ...@@ -195,6 +195,13 @@ void nua_shutdown(nua_t *nua)
nua_signal(nua, NULL, NULL, 1, nua_r_shutdown, 0, NULL, TAG_END()); nua_signal(nua, NULL, NULL, 1, nua_r_shutdown, 0, NULL, TAG_END());
} }
/** @internal Linked stack frames from nua event callback */
struct nua_event_frame_s {
nua_event_frame_t *nf_next;
nua_t *nf_nua;
nua_saved_event_t nf_saved[1];
};
/** Destroy the @nua stack. /** Destroy the @nua stack.
* *
* Before calling nua_destroy() the application * Before calling nua_destroy() the application
...@@ -220,6 +227,8 @@ void nua_destroy(nua_t *nua) ...@@ -220,6 +227,8 @@ void nua_destroy(nua_t *nua)
enter; enter;
if (nua) { if (nua) {
nua_event_frame_t *nf;
if (!nua->nua_shutdown_final) { if (!nua->nua_shutdown_final) {
SU_DEBUG_0(("nua_destroy(%p): FATAL: nua_shutdown not completed\n", SU_DEBUG_0(("nua_destroy(%p): FATAL: nua_shutdown not completed\n",
(void *)nua)); (void *)nua));
...@@ -227,6 +236,13 @@ void nua_destroy(nua_t *nua) ...@@ -227,6 +236,13 @@ void nua_destroy(nua_t *nua)
return; return;
} }
nua->nua_callback = NULL;
for (nf = nua->nua_current; nf; nf = nf->nf_next) {
nf->nf_nua = NULL;
}
nua->nua_current = NULL;
su_task_deinit(nua->nua_server); su_task_deinit(nua->nua_server);
su_task_deinit(nua->nua_client); su_task_deinit(nua->nua_client);
...@@ -984,9 +1000,10 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e) ...@@ -984,9 +1000,10 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
{ {
nua_t *nua; nua_t *nua;
nua_handle_t *nh = e->e_nh; nua_handle_t *nh = e->e_nh;
enter; enter;
e->e_nh = NULL;
if (nh) { if (nh) {
if (!nh->nh_ref_by_user && nh->nh_valid) { if (!nh->nh_ref_by_user && nh->nh_valid) {
nh->nh_ref_by_user = 1; nh->nh_ref_by_user = 1;
...@@ -1013,40 +1030,40 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e) ...@@ -1013,40 +1030,40 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
nua = nh->nh_nua; assert(nua); nua = nh->nh_nua; assert(nua);
if (NH_IS_DEFAULT(nh))
nh = NULL;
if (e->e_event == nua_r_shutdown && e->e_status >= 200) if (e->e_event == nua_r_shutdown && e->e_status >= 200)
nua->nua_shutdown_final = 1; nua->nua_shutdown_final = 1;
if (!nua->nua_callback) if (nua->nua_callback) {
return; nua_event_frame_t frame[1];
su_msg_remove_refs(sumsg); /* Remove references to tasks */
su_msg_save(frame->nf_saved, sumsg);
frame->nf_nua = nua;
frame->nf_next = nua->nua_current, nua->nua_current = frame;
if (NH_IS_DEFAULT(nh)) nua->nua_callback(e->e_event, e->e_status, e->e_phrase,
nh = NULL; nua, nua->nua_magic,
nh, nh ? nh->nh_magic : NULL,
su_msg_save(nua->nua_current, sumsg); e->e_msg ? sip_object(e->e_msg) : NULL,
e->e_tags);
e->e_nh = NULL; su_msg_destroy(frame->nf_saved);
nua->nua_callback(e->e_event, e->e_status, e->e_phrase, if (frame->nf_nua == NULL)
nua, nua->nua_magic, return;
nh, nh ? nh->nh_magic : NULL, nua->nua_current = frame->nf_next;
e->e_msg ? sip_object(e->e_msg) : NULL, }
e->e_tags);
if (nh && !NH_IS_DEFAULT(nh) && nua_handle_unref(nh)) { if (nh && nua_handle_unref(nh)) {
#if HAVE_NUA_HANDLE_DEBUG #if HAVE_NUA_HANDLE_DEBUG
SU_DEBUG_0(("nua(%p): freed by application\n", (void *)nh)); SU_DEBUG_0(("nua(%p): freed by application\n", (void *)nh));
#else #else
SU_DEBUG_9(("nua(%p): freed by application\n", (void *)nh)); SU_DEBUG_9(("nua(%p): freed by application\n", (void *)nh));
#endif #endif
} }
if (!su_msg_is_non_null(nua->nua_current))
return;
if (e->e_msg)
msg_destroy(e->e_msg), e->e_msg = NULL;
su_msg_destroy(nua->nua_current);
} }
/** Get current request message. @NEW_1_12_4. /** Get current request message. @NEW_1_12_4.
...@@ -1057,7 +1074,9 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e) ...@@ -1057,7 +1074,9 @@ void nua_event(nua_t *root_magic, su_msg_r sumsg, event_t *e)
*/ */
msg_t *nua_current_request(nua_t const *nua) msg_t *nua_current_request(nua_t const *nua)
{ {
return nua && nua->nua_current ? su_msg_data(nua->nua_current)->e_msg : NULL; if (nua && nua->nua_current && su_msg_is_non_null(nua->nua_current->nf_saved))
return su_msg_data(nua->nua_current->nf_saved)->e_msg;
return NULL;
} }
/** Get request message from saved nua event. @NEW_1_12_4. /** Get request message from saved nua event. @NEW_1_12_4.
...@@ -1075,14 +1094,15 @@ msg_t *nua_saved_event_request(nua_saved_event_t const *saved) ...@@ -1075,14 +1094,15 @@ msg_t *nua_saved_event_request(nua_saved_event_t const *saved)
*/ */
int nua_save_event(nua_t *nua, nua_saved_event_t return_saved[1]) int nua_save_event(nua_t *nua, nua_saved_event_t return_saved[1])
{ {
if (nua && return_saved) { if (return_saved) {
su_msg_save(return_saved, nua->nua_current); if (nua && nua->nua_current) {
if (su_msg_is_non_null(return_saved)) { su_msg_save(return_saved, nua->nua_current->nf_saved);
/* Remove references to tasks */ return su_msg_is_non_null(return_saved);
su_msg_remove_refs(return_saved);
return 1;
} }
else
*return_saved = NULL;
} }
return 0; return 0;
} }
......
...@@ -197,6 +197,8 @@ int nh_is_special(nua_handle_t *nh) ...@@ -197,6 +197,8 @@ int nh_is_special(nua_handle_t *nh)
return nh == NULL || nh->nh_special; return nh == NULL || nh->nh_special;
} }
typedef struct nua_event_frame_s nua_event_frame_t;
extern char const nua_internal_error[]; extern char const nua_internal_error[];
#define NUA_INTERNAL_ERROR 900, nua_internal_error #define NUA_INTERNAL_ERROR 900, nua_internal_error
...@@ -214,7 +216,7 @@ struct nua_s { ...@@ -214,7 +216,7 @@ struct nua_s {
nua_callback_f nua_callback; nua_callback_f nua_callback;
nua_magic_t *nua_magic; nua_magic_t *nua_magic;
nua_saved_event_t nua_current[1]; nua_event_frame_t *nua_current;
nua_saved_event_t nua_signal[1]; nua_saved_event_t nua_signal[1];
/* Engine state flags */ /* Engine state flags */
......
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