[asterisk-commits] russell: branch russell/sched_thread r140403 - in /team/russell/sched_thread:...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 28 17:02:25 CDT 2008


Author: russell
Date: Thu Aug 28 17:02:25 2008
New Revision: 140403

URL: http://svn.digium.com/view/asterisk?view=rev&rev=140403
Log:
 - Add a bit more to the sched thread API
 - Start converting chan_sip over to use it.  (That means that at the
   end, the SIP scheduler will be running in its own thread.  I'm curious
   to see how bad it's going to blow up ...)

Modified:
    team/russell/sched_thread/channels/chan_sip.c
    team/russell/sched_thread/include/asterisk/sched.h
    team/russell/sched_thread/main/sched.c

Modified: team/russell/sched_thread/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/russell/sched_thread/channels/chan_sip.c?view=diff&rev=140403&r1=140402&r2=140403
==============================================================================
--- team/russell/sched_thread/channels/chan_sip.c (original)
+++ team/russell/sched_thread/channels/chan_sip.c Thu Aug 28 17:02:25 2008
@@ -832,7 +832,7 @@
 static int sip_reloading = FALSE;                       /*!< Flag for avoiding multiple reloads at the same time */
 static enum channelreloadreason sip_reloadreason;       /*!< Reason for last reload/load of configuration */
 
-static struct sched_context *sched;     /*!< The scheduling context */
+static struct sched_thread *sched;     /*!< The scheduling context */
 static struct io_context *io;           /*!< The IO context */
 static int *sipsock_read_id;            /*!< ID of IO entry for sipsock FD */
 
@@ -2491,17 +2491,25 @@
 	/* remove all current packets in this dialog */
 	while((cp = dialog->packets)) {
 		dialog->packets = dialog->packets->next;
-		AST_SCHED_DEL(sched, cp->retransid);
-		dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
+		if (sched_thread_del(sched, cp->retransid) > -1) {
+			dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
+		}
 		ast_free(cp);
 	}
 
-	AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
-
-	AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
+	if (sched_thread_del(sched, dialog->waitid) > -1) {
+		dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr");
+	}
+
+	if (sched_thread_del(sched, dialog->initid) > -1) {
+		dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr");
+	}
 	
-	if (dialog->autokillid > -1)
-		AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr"));
+	if (dialog->autokillid > -1) {
+		if (sched_thread_del(sched, dialog->autokillid) > -1) {
+			dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr");
+		}
+	}
 
 	dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
 	return NULL;
@@ -3106,7 +3114,9 @@
 		siptimer_a = pkt->timer_t1 * 2;
 
 	/* Schedule retransmission */
-	AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1);
+	sched_thread_del(sched, pkt->retransid);
+	pkt->retransid = sched_thread_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
+
 	if (sipdebug)
 		ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
 
@@ -3192,7 +3202,7 @@
 
 	if (p->do_history)
 		append_history(p, "SchedDestroy", "%d ms", ms);
-	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
+	p->autokillid = sched_thread_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
 
 	if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0)
 		stop_session_timer(p);
@@ -3208,7 +3218,7 @@
 	if (p->autokillid > -1) {
 		int res3;
 		
-		if (!(res3 = ast_sched_del(sched, p->autokillid))) {
+		if (!(res3 = sched_thread_del(sched, p->autokillid))) {
 			append_history(p, "CancelDestroy", "");
 			p->autokillid = -1;
 			dialog_unref(p, "dialog unrefd because autokillid is de-sched'd");
@@ -3261,7 +3271,7 @@
 			 * the packet's retransid will be set to -1. The atomicity of the setting and checking
 			 * of the retransid to -1 is ensured since in both cases p's lock is held.
 			 */
-			while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
+			while (cur->retransid > -1 && sched_thread_del(sched, cur->retransid)) {
 				sip_pvt_unlock(p);
 				usleep(1);
 				sip_pvt_lock(p);
@@ -3310,7 +3320,7 @@
 				if (sipdebug)
 					ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
 			}
-			AST_SCHED_DEL(sched, cur->retransid);
+			sched_thread_del(sched, cur->retransid);
 			res = 0;
 			break;
 		}
@@ -3789,8 +3799,8 @@
 	 *
 	 * NOTE: once peer is refcounted, this probably is no longer necessary.
 	 */
-	AST_SCHED_DEL(sched, peer->expire);
-	AST_SCHED_DEL(sched, peer->pokeexpire);
+	sched_thread_del(sched, peer->expire);
+	sched_thread_del(sched, peer->pokeexpire);
 
 	register_peer_exten(peer, FALSE);
 	ast_free_ha(peer->ha);
@@ -4019,7 +4029,8 @@
 		/* Cache peer */
 		ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
 		if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
-			AST_SCHED_REPLACE(peer->expire, sched, global_rtautoclear * 1000, expire_register, (void *) peer);
+			sched_thread_del(sched, peer->expire);
+			peer->expire = sched_thread_add(sched, global_rtautoclear * 1000, expire_register, peer);
 			/* we could be incr. its refcount right here, but I guess, since
 			   peers hang around until module unload time anyway, it's not worth the trouble */
 		}
@@ -4492,10 +4503,14 @@
 		p->invitestate = INV_CALLING;
 	
 		/* Initialize auto-congest time */
-		AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 
-								dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 
-								dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
-								dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
+		if (sched_thread_del(sched, p->initid) > -1) { 
+			dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed");
+		}
+		p->initid = sched_thread_add(sched, p->timer_b, auto_congest,
+				dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded"));
+		if (p->initid == -1) {
+			dialog_unref(p, "sched add failed");
+		}
 	}
 	return res;
 }
