[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380291 - in /team/mmichelson/pool_s...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 28 17:39:35 CST 2013


Author: mmichelson
Date: Mon Jan 28 17:39:32 2013
New Revision: 380291

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380291
Log:
Create a generic method for pushing tasks synchronously.


Modified:
    team/mmichelson/pool_shark/channels/chan_gulp.c
    team/mmichelson/pool_shark/include/asterisk/res_sip.h
    team/mmichelson/pool_shark/res/res_sip.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=380291&r1=380290&r2=380291
==============================================================================
--- team/mmichelson/pool_shark/channels/chan_gulp.c (original)
+++ team/mmichelson/pool_shark/channels/chan_gulp.c Mon Jan 28 17:39:32 2013
@@ -599,43 +599,11 @@
 }
 
 struct request_data {
-	ast_cond_t cond;
-	ast_mutex_t lock;
 	struct ast_sip_session *session;
-	int success;
-	int complete;
 	struct ast_sip_work *work;
 	const char *dest;
 };
 
-static void request_data_destroy(void *obj)
-{
-	struct request_data *req_data = obj;
-	ast_mutex_destroy(&req_data->lock);
-	ast_cond_destroy(&req_data->cond);
-	/* Don't unref the session or destroy the work since they
-	 * are now owned by other structures. They'll be destroyed
-	 * in due time
-	 */
-}
-
-static struct request_data *request_data_alloc(struct ast_sip_work *work, const char *dest)
-{
-	struct request_data *req_data = ao2_alloc(sizeof(*req_data), request_data_destroy);
-	if (!req_data) {
-		return NULL;
-	}
-	ast_mutex_init(&req_data->lock);
-	ast_cond_init(&req_data->cond, NULL);
-	req_data->dest = ast_strdup(dest);
-	if (!req_data->dest) {
-		ao2_cleanup(req_data);
-		return NULL;
-	}
-	req_data->work = work;
-	return req_data;
-}
-
 static int request(void *obj)
 {
 	struct request_data *req_data = obj;
@@ -643,24 +611,17 @@
 	struct ast_sip_session *session = NULL;
 
 	if (!endpoint) {
-		goto end;;
+		return -1;
 	}
 
 	ast_string_field_set(endpoint, context, "default");
 	ast_parse_allow_disallow(&endpoint->prefs, endpoint->codecs, "ulaw", 1);
 
 	if (!(session = ast_sip_session_create_outgoing(endpoint, req_data->dest, req_data->work))) {
-		goto end;
-	}
-
-	req_data->success = 1;
+		return -1;
+	}
+
 	req_data->session = session;
-
-end:
-	ast_mutex_lock(&req_data->lock);
-	req_data->complete = 1;
-	ast_cond_signal(&req_data->cond);
-	ast_mutex_unlock(&req_data->lock);
 	return 0;
 }
 
@@ -668,38 +629,27 @@
 static struct ast_channel *gulp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
 {
 	struct ast_sip_work *work = ast_sip_create_work();
-	struct request_data *req_data = request_data_alloc(work, data);
+	struct request_data req_data;
 	struct ast_sip_session *session;
 	if (!work) {
 		return NULL;
 	}
 
-	/* XXX This probably needs to be made more generic. It may be
-	 * necessary to push tasks synchronously in other places, and repeating
-	 * this logic is cray-cray.
-	 */
-	if (ast_sip_push_task(work, request, req_data)) {
-		ao2_cleanup(req_data);
+	req_data.dest = data;
+	req_data.work = work;
+
+	if (ast_sip_push_task_synchronous(work, request, &req_data)) {
 		ast_sip_destroy_work(work);
 		return NULL;
 	}
 
-	ast_mutex_lock(&req_data->lock);
-	while (!req_data->complete) {
-		ast_cond_wait(&req_data->cond, &req_data->lock);
-	}
-
-	if (!req_data->success) {
-		return NULL;
-	}
-	session = req_data->session;
+	session = req_data.session;
 
 	if (!(session->channel = gulp_new(session, AST_STATE_DOWN, NULL, NULL, requestor ? ast_channel_linkedid(requestor) : NULL, NULL))) {
 		/* Session needs to be terminated prematurely */
 		return NULL;
 	}
 
-	ao2_cleanup(req_data);
 	return session->channel;
 }
 

Modified: team/mmichelson/pool_shark/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/include/asterisk/res_sip.h?view=diff&rev=380291&r1=380290&r2=380291
==============================================================================
--- team/mmichelson/pool_shark/include/asterisk/res_sip.h (original)
+++ team/mmichelson/pool_shark/include/asterisk/res_sip.h Mon Jan 28 17:39:32 2013
@@ -477,6 +477,17 @@
 int ast_sip_push_task(struct ast_sip_work *work, int (*sip_task)(void *), void *task_data);
 
 /*!
+ * \brief Push a task into the SIP threadpool and wait for it to complete
+ *
+ * \param work The SIP work to which the task belongs
+ * \param sip_task The task to execute
+ * \param task_data The parameter to pass to the task when it executes
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_push_task_synchronous(struct ast_sip_work *work, int (*sip_task)(void *), void *task_data);
+
+/*!
  * \brief SIP body description
  *
  * This contains a type and subtype that will be added as

Modified: team/mmichelson/pool_shark/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/res/res_sip.c?view=diff&rev=380291&r1=380290&r2=380291
==============================================================================
--- team/mmichelson/pool_shark/res/res_sip.c (original)
+++ team/mmichelson/pool_shark/res/res_sip.c Mon Jan 28 17:39:32 2013
@@ -444,6 +444,52 @@
 	return ast_taskprocessor_push(work->queue, sip_task, task_data);
 }
 
+struct sync_task_data {
+	ast_mutex_t lock;
+	ast_cond_t cond;
+	int complete;
+	int fail;
+	int (*task)(void *);
+	void *task_data;
+};
+
+static int sync_task(void *data)
+{
+	struct sync_task_data *std = data;
+	std->fail = std->task(std->task_data);
+
+	ast_mutex_lock(&std->lock);
+	std->complete = 1;
+	ast_cond_signal(&std->cond);
+	ast_mutex_unlock(&std->lock);
+	return std->fail;
+}
+
+int ast_sip_push_task_synchronous(struct ast_sip_work *work, int (*sip_task)(void *), void *task_data)
+{
+	/* This method is an onion */
+	struct sync_task_data std;
+	ast_mutex_init(&std.lock);
+	ast_cond_init(&std.cond, NULL);
+	std.fail = std.complete = 0;
+	std.task = sip_task;
+	std.task_data = task_data;
+
+	if (ast_taskprocessor_push(work->queue, sync_task, &std)) {
+		return -1;
+	}
+
+	ast_mutex_lock(&std.lock);
+	while (!std.complete) {
+		ast_cond_wait(&std.cond, &std.lock);
+	}
+	ast_mutex_unlock(&std.lock);
+
+	ast_mutex_destroy(&std.lock);
+	ast_cond_destroy(&std.cond);
+	return std.fail;
+}
+
 void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size)
 {
 	size_t chars_to_copy = MIN(size - 1, pj_strlen(src));




More information about the asterisk-commits mailing list