[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380250 - in /team/mmichelson/pool_s...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jan 28 13:20:04 CST 2013
Author: mmichelson
Date: Mon Jan 28 13:20:01 2013
New Revision: 380250
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380250
Log:
Dispatch incoming new INVITE handling to the threadpool.
Modified:
team/mmichelson/pool_shark/include/asterisk/res_sip_session.h
team/mmichelson/pool_shark/res/res_sip_session.c
Modified: team/mmichelson/pool_shark/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/include/asterisk/res_sip_session.h?view=diff&rev=380250&r1=380249&r2=380250
==============================================================================
--- team/mmichelson/pool_shark/include/asterisk/res_sip_session.h (original)
+++ team/mmichelson/pool_shark/include/asterisk/res_sip_session.h Mon Jan 28 13:20:01 2013
@@ -140,8 +140,9 @@
* as placing all registered supplements onto the session.
* \param endpoint The endpoint that this session communicates with
* \param inv_session The PJSIP INVITE session data
- */
-struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv);
+ * \param work SIP work queue to use for this session. May be NULL.
+ */
+struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv, struct ast_sip_work *work);
/*!
* \brief Create a new outgoing SIP session
Modified: team/mmichelson/pool_shark/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/res/res_sip_session.c?view=diff&rev=380250&r1=380249&r2=380250
==============================================================================
--- team/mmichelson/pool_shark/res/res_sip_session.c (original)
+++ team/mmichelson/pool_shark/res/res_sip_session.c Mon Jan 28 13:20:01 2013
@@ -441,7 +441,7 @@
return 0;
}
-struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv_session)
+struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, pjsip_inv_session *inv_session, struct ast_sip_work *work)
{
RAII_VAR(struct ast_sip_session *, session, ao2_alloc(sizeof(*session), session_destructor), ao2_cleanup);
struct ast_sip_session_supplement *iter;
@@ -453,7 +453,14 @@
if (!session->datastores) {
return NULL;
}
- session->work = ast_sip_create_work();
+ if (work) {
+ session->work = work;
+ } else {
+ session->work = ast_sip_create_work();
+ }
+ if (!session->work) {
+ return NULL;
+ }
session->endpoint = endpoint;
session->inv_session = inv_session;
if (add_supplements(session)) {
@@ -557,7 +564,7 @@
return NULL;
}
- if (!(session = ast_sip_session_alloc(endpoint, inv_session))) {
+ if (!(session = ast_sip_session_alloc(endpoint, inv_session, NULL))) {
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
return NULL;
}
@@ -644,7 +651,23 @@
return inv_session;
}
-static void handle_new_invite(pjsip_rx_data *rdata)
+struct new_request_data {
+ pjsip_rx_data *rdata;
+ struct ast_sip_work *work;
+};
+
+static struct new_request_data *new_request_data_alloc(pjsip_rx_data *rdata, struct ast_sip_work *work)
+{
+ struct new_request_data *nrd = ast_calloc(1, sizeof(*nrd));
+ if (!nrd) {
+ return NULL;
+ }
+ nrd->rdata = rdata;
+ nrd->work = work;
+ return nrd;
+}
+
+static int handle_new_invite_request(void *data)
{
/* The goal here is to create SIP work and throw it into
* the threadpool. The threadpool callback will deal with
@@ -653,17 +676,21 @@
* branch at this point, we'll just handle this in PJSIP's
* endpoint thread.
*/
+ struct new_request_data *nrd = data;
+ pjsip_rx_data *rdata = nrd->rdata;
+ struct ast_sip_work *work = nrd->work;
pjsip_tx_data *tdata = NULL;
pjsip_inv_session *inv_session = NULL;
struct ast_sip_endpoint *endpoint = NULL;
struct ast_sip_session *session = NULL;
pjsip_rdata_sdp_info *sdp_info;
pjmedia_sdp_session *local = NULL;
+ int destroy_work = 1;
inv_session = pre_session_setup(rdata);
if (!inv_session) {
/* pre_session_setup() returns a response on failure */
- return;
+ goto end;
}
endpoint = ast_sip_identify_endpoint(rdata);
@@ -673,29 +700,33 @@
} else {
pjsip_inv_terminate(inv_session, 403, PJ_FALSE);
}
- return;
- }
-
- session = ast_sip_session_alloc(endpoint, inv_session);
+ goto end;
+ }
+
+ session = ast_sip_session_alloc(endpoint, inv_session, work);
if (!session) {
if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
} else {
pjsip_inv_send_msg(inv_session, tdata);
}
- return;
+ goto end;
}
/* From this point on, any calls to pjsip_inv_terminate have the last argument as PJ_TRUE
* so that we will be notified so we can destroy the session properly
+ *
+ * Also from this point on, the work belongs to the session, so there is no need to destroy
+ * it ourselves. When the session dies, so will the work.
*/
+ destroy_work = 0;
if (ast_sip_requires_authentication(endpoint, rdata)) {
if (ast_sip_authenticate_request(endpoint, rdata)) {
struct ast_sip_digest_challenge_data challenge_data;
if (pjsip_inv_initial_answer(inv_session, rdata, 401, NULL, NULL, &tdata) != PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
- return;
+ goto end;
}
memset(&challenge_data, 0, sizeof(challenge_data));
if (ast_sip_get_authentication_credentials(endpoint, &challenge_data)) {
@@ -704,11 +735,11 @@
} else {
pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
}
- return;
+ goto end;
}
ast_sip_add_digest_to_challenge(&challenge_data, tdata);
ast_sip_session_send_response(session, tdata);
- return;
+ goto end;
}
}
@@ -722,7 +753,7 @@
} else {
pjsip_inv_terminate(inv_session, 416, PJ_TRUE);
}
- return;
+ goto end;
case SIP_GET_DEST_EXTEN_NOT_FOUND:
case SIP_GET_DEST_EXTEN_PARTIAL:
default:
@@ -731,7 +762,7 @@
} else {
pjsip_inv_terminate(inv_session, 404, PJ_TRUE);
}
- return;
+ goto end;
};
if ((sdp_info = pjsip_rdata_get_sdp_info(rdata)) && (sdp_info->sdp_err == PJ_SUCCESS)) {
@@ -741,7 +772,7 @@
} else {
pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
}
- return;
+ goto end;
}
/* We are creating a local SDP which is an answer to their offer */
local = create_local_sdp(inv_session, session, sdp_info->sdp);
@@ -757,7 +788,7 @@
} else {
pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
}
- return;
+ goto end;
} else {
pjsip_inv_set_local_sdp(inv_session, local);
}
@@ -765,13 +796,20 @@
/* At this point, we've verified what we can, so let's go ahead and send a 100 Trying out */
if (pjsip_inv_initial_answer(inv_session, rdata, 100, NULL, NULL, &tdata) != PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_TRUE);
- return;
+ goto end;
}
ast_sip_session_send_response(session, tdata);
handle_incoming_request(session, rdata);
-}
-
+
+end:
+ if (destroy_work) {
+ ast_sip_destroy_work(work);
+ }
+ pjsip_rx_data_free_cloned(rdata);
+ ast_free(nrd);
+ return 0;
+}
/*!
* \brief Called when a new SIP request comes into PJSIP
*
@@ -790,21 +828,43 @@
*/
static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata)
{
+ pjsip_rx_data *clone;
+ struct ast_sip_work *work;
+ struct new_request_data *nrd;
+ pj_status_t res = PJ_FALSE;
pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
- pj_bool_t res = PJ_FALSE;
+
switch (rdata->msg_info.msg->line.req.method.id) {
case PJSIP_INVITE_METHOD:
if (dlg) {
ast_log(LOG_WARNING, "on_rx_request called for INVITE in mid-dialog?\n");
break;
}
- ast_log(LOG_NOTICE, "INVITE request received by session module!\n");
- handle_new_invite(rdata);
res = PJ_TRUE;
+
+ if (pjsip_rx_data_clone(rdata, 0, &clone) != PJ_SUCCESS) {
+ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+ break;
+ }
+
+ work = ast_sip_create_work();
+ if (!work) {
+ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+ pjsip_rx_data_free_cloned(clone);
+ break;
+ }
+
+ nrd = new_request_data_alloc(clone, work);
+ if (!nrd) {
+ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+ pjsip_rx_data_free_cloned(clone);
+ ast_sip_destroy_work(work);
+ break;
+ }
+ ast_sip_push_task(work, handle_new_invite_request, nrd);
break;
case PJSIP_OTHER_METHOD:
/* Area for INFO and REFER, possibly other methods */
- res = PJ_TRUE;
break;
default:
break;
More information about the asterisk-commits
mailing list