@@ -4516,8 +4531,8 @@
 		reg->call = dialog_unref(reg->call, "unref reg->call");
 		/* reg->call = sip_destroy(reg->call); */
 	}
-	AST_SCHED_DEL(sched, reg->expire);	
-	AST_SCHED_DEL(sched, reg->timeout);
+	sched_thread_del(sched, reg->expire);	
+	sched_thread_del(sched, reg->timeout);
 	
 	ast_string_field_free_memory(reg);
 	ast_atomic_fetchadd_int(&regobjs, -1);
@@ -4603,7 +4618,7 @@
 	/* Destroy Session-Timers if allocated */
 	if (p->stimer) {
 		if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1)
-			AST_SCHED_DEL(sched, p->stimer->st_schedid);
+			sched_thread_del(sched, p->stimer->st_schedid);
 		ast_free(p->stimer);
 		p->stimer = NULL;
 	}
@@ -5091,7 +5106,9 @@
 				   but we can't send one while we have "INVITE" outstanding. */
 				ast_set_flag(&p->flags[0], SIP_PENDINGBYE);	
 				ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);	
-				AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
+				if (sched_thread_del(sched, p->waitid) > -1) {
+					dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr");
+				}
 				if (sip_cancel_destroy(p))
 					ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
 			}
@@ -6036,14 +6053,14 @@
 	p->ocseq = INITIAL_CSEQ;
 
 	if (sip_methods[intended_method].need_rtp) {
-		p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+		p->rtp = ast_rtp_new_with_bindaddr(sched_thread_get_context(sched), io, 1, 0, bindaddr.sin_addr);
 		/* If the global videosupport flag is on, we always create a RTP interface for video */
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
-			p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+			p->vrtp = ast_rtp_new_with_bindaddr(sched_thread_get_context(sched), io, 1, 0, bindaddr.sin_addr);
  		if (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT))
