Added prev_state in tsx_state event
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@110 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 885b5bb..d982456 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -892,6 +892,8 @@
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 @@
/* 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 @@
}
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 de2f85a..33b9f22 100644
--- a/pjsip/src/pjsip/sip_transport_loop.c
+++ b/pjsip/src/pjsip/sip_transport_loop.c
@@ -253,6 +253,11 @@
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 @@
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,26 +275,54 @@
if (PJ_TIME_VAL_GTE(node->sent_time, now))
break;
+ /* Delete this from the list. */
+ pj_list_erase(node);
+
+ /* Add to local list. */
+ pj_list_push_back(&s, node);
+ }
+
+ /* Move expired "incoming" packet to local list. */
+ while (!pj_list_empty(&loop->recv_list)) {
+ struct recv_list *node = loop->recv_list.next;
+
+ /* 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);
}
- /* Delete this from the list. */
- pj_list_erase(node);
-
/* Decrement tdata reference counter. */
pjsip_tx_data_dec_ref(node->tdata);
}
- /* Process "incoming" packets. */
- while (!pj_list_empty(&loop->recv_list)) {
- struct recv_list *node = loop->recv_list.next;
+ /* Process "incoming" packet. */
+ while (!pj_list_empty(&r)) {
+ struct recv_list *node = r.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;
+ pj_list_erase(node);
/* Notify transport manager about the "incoming packet" */
size_eaten = pjsip_tpmgr_receive_packet(loop->base.tpmgr,
@@ -298,15 +331,10 @@
/* 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;