summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsip/sip_transport_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip/src/pjsip/sip_transport_udp.c')
-rw-r--r--pjsip/src/pjsip/sip_transport_udp.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/pjsip/src/pjsip/sip_transport_udp.c b/pjsip/src/pjsip/sip_transport_udp.c
index 36995b08..ef9ecbdd 100644
--- a/pjsip/src/pjsip/sip_transport_udp.c
+++ b/pjsip/src/pjsip/sip_transport_udp.c
@@ -76,6 +76,9 @@ struct udp_transport
pjsip_rx_data **rdata;
int is_closing;
pj_bool_t is_paused;
+
+ /* Group lock to be used by UDP transport and ioqueue key */
+ pj_grp_lock_t *grp_lock;
};
@@ -345,6 +348,31 @@ static pj_status_t udp_send_msg( pjsip_transport *transport,
return status;
}
+
+/* Clean up UDP resources */
+static void udp_on_destroy(void *arg)
+{
+ struct udp_transport *tp = (struct udp_transport*)arg;
+ int i;
+
+ /* Destroy rdata */
+ for (i=0; i<tp->rdata_cnt; ++i) {
+ pj_pool_release(tp->rdata[i]->tp_info.pool);
+ }
+
+ /* Destroy reference counter. */
+ if (tp->base.ref_cnt)
+ pj_atomic_destroy(tp->base.ref_cnt);
+
+ /* Destroy lock */
+ if (tp->base.lock)
+ pj_lock_destroy(tp->base.lock);
+
+ /* Destroy pool. */
+ pjsip_endpt_release_pool(tp->base.endpt, tp->base.pool);
+}
+
+
/*
* udp_destroy()
*
@@ -397,22 +425,15 @@ static pj_status_t udp_destroy( pjsip_transport *transport )
break;
}
- /* Destroy rdata */
- for (i=0; i<tp->rdata_cnt; ++i) {
- pj_pool_release(tp->rdata[i]->tp_info.pool);
+ if (tp->grp_lock) {
+ pj_grp_lock_t *grp_lock = tp->grp_lock;
+ tp->grp_lock = NULL;
+ pj_grp_lock_dec_ref(grp_lock);
+ /* Transport may have been deleted at this point */
+ } else {
+ udp_on_destroy(tp);
}
- /* Destroy reference counter. */
- if (tp->base.ref_cnt)
- pj_atomic_destroy(tp->base.ref_cnt);
-
- /* Destroy lock */
- if (tp->base.lock)
- pj_lock_destroy(tp->base.lock);
-
- /* Destroy pool. */
- pjsip_endpt_release_pool(tp->base.endpt, tp->base.pool);
-
return PJ_SUCCESS;
}
@@ -602,10 +623,19 @@ static pj_status_t register_to_ioqueue(struct udp_transport *tp)
{
pj_ioqueue_t *ioqueue;
pj_ioqueue_callback ioqueue_cb;
+ pj_status_t status;
/* Ignore if already registered */
if (tp->key != NULL)
return PJ_SUCCESS;
+
+ /* Create group lock */
+ status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ pj_grp_lock_add_ref(tp->grp_lock);
+ pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp, &udp_on_destroy);
/* Register to ioqueue. */
ioqueue = pjsip_endpt_get_ioqueue(tp->base.endpt);
@@ -613,8 +643,8 @@ static pj_status_t register_to_ioqueue(struct udp_transport *tp)
ioqueue_cb.on_read_complete = &udp_on_read_complete;
ioqueue_cb.on_write_complete = &udp_on_write_complete;
- return pj_ioqueue_register_sock(tp->base.pool, ioqueue, tp->sock, tp,
- &ioqueue_cb, &tp->key);
+ return pj_ioqueue_register_sock2(tp->base.pool, ioqueue, tp->sock,
+ tp->grp_lock, tp, &ioqueue_cb, &tp->key);
}
/* Start ioqueue asynchronous reading to all rdata */