summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-01-07 23:01:13 +0000
committerBenny Prijono <bennylp@teluu.com>2006-01-07 23:01:13 +0000
commit8bdb232f47e4f3518f983a8921c6cdab388bbcbe (patch)
treec38d319da22d93c74fe9ed072c15461e01d65603 /pjsip
parent57b75697969b3cfd0cc5fe6ca3c98b38acc16608 (diff)
Added prev_state in tsx_state event
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@110 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/src/pjsip/sip_transaction.c12
-rw-r--r--pjsip/src/pjsip/sip_transport_loop.c58
2 files changed, 53 insertions, 17 deletions
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 885b5bb4..d9824562 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -892,6 +892,8 @@ static void tsx_set_state( pjsip_transaction *tsx,
pjsip_event_id_e event_src_type,
void *event_src )
{
+ pjsip_tsx_state_e prev_state = tsx->state;
+
PJ_LOG(5, (tsx->obj_name, "State changed from %s to %s, event=%s",
state_str[tsx->state], state_str[state],
pjsip_event_str(event_src_type)));
@@ -909,7 +911,8 @@ static void tsx_set_state( pjsip_transaction *tsx,
/* Inform TU */
if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) {
pjsip_event e;
- PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src);
+ PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src,
+ prev_state);
(*tsx->tsx_user->on_tsx_state)(tsx, &e);
}
@@ -2106,7 +2109,12 @@ static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
}
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
- /* Inform TU. */
+ /* Inform TU.
+ * blp: You might be tempted to move this notification before
+ * sending ACK, but I think you shouldn't. Better set-up
+ * everything before calling tsx_user's callback to avoid
+ * mess up.
+ */
tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,
PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
diff --git a/pjsip/src/pjsip/sip_transport_loop.c b/pjsip/src/pjsip/sip_transport_loop.c
index de2f85ae..33b9f229 100644
--- a/pjsip/src/pjsip/sip_transport_loop.c
+++ b/pjsip/src/pjsip/sip_transport_loop.c
@@ -253,6 +253,11 @@ static pj_status_t loop_destroy(pjsip_transport *tp)
static int loop_thread(void *arg)
{
struct loop_transport *loop = arg;
+ struct recv_list r;
+ struct send_list s;
+
+ pj_list_init(&r);
+ pj_list_init(&s);
while (!loop->thread_quit_flag) {
pj_time_val now;
@@ -262,7 +267,7 @@ static int loop_thread(void *arg)
pj_lock_acquire(loop->base.lock);
- /* Process pending send notification. */
+ /* Move expired send notification to local list. */
while (!pj_list_empty(&loop->send_list)) {
struct send_list *node = loop->send_list.next;
@@ -270,27 +275,55 @@ static int loop_thread(void *arg)
if (PJ_TIME_VAL_GTE(node->sent_time, now))
break;
- /* Notify callback. */
- if (node->callback) {
- (*node->callback)(&loop->base, node->token, node->sent);
- }
-
/* Delete this from the list. */
pj_list_erase(node);
- /* Decrement tdata reference counter. */
- pjsip_tx_data_dec_ref(node->tdata);
+ /* Add to local list. */
+ pj_list_push_back(&s, node);
}
- /* Process "incoming" packets. */
+ /* Move expired "incoming" packet to local list. */
while (!pj_list_empty(&loop->recv_list)) {
struct recv_list *node = loop->recv_list.next;
- pj_ssize_t size_eaten;
/* Break when next node time is greater than now. */
if (PJ_TIME_VAL_GTE(node->rdata.pkt_info.timestamp, now))
break;
+ /* Delete this from the list. */
+ pj_list_erase(node);
+
+ /* Add to local list. */
+ pj_list_push_back(&r, node);
+
+ }
+
+ pj_lock_release(loop->base.lock);
+
+ /* Process send notification and incoming packet notification
+ * without holding down the loop's mutex.
+ */
+ while (!pj_list_empty(&s)) {
+ struct send_list *node = s.next;
+
+ pj_list_erase(node);
+
+ /* Notify callback. */
+ if (node->callback) {
+ (*node->callback)(&loop->base, node->token, node->sent);
+ }
+
+ /* Decrement tdata reference counter. */
+ pjsip_tx_data_dec_ref(node->tdata);
+ }
+
+ /* Process "incoming" packet. */
+ while (!pj_list_empty(&r)) {
+ struct recv_list *node = r.next;
+ pj_ssize_t size_eaten;
+
+ pj_list_erase(node);
+
/* Notify transport manager about the "incoming packet" */
size_eaten = pjsip_tpmgr_receive_packet(loop->base.tpmgr,
&node->rdata);
@@ -298,15 +331,10 @@ static int loop_thread(void *arg)
/* Must "eat" all the packets. */
pj_assert(size_eaten == node->rdata.pkt_info.len);
- /* Delete this from the list. */
- pj_list_erase(node);
-
/* Done. */
pjsip_endpt_release_pool(loop->base.endpt,
node->rdata.tp_info.pool);
}
-
- pj_lock_release(loop->base.lock);
}
return 0;