summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2014-06-19 09:42:02 +0000
committerNanang Izzuddin <nanang@teluu.com>2014-06-19 09:42:02 +0000
commit1321a047fb6d74374f7948eda41ad5c84884daab (patch)
tree3a0bd88b9610bbbe80b1de3351dea390e04058bf /pjlib
parentf0d0ddae6055d905cb55b6aebe17f073c52cb383 (diff)
Fix #1773: Added group lock to SIP transport to avoid race condition between transport callback and destroy.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4862 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/ssl_sock.h16
-rw-r--r--pjlib/src/pj/ssl_sock_ossl.c28
2 files changed, 44 insertions, 0 deletions
diff --git a/pjlib/include/pj/ssl_sock.h b/pjlib/include/pj/ssl_sock.h
index 23843717..92e86aab 100644
--- a/pjlib/include/pj/ssl_sock.h
+++ b/pjlib/include/pj/ssl_sock.h
@@ -552,6 +552,11 @@ typedef struct pj_ssl_sock_info
*/
unsigned long last_native_err;
+ /**
+ * Group lock assigned to the ioqueue key.
+ */
+ pj_grp_lock_t *grp_lock;
+
} pj_ssl_sock_info;
@@ -561,6 +566,17 @@ typedef struct pj_ssl_sock_info
typedef struct pj_ssl_sock_param
{
/**
+ * Optional group lock to be assigned to the ioqueue key.
+ *
+ * Note that when a secure socket listener is configured with a group
+ * lock, any new secure socket of an accepted incoming connection
+ * will have its own group lock created automatically by the library,
+ * this group lock can be queried via pj_ssl_sock_get_info() in the info
+ * field pj_ssl_sock_info::grp_lock.
+ */
+ pj_grp_lock_t *grp_lock;
+
+ /**
* Specifies socket address family, either pj_AF_INET() and pj_AF_INET6().
*
* Default is pj_AF_INET().
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
index 3aa85b0d..cc99433d 100644
--- a/pjlib/src/pj/ssl_sock_ossl.c
+++ b/pjlib/src/pj/ssl_sock_ossl.c
@@ -1693,6 +1693,24 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
asock_cfg.async_cnt = ssock->param.async_cnt;
asock_cfg.concurrency = ssock->param.concurrency;
asock_cfg.whole_data = PJ_TRUE;
+
+ /* If listener socket has group lock, automatically create group lock
+ * for the new socket.
+ */
+ if (ssock_parent->param.grp_lock) {
+ pj_grp_lock_t *glock;
+
+ status = pj_grp_lock_create(ssock->pool, NULL, &glock);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+ /* Temporarily add ref the group lock until active socket creation,
+ * to make sure that group lock is destroyed if the active socket
+ * creation fails.
+ */
+ pj_grp_lock_add_ref(glock);
+ asock_cfg.grp_lock = ssock->param.grp_lock = glock;
+ }
pj_bzero(&asock_cb, sizeof(asock_cb));
asock_cb.on_data_read = asock_on_data_read;
@@ -1707,6 +1725,11 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
ssock,
&ssock->asock);
+ /* This will destroy the group lock if active socket creation fails */
+ if (asock_cfg.grp_lock) {
+ pj_grp_lock_dec_ref(asock_cfg.grp_lock);
+ }
+
if (status != PJ_SUCCESS)
goto on_return;
@@ -2122,6 +2145,9 @@ PJ_DEF(pj_status_t) pj_ssl_sock_get_info (pj_ssl_sock_t *ssock,
/* Last known OpenSSL error code */
info->last_native_err = ssock->last_err;
+ /* Group lock */
+ info->grp_lock = ssock->param.grp_lock;
+
return PJ_SUCCESS;
}
@@ -2488,6 +2514,7 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock,
asock_cfg.async_cnt = ssock->param.async_cnt;
asock_cfg.concurrency = ssock->param.concurrency;
asock_cfg.whole_data = PJ_TRUE;
+ asock_cfg.grp_lock = ssock->param.grp_lock;
pj_bzero(&asock_cb, sizeof(asock_cb));
asock_cb.on_accept_complete = asock_on_accept_complete;
@@ -2574,6 +2601,7 @@ PJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock,
asock_cfg.async_cnt = ssock->param.async_cnt;
asock_cfg.concurrency = ssock->param.concurrency;
asock_cfg.whole_data = PJ_TRUE;
+ asock_cfg.grp_lock = ssock->param.grp_lock;
pj_bzero(&asock_cb, sizeof(asock_cb));
asock_cb.on_connect_complete = asock_on_connect_complete;