Index: pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c	(revision 3347)
+++ pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c	(revision 3348)
@@ -481,6 +481,9 @@
     int		     au_rx_idx = 0;
     int		     crypto_suites_cnt;
+    pj_status_t	     status = PJ_SUCCESS;
 
     PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL);
+
+    pj_lock_acquire(srtp->mutex);
 
     if (srtp->session_inited) {
@@ -506,10 +509,13 @@
     if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || 
 	au_rx_idx == -1)
-	return PJMEDIA_SRTP_ENOTSUPCRYPTO;
+    {
+	status = PJMEDIA_SRTP_ENOTSUPCRYPTO;
+	goto on_return;
+    }
 
     /* If all options points to 'NULL' method, just bypass SRTP */
     if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) {
 	srtp->bypass_srtp = PJ_TRUE;
-	return PJ_SUCCESS;
+	goto on_return;
     }
 
@@ -517,5 +523,8 @@
     if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len ||
         rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len)
-	return PJMEDIA_SRTP_EINKEYLEN;
+    {
+	status = PJMEDIA_SRTP_EINKEYLEN;
+	goto on_return;
+    }
 
     /* Init transmit direction */
@@ -543,5 +552,6 @@
     err = srtp_create(&srtp->srtp_tx_ctx, &tx_);
     if (err != err_status_ok) {
-	return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
+	status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
+	goto on_return;
     }
     srtp->tx_policy = *tx;
@@ -576,5 +586,6 @@
     if (err != err_status_ok) {
 	srtp_dealloc(srtp->srtp_tx_ctx);
-	return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
+	status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
+	goto on_return;
     }
     srtp->rx_policy = *rx;
@@ -599,5 +610,7 @@
     }
 
-    return PJ_SUCCESS;
+on_return:
+    pj_lock_release(srtp->mutex);
+    return status;
 }
 
@@ -612,6 +625,10 @@
     PJ_ASSERT_RETURN(srtp, PJ_EINVAL);
 
-    if (!p_srtp->session_inited)
+    pj_lock_acquire(p_srtp->mutex);
+
+    if (!p_srtp->session_inited) {
+	pj_lock_release(p_srtp->mutex);
 	return PJ_SUCCESS;
+    }
 
     err = srtp_dealloc(p_srtp->srtp_rx_ctx);
@@ -629,4 +646,6 @@
 
     p_srtp->session_inited = PJ_FALSE;
+
+    pj_lock_release(p_srtp->mutex);
 
     return PJ_SUCCESS;
@@ -688,7 +707,9 @@
 
     /* Save the callbacks */
+    pj_lock_acquire(srtp->mutex);
     srtp->rtp_cb = rtp_cb;
     srtp->rtcp_cb = rtcp_cb;
     srtp->user_data = user_data;
+    pj_lock_release(srtp->mutex);
 
     /* Attach itself to transport */
@@ -697,7 +718,9 @@
 				      &srtp_rtcp_cb);
     if (status != PJ_SUCCESS) {
+	pj_lock_acquire(srtp->mutex);
 	srtp->rtp_cb = NULL;
 	srtp->rtcp_cb = NULL;
 	srtp->user_data = NULL;
+	pj_lock_release(srtp->mutex);
 	return status;
     }
@@ -718,7 +741,9 @@
 
     /* Clear up application infos from transport */
+    pj_lock_acquire(srtp->mutex);
     srtp->rtp_cb = NULL;
     srtp->rtcp_cb = NULL;
     srtp->user_data = NULL;
+    pj_lock_release(srtp->mutex);
 }
 
@@ -735,7 +760,4 @@
 	return pjmedia_transport_send_rtp(srtp->member_tp, pkt, size);
 
-    if (!srtp->session_inited)
-	return PJ_SUCCESS;
-
     if (size > sizeof(srtp->rtp_tx_buffer))
 	return PJ_ETOOBIG;
@@ -744,4 +766,8 @@
 
     pj_lock_acquire(srtp->mutex);
+    if (!srtp->session_inited) {
+	pj_lock_release(srtp->mutex);
+	return PJ_EINVALIDOP;
+    }
     err = srtp_protect(srtp->srtp_tx_ctx, srtp->rtp_tx_buffer, &len);
     pj_lock_release(srtp->mutex);
