[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380288 - /team/mmichelson/pool_shar...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 28 15:40:22 CST 2013


Author: mmichelson
Date: Mon Jan 28 15:40:18 2013
New Revision: 380288

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380288
Log:
Progress towards having chan_gulp use the threadpool.

This takes careful consideration. The channel-related stuff needs
to occur in the PBX thread and the PJSIP stuff needs to happen in
the threadpool. This commit takes care of gulp_answer, gulp_indicate,
and gulp_call.

Next will be gulp_hangup and gulp_request.


Modified:
    team/mmichelson/pool_shark/channels/chan_gulp.c

Modified: team/mmichelson/pool_shark/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/channels/chan_gulp.c?view=diff&rev=380288&r1=380287&r2=380288
==============================================================================
--- team/mmichelson/pool_shark/channels/chan_gulp.c (original)
+++ team/mmichelson/pool_shark/channels/chan_gulp.c Mon Jan 28 15:40:18 2013
@@ -186,12 +186,24 @@
 	return chan;
 }
 
+static int answer(void *data)
+{
+	pj_status_t status;
+	pjsip_tx_data *packet;
+	struct ast_sip_session *session = data;
+
+	if ((status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet)) == PJ_SUCCESS) {
+		ast_sip_session_send_response(session, packet);
+	}
+
+	ao2_ref(session, -1);
+	return (status == PJ_SUCCESS) ? 0 : -1;
+}
+
 /*! \brief Function called by core when we should answer a Gulp session */
 static int gulp_answer(struct ast_channel *ast)
 {
 	struct ast_sip_session *session = ast_channel_tech_pvt(ast);
-	pj_status_t status;
-	pjsip_tx_data *packet;
 
 	if (ast_channel_state(ast) == AST_STATE_UP) {
 		return 0;
@@ -199,13 +211,8 @@
 
 	ast_setstate(ast, AST_STATE_UP);
 
-	pj_thread_register_check();
-
-	if ((status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet)) == PJ_SUCCESS) {
-		ast_sip_session_send_response(session, packet);
-	}
-
-	return (status == PJ_SUCCESS) ? 0 : -1;
+	ao2_ref(session, +1);
+	return ast_sip_push_task(session->work, answer, session);
 }
 
 /*! \brief Function called by core to read any waiting frames */
@@ -282,55 +289,100 @@
 	return 0;
 }
 
+struct indicate_data {
+	struct ast_sip_session *session;
+	int condition;
+	int response_code;
+	void *frame_data;
+	size_t datalen;
+};
+
+static void indicate_data_destroy(void *obj)
+{
+	struct indicate_data *ind_data = obj;
+	ast_free(ind_data->frame_data);
+}
+
+static struct indicate_data *indicate_data_alloc(struct ast_sip_session *session,
+		int condition, int response_code, const void *frame_data, size_t datalen)
+{
+	struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
+	if (!ind_data) {
+		return NULL;
+	}
+	ind_data->frame_data = ast_malloc(datalen);
+	if (!ind_data->frame_data) {
+		ao2_ref(ind_data, -1);
+		return NULL;
+	}
+	memcpy(ind_data->frame_data, frame_data, datalen);
+	ind_data->datalen = datalen;
+	ind_data->condition = condition;
+	ind_data->response_code = response_code;
+	return ind_data;
+}
+
+static int indicate(void *data)
+{
+	struct indicate_data *ind_data = data;
+	struct ast_sip_session *session = ind_data->session;
+	int response_code = ind_data->response_code;
+	pjsip_tx_data *packet = NULL;
+
+	if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
+		ast_sip_session_send_response(session, packet);
+	}
+
+	ao2_ref(ind_data, -1);
+	return 0;
+}
+
 /*! \brief Function called by core to ask the channel to indicate some sort of condition */
 static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
 {
 	int res = 0;
 	struct ast_sip_session *session = ast_channel_tech_pvt(ast);
-	pj_status_t status = -1;
-	pjsip_tx_data *packet = NULL;
-
-	pj_thread_register_check();
+	int response_code = 0;
 
 	switch (condition) {
 	case AST_CONTROL_RINGING:
 		if (ast_channel_state(ast) == AST_STATE_RING) {
-			status = pjsip_inv_answer(session->inv_session, 180, NULL, NULL, &packet);
+			response_code = 180;
 		} else {
 			res = -1;
 		}
 		break;
 	case AST_CONTROL_BUSY:
 		if (ast_channel_state(ast) != AST_STATE_UP) {
-			status = pjsip_inv_answer(session->inv_session, 486, NULL, NULL, &packet);
+			response_code = 486;
 		} else {
 			res = -1;
 		}
 		break;
 	case AST_CONTROL_CONGESTION:
 		if (ast_channel_state(ast) != AST_STATE_UP) {
-			status = pjsip_inv_answer(session->inv_session, 503, NULL, NULL, &packet);
+			response_code = 503;
 		} else {
 			res = -1;
 		}
 		break;
 	case AST_CONTROL_INCOMPLETE:
 		if (ast_channel_state(ast) != AST_STATE_UP) {
-			status = pjsip_inv_answer(session->inv_session, 484, NULL, NULL, &packet);
+			response_code = 484;
 		} else {
 			res = -1;
 		}
 		break;
 	case AST_CONTROL_PROCEEDING:
 		if (ast_channel_state(ast) != AST_STATE_UP) {
-			status = pjsip_inv_answer(session->inv_session, 100, NULL, NULL, &packet);
+			response_code = 100;
 		} else {
 			res = -1;
 		}
 		break;
 	case AST_CONTROL_PROGRESS:
 		if (ast_channel_state(ast) != AST_STATE_UP) {
-			status = pjsip_inv_answer(session->inv_session, 183, NULL, NULL, &packet);
+			response_code = 183;
 		} else {
 			res = -1;
 		}
@@ -358,8 +410,13 @@
 		break;
 	}
 
-	if (packet && (status == PJ_SUCCESS)) {
-		ast_sip_session_send_response(session, packet);
+	if (!res) {
+		struct indicate_data *ind_data = indicate_data_alloc(session, condition, response_code, data, datalen);
+		if (!ind_data) {
+			res = -1;
+		} else {
+			ast_sip_push_task(session->work, indicate, ind_data);
+		}
 	}
 
 	return res;
@@ -408,21 +465,28 @@
 	return res;
 }
 
+static int call(void *data)
+{
+	struct ast_sip_session *session = data;
+	pjsip_tx_data *packet;
+
+	if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	ast_sip_session_send_request(session, packet);
+
+	ao2_ref(session, -1);
+	return 0;
+}
+
 /*! \brief Function called by core to actually start calling a remote party */
 static int gulp_call(struct ast_channel *ast, const char *dest, int timeout)
 {
 	struct ast_sip_session *session = ast_channel_tech_pvt(ast);
-	pjsip_tx_data *packet;
-
-	pj_thread_register_check();
-
-	if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
-		return -1;
-	}
-
-	ast_sip_session_send_request(session, packet);
-
-	return 0;
+
+	ao2_ref(session, +1);
+	return ast_sip_push_task(session->work, call, session);
 }
 
 /*! \brief Internal function which translates from Asterisk cause codes to SIP response codes */




More information about the asterisk-commits mailing list