提交 ef020e60 authored 作者: Michael Jerris's avatar Michael Jerris

Wed Sep 3 14:20:29 EDT 2008 Pekka Pessi <first.last@nokia.com>

  * nua: added reference counting for client-side transactions



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9421 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 a2740a96
Wed Sep 3 14:29:03 EDT 2008 Wed Sep 3 14:29:36 EDT 2008
...@@ -354,12 +354,12 @@ void nua_dialog_usage_remove(nua_owner_t *own, ...@@ -354,12 +354,12 @@ void nua_dialog_usage_remove(nua_owner_t *own,
* *
* Zap dialog state (leg, tag and route) if no usages remain. * Zap dialog state (leg, tag and route) if no usages remain.
*/ */
static static void
void nua_dialog_usage_remove_at(nua_owner_t *own, nua_dialog_usage_remove_at(nua_owner_t *own,
nua_dialog_state_t *ds, nua_dialog_state_t *ds,
nua_dialog_usage_t **at, nua_dialog_usage_t **at,
nua_client_request_t *cr0, nua_client_request_t *cr0,
nua_server_request_t *sr0) nua_server_request_t *sr0)
{ {
if (*at) { if (*at) {
nua_dialog_usage_t *du = *at; nua_dialog_usage_t *du = *at;
...@@ -376,17 +376,9 @@ void nua_dialog_usage_remove_at(nua_owner_t *own, ...@@ -376,17 +376,9 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
o ? " with event " : "", o ? o->o_type :"")); o ? " with event " : "", o ? o->o_type :""));
du->du_class->usage_remove(own, ds, du, cr0, sr0); du->du_class->usage_remove(own, ds, du, cr0, sr0);
/* Destroy saved client request */ /* Clean reference to saved client request */
if (cr0 != du->du_cr && nua_client_is_bound(du->du_cr)) { if (du->du_cr)
nua_client_bind(cr = du->du_cr, NULL); nua_client_bind(du->du_cr, NULL);
if (nua_client_is_queued(cr))
nua_client_request_complete(cr);
else if (nua_client_is_reporting(cr))
;
else
nua_client_request_destroy(cr);
}
/* Clean references from queued client requests */ /* Clean references from queued client requests */
for (cr = ds->ds_cr; cr; cr = cr_next) { for (cr = ds->ds_cr; cr; cr = cr_next) {
...@@ -395,6 +387,7 @@ void nua_dialog_usage_remove_at(nua_owner_t *own, ...@@ -395,6 +387,7 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
cr->cr_usage = NULL; cr->cr_usage = NULL;
} }
/* Clean references from queued server requests */
for (sr = ds->ds_sr; sr; sr = sr_next) { for (sr = ds->ds_sr; sr; sr = sr_next) {
sr_next = sr->sr_next; sr_next = sr->sr_next;
if (sr->sr_usage == du) { if (sr->sr_usage == du) {
......
...@@ -276,6 +276,8 @@ struct nua_client_request ...@@ -276,6 +276,8 @@ struct nua_client_request
unsigned short cr_retry_count; /**< Retry count for this request */ unsigned short cr_retry_count; /**< Retry count for this request */
uint32_t cr_seq; uint32_t cr_seq;
unsigned cr_refs; /**< References to client request */
/* Flags used with offer-answer */ /* Flags used with offer-answer */
unsigned short cr_answer_recv; /**< Recv answer in response unsigned short cr_answer_recv; /**< Recv answer in response
...@@ -300,7 +302,6 @@ struct nua_client_request ...@@ -300,7 +302,6 @@ struct nua_client_request
unsigned cr_waiting:1; /**< Request is waiting */ unsigned cr_waiting:1; /**< Request is waiting */
unsigned cr_challenged:1; /**< Request was challenged */ unsigned cr_challenged:1; /**< Request was challenged */
unsigned cr_wait_for_cred:1; /**< Request is pending authentication */ unsigned cr_wait_for_cred:1; /**< Request is pending authentication */
unsigned cr_wait_for_timer:1; /**< Request is waiting for a timer to expire */
unsigned cr_restarting:1; /**< Request is being restarted */ unsigned cr_restarting:1; /**< Request is being restarted */
unsigned cr_reporting:1; /**< Reporting in progress */ unsigned cr_reporting:1; /**< Reporting in progress */
unsigned cr_terminating:1; /**< Request terminates the usage */ unsigned cr_terminating:1; /**< Request terminates the usage */
...@@ -523,8 +524,23 @@ void *nua_private_client_request(nua_client_request_t const *cr) ...@@ -523,8 +524,23 @@ void *nua_private_client_request(nua_client_request_t const *cr)
return (void *)(cr + 1); return (void *)(cr + 1);
} }
void nua_client_request_complete(nua_client_request_t *); nua_client_request_t *nua_client_request_ref(nua_client_request_t *);
void nua_client_request_destroy(nua_client_request_t *); int nua_client_request_unref(nua_client_request_t *);
#if HAVE_MEMLEAK_LOG
#define nua_client_request_ref(cr) \
nua_client_request_ref_by((cr), __FILE__, __LINE__, __func__)
#define nua_client_request_unref(cr) \
nua_client_request_unref_by((cr), __FILE__, __LINE__, __func__)
nua_client_request_t *nua_client_request_ref_by(nua_client_request_t *,
char const *file, unsigned line,
char const *who);
int nua_client_request_unref_by(nua_client_request_t *,
char const *file, unsigned line, char const *who);
#endif
int nua_client_request_queue(nua_client_request_t *cr); int nua_client_request_queue(nua_client_request_t *cr);
...@@ -533,8 +549,8 @@ su_inline int nua_client_is_queued(nua_client_request_t const *cr) ...@@ -533,8 +549,8 @@ su_inline int nua_client_is_queued(nua_client_request_t const *cr)
return cr && cr->cr_prev; return cr && cr->cr_prev;
} }
void nua_client_request_remove(nua_client_request_t *cr); int nua_client_request_remove(nua_client_request_t *cr);
void nua_client_request_clean(nua_client_request_t *cr); int nua_client_request_clean(nua_client_request_t *cr);
int nua_client_bind(nua_client_request_t *cr, nua_dialog_usage_t *du); int nua_client_bind(nua_client_request_t *cr, nua_dialog_usage_t *du);
su_inline int nua_client_is_bound(nua_client_request_t const *cr) su_inline int nua_client_is_bound(nua_client_request_t const *cr)
......
...@@ -276,7 +276,7 @@ void nua_session_usage_remove(nua_handle_t *nh, ...@@ -276,7 +276,7 @@ void nua_session_usage_remove(nua_handle_t *nh,
NULL); NULL);
} }
nua_client_request_destroy(cr); nua_client_request_remove(cr);
cr_next = ds->ds_cr; cr_next = ds->ds_cr;
} }
...@@ -1177,9 +1177,9 @@ int nua_stack_ack(nua_t *nua, nua_handle_t *nh, nua_event_t e, ...@@ -1177,9 +1177,9 @@ int nua_stack_ack(nua_t *nua, nua_handle_t *nh, nua_event_t e,
soa_set_params(nh->nh_soa, TAG_NEXT(tags)); soa_set_params(nh->nh_soa, TAG_NEXT(tags));
} }
error = nua_invite_client_ack(cr, tags); nua_client_request_ref(cr);
nua_client_request_clean(cr); error = nua_invite_client_ack(cr, tags);
if (error < 0) { if (error < 0) {
if (ss->ss_reason == NULL) if (ss->ss_reason == NULL)
...@@ -1195,8 +1195,7 @@ int nua_stack_ack(nua_t *nua, nua_handle_t *nh, nua_event_t e, ...@@ -1195,8 +1195,7 @@ int nua_stack_ack(nua_t *nua, nua_handle_t *nh, nua_event_t e,
else if (ss) else if (ss)
signal_call_state_change(nh, ss, 200, "ACK sent", nua_callstate_ready); signal_call_state_change(nh, ss, 200, "ACK sent", nua_callstate_ready);
if (!nua_client_is_queued(cr) && !nua_client_is_bound(cr)) nua_client_request_unref(cr);
nua_client_request_destroy(cr);
nua_client_next_request(nh->nh_ds->ds_cr, 1); nua_client_next_request(nh->nh_ds->ds_cr, 1);
...@@ -1233,7 +1232,8 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags) ...@@ -1233,7 +1232,8 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
if (!ds->ds_leg) { if (!ds->ds_leg) {
/* XXX - fix nua_dialog_usage_remove_at() instead! */ /* XXX - fix nua_dialog_usage_remove_at() instead! */
nta_outgoing_destroy(cr->cr_orq); nua_client_request_clean(cr);
nua_client_request_remove(cr);
return -1; return -1;
} }
...@@ -1366,9 +1366,11 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags) ...@@ -1366,9 +1366,11 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
if (error == -1) if (error == -1)
msg_destroy(msg); msg_destroy(msg);
nua_client_request_remove(cr);
cr->cr_acked = 1; /* ... or we have at least tried */ cr->cr_acked = 1; /* ... or we have at least tried */
nua_client_request_clean(cr);
nua_client_request_remove(cr);
return error; return error;
} }
...@@ -1452,11 +1454,19 @@ static int nua_cancel_client_request(nua_client_request_t *cr, ...@@ -1452,11 +1454,19 @@ static int nua_cancel_client_request(nua_client_request_t *cr,
return nua_client_return(cr, 481, "No transaction to CANCEL", msg); return nua_client_return(cr, 481, "No transaction to CANCEL", msg);
} }
assert(cr->cr_orq == NULL);
cr->cr_orq = nta_outgoing_tcancel(du->du_cr->cr_orq, cr->cr_orq = nta_outgoing_tcancel(du->du_cr->cr_orq,
nua_client_orq_response, cr, nua_client_orq_response,
nua_client_request_ref(cr),
TAG_NEXT(tags)); TAG_NEXT(tags));
return cr->cr_orq ? 0 : -1; if (cr->cr_orq == NULL) {
nua_client_request_unref(cr);
return -1;
}
return 0;
} }
/** @NUA_EVENT nua_r_cancel /** @NUA_EVENT nua_r_cancel
...@@ -3630,7 +3640,6 @@ static int nua_bye_client_init(nua_client_request_t *cr, ...@@ -3630,7 +3640,6 @@ static int nua_bye_client_init(nua_client_request_t *cr,
if (nh->nh_soa) if (nh->nh_soa)
soa_terminate(nh->nh_soa, 0); soa_terminate(nh->nh_soa, 0);
du->du_cr = NULL;
nua_client_bind(cr, du); nua_client_bind(cr, du);
return 0; return 0;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论