@@ -779,7 +805,4 @@
     }
 
-    if (!srtp->session_inited)
-	return PJ_SUCCESS;
-
     if (size > sizeof(srtp->rtcp_tx_buffer))
 	return PJ_ETOOBIG;
@@ -788,4 +811,8 @@
 
     pj_lock_acquire(srtp->mutex);
+    if (!srtp->session_inited) {
+	pj_lock_release(srtp->mutex);
+	return PJ_EINVALIDOP;
+    }
     err = srtp_protect_rtcp(srtp->srtp_tx_ctx, srtp->rtcp_tx_buffer, &len);
     pj_lock_release(srtp->mutex);
@@ -820,6 +847,4 @@
     PJ_ASSERT_RETURN(tp, PJ_EINVAL);
 
-    pj_lock_acquire(srtp->mutex);
-
     if (srtp->setting.close_member_tp && srtp->member_tp) {
 	pjmedia_transport_close(srtp->member_tp);
@@ -828,4 +853,6 @@
     status = pjmedia_transport_srtp_stop(tp);
 
+    /* In case mutex is being acquired by other thread */
+    pj_lock_acquire(srtp->mutex);
     pj_lock_release(srtp->mutex);
 
@@ -844,4 +871,6 @@
     int len = size;
     err_status_t err;
+    void (*cb)(void*, void*, pj_ssize_t) = NULL;
+    void *cb_data = NULL;
 
     if (srtp->bypass_srtp) {
@@ -850,5 +879,5 @@
     }
 
-    if (size < 0 || !srtp->session_inited) {
+    if (size < 0) {
 	return;
     }
@@ -862,6 +891,9 @@
     pj_lock_acquire(srtp->mutex);
 
+    if (!srtp->session_inited) {
+	pj_lock_release(srtp->mutex);
+	return;
+    }
     err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
-
     if (srtp->probation_cnt > 0 && 
 	(err == err_status_replay_old || err == err_status_replay_fail)) 
@@ -885,13 +917,18 @@
     }
 
-    if (err == err_status_ok) {
-	srtp->rtp_cb(srtp->user_data, pkt, len);
-    } else {
+    if (err != err_status_ok) {
 	PJ_LOG(5,(srtp->pool->obj_name, 
 		  "Failed to unprotect SRTP, pkt size=%d, err=%s", 
 		  size, get_libsrtp_errstr(err)));
+    } else {
+	cb = srtp->rtp_cb;
+	cb_data = srtp->user_data;
     }
 
     pj_lock_release(srtp->mutex);
+
+    if (cb) {
+	(*cb)(cb_data, pkt, len);
+    }
 }
 
@@ -904,4 +941,6 @@
     int len = size;
     err_status_t err;
+    void (*cb)(void*, void*, pj_ssize_t) = NULL;
+    void *cb_data = NULL;
 
     if (srtp->bypass_srtp) {
@@ -910,5 +949,5 @@
     }
 
-    if (size < 0 || !srtp->session_inited) {
+    if (size < 0) {
 	return;
     }
@@ -919,15 +958,23 @@
     pj_lock_acquire(srtp->mutex);
 
+    if (!srtp->session_inited) {
+	pj_lock_release(srtp->mutex);
+	return;
+    }
     err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
-
-    if (err == err_status_ok) {
-	srtp->rtcp_cb(srtp->user_data, pkt, len);
-    } else {
+    if (err != err_status_ok) {
 	PJ_LOG(5,(srtp->pool->obj_name, 
 		  "Failed to unprotect SRTCP, pkt size=%d, err=%s",
 		  size, get_libsrtp_errstr(err)));
-    }
-    
+    } else {
+	cb = srtp->rtcp_cb;
+	cb_data = srtp->user_data;
+    }
+
     pj_lock_release(srtp->mutex);
+
+    if (cb) {
+	(*cb)(cb_data, pkt, len);
+    }
 }
 
@@ -1572,4 +1619,9 @@
     pj_lock_acquire(srtp->mutex);
 
+    if (!srtp->session_inited) {
+	pj_lock_release(srtp->mutex);
+	return PJ_EINVALIDOP;
+    }
+
     if (is_rtp)
 	err = srtp_unprotect(srtp->srtp_rx_ctx, pkt, pkt_len);