- 			p->trtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+ 			p->trtp = ast_rtp_new_with_bindaddr(sched_thread_get_context(sched), io, 1, 0, bindaddr.sin_addr);
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
-			p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
+			p->udptl = ast_udptl_new_with_bindaddr(sched_thread_get_context(sched), io, 0, bindaddr.sin_addr);
  		if (!p->rtp|| (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp) 
 				|| (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) && !p->trtp)) {
  			ast_log(LOG_WARNING, "Unable to create RTP audio %s%ssession: %s\n",
@@ -9702,10 +9719,14 @@
 			dialog_unlink_all(p, TRUE, TRUE);
 			p = dialog_unref(p, "unref dialog after unlink_all");
 			if (r->timeout > -1) {
-				AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
-										registry_unref(_data, "del for REPLACE of registry ptr"), 
-										registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"),
-										registry_addref(r,"add for REPLACE registry ptr"));
+				if (sched_thread_del(sched, r->timeout) > -1) {
+					registry_unref(_data, "del for REPLACE of registry ptr"), 
+				}
+				r->timeout = sched_thread_add(sched, global_reg_timeout * 1000, sip_reg_timeout, 
+						registry_addref(r, "add"));
+				if (r->timeout == -1) {
+					registry_unref(_data, "sched_add failed"), 
+				}
 				ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
 			} else {
 				r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr"));
@@ -22525,14 +22546,14 @@
 	
 	ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
 
-	if (!(sched = sched_context_create())) {
-		ast_log(LOG_ERROR, "Unable to create scheduler context\n");
+	if (!(sched = sched_thread_create())) {
+		ast_log(LOG_ERROR, "Unable to create scheduler thread\n");
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	if (!(io = io_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create I/O context\n");
-		sched_context_destroy(sched);
+		sched = sched_thread_destroy(sched);
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
@@ -22552,7 +22573,7 @@
 	if (ast_channel_register(&sip_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
 		io_context_destroy(io);
-		sched_context_destroy(sched);
+		sched = sched_thread_destroy(sched);
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
@@ -22712,7 +22733,7 @@
 
 	clear_sip_domains();
 	close(sipsock);
-	sched_context_destroy(sched);
+	sched = sched_thread_destroy(sched);
 	con = ast_context_find(used_context);
 	if (con)
 		ast_context_destroy(con, "SIP");

Modified: team/russell/sched_thread/include/asterisk/sched.h
URL: http://svn.digium.com/view/asterisk/team/russell/sched_thread/include/asterisk/sched.h?view=diff&rev=140403&r1=140402&r2=140403
==============================================================================
--- team/russell/sched_thread/include/asterisk/sched.h (original)
+++ team/russell/sched_thread/include/asterisk/sched.h Thu Aug 28 17:02:25 2008
@@ -49,15 +49,17 @@
  * and not a copy of the value of the id.
  */
 #define AST_SCHED_DEL(sched, id) \
-	do { \
+	({ \
 		int _count = 0; \
-		while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
-			usleep(1); \
-		} \
-		if (_count == 10) \
-			ast_debug(3, "Unable to cancel schedule ID %d.\n", id); \
+		int _sched_res = -1; \
+		while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) \
+			usleep(1); \
+		if (_count == 10 && option_debug > 2) { \
+			ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \
+		} \
 		id = -1; \
-	} while (0);
+		(_sched_res); \
+	})
 
 #define AST_SCHED_DEL_UNREF(sched, id, refcall)			\
 	do { \
@@ -279,7 +281,13 @@
 int sched_thread_add(struct sched_thread *st, int when, ast_sched_cb cb,
 		const void *data);
 
+int sched_thread_add_variable(struct sched_thread *st, int when, ast_sched_cb cb,
+		const void *data, int variable);
+
 int sched_thread_del(struct sched_thread *st, int id);
+
+/*! XXX I hate this and want it to go away eventually */
+struct sched_context *sched_thread_get_context(struct sched_thread *st);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/russell/sched_thread/main/sched.c
URL: http://svn.digium.com/view/asterisk/team/russell/sched_thread/main/sched.c?view=diff&rev=140403&r1=140402&r2=140403
==============================================================================
--- team/russell/sched_thread/main/sched.c (original)
+++ team/russell/sched_thread/main/sched.c Thu Aug 28 17:02:25 2008
@@ -119,6 +119,11 @@
 	return NULL;
 }
 
+struct sched_context *sched_thread_get_context(struct sched_thread *st)
+{
+	return st->context;
+}
+
 struct sched_thread *sched_thread_destroy(struct sched_thread *st)
 {
 	if (st->thread != AST_PTHREADT_NULL) {
@@ -171,12 +176,12 @@
 	return st;
 }
 
-int sched_thread_add(struct sched_thread *st, int when, ast_sched_cb cb,
-		const void *data)
+int sched_thread_add_variable(struct sched_thread *st, int when, ast_sched_cb cb,
+		const void *data, int variable)
 {
 	int res;
 
-	res = ast_sched_add(st->context, when, cb, data);
+	res = ast_sched_add_variable(st->context, when, cb, data, variable);
 
 	if (res != -1) {
 		ast_mutex_lock(&st->lock);
@@ -187,10 +192,25 @@
 	return res;
 }
 
+int sched_thread_add(struct sched_thread *st, int when, ast_sched_cb cb,
+		const void *data)
+{
+	int res;
+
+	res = ast_sched_add(st->context, when, cb, data);
+
+	if (res != -1) {
+		ast_mutex_lock(&st->lock);
+		ast_cond_signal(&st->cond);
+		ast_mutex_unlock(&st->lock);
+	}
+
+	return res;
+}
+
 int sched_thread_del(struct sched_thread *st, int id)
 {
-	AST_SCHED_DEL(st->context, id);
-	return 0;
+	return AST_SCHED_DEL(st->context, id);
 }
 
 /* hash routines for sched */




More information about the asterisk-commits mailing list