[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