[svn-commits] murf: trunk r89478 - in /trunk: main/hashtab.c res/res_features.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Nov 21 09:11:43 CST 2007


Author: murf
Date: Wed Nov 21 09:11:43 2007
New Revision: 89478

URL: http://svn.digium.com/view/asterisk?view=rev&rev=89478
Log:
closes issue #11265; Thanks to snuffy for his work on neatening up the code and removing duplicated code.

Modified:
    trunk/main/hashtab.c
    trunk/res/res_features.c

Modified: trunk/main/hashtab.c
URL: http://svn.digium.com/view/asterisk/trunk/main/hashtab.c?view=diff&rev=89478&r1=89477&r2=89478
==============================================================================
--- trunk/main/hashtab.c (original)
+++ trunk/main/hashtab.c Wed Nov 21 09:11:43 2007
@@ -383,66 +383,27 @@
 
 int ast_hashtab_insert_immediate(struct ast_hashtab *tab, const void *obj)
 {
-	/* normally, you'd insert "safely" by checking to see if the element is
-	   already there; in this case, you must already have checked. If an element
-	   is already in the hashtable, that matches this one, most likely this one
-	   will be found first, but.... */
-
-	/* will force a resize if the resize func returns 1 */
-	/* returns 1 on success, 0 if there's a problem */
 	unsigned int h;
-	int c;
-	struct ast_hashtab_bucket *b;
-	
-	if (!tab)
-		return 0;
-
-	if (!obj)
-		return 0;
+	int res=0;
+	
+	if (!tab || !obj)
+		return res;
 
 	if (tab->do_locking)
 		ast_rwlock_wrlock(&tab->lock);
 
 	h = (*tab->hash)(obj) % tab->hash_tab_size;
 
-	for (c = 0, b = tab->array[h]; b; b = b->next)
-		c++;
-
-	if (c + 1 > tab->largest_bucket_size)
-		tab->largest_bucket_size = c + 1;
-
-	if (!(b = ast_calloc(1, sizeof(*b))))
-		return 0;
-
-	b->object = obj;
-	b->next = tab->array[h];
-
-	if (b->next)
-		b->next->prev = b;
-
-	tlist_add_head(&(tab->tlist), b);
-	
-	tab->array[h] = b;
-	tab->hash_tab_elements++;
-
-	if ((*tab->resize)(tab))
-		ast_hashtab_resize(tab);
+	res = ast_hashtab_insert_immediate_bucket(tab,obj,h);
 
 	if (tab->do_locking)
 		ast_rwlock_unlock(&tab->lock);
 
-	return 1;
+	return res;
 }
 
 int ast_hashtab_insert_immediate_bucket(struct ast_hashtab *tab, const void *obj, unsigned int h)
 {
-	/* normally, you'd insert "safely" by checking to see if the element is
-	   already there; in this case, you must already have checked. If an element
-	   is already in the hashtable, that matches this one, most likely this one
-	   will be found first, but.... */
-
-	/* will force a resize if the resize func returns 1 */
-	/* returns 1 on success, 0 if there's a problem */
 	int c;
 	struct ast_hashtab_bucket *b;
 	
@@ -759,8 +720,7 @@
 void *ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj)
 {
 	/* looks up the object; removes the corresponding bucket */
-	unsigned int h;
-	struct ast_hashtab_bucket *b;
+	const void *obj2;
 
 	if (!tab || !obj)
 		return 0;
@@ -768,24 +728,12 @@
 	if (tab->do_locking)
 		ast_rwlock_wrlock(&tab->lock);
 
-	h = (*tab->hash)(obj) % tab->hash_tab_size;
-	for (b = tab->array[h]; b; b = b->next) {
-		void *obj2;
-		
-		if (!(*tab->compare)(obj,b->object)) {
-			obj2 = ast_hashtab_remove_object_internal(tab,b,h);
-			
-			if (tab->do_locking)
-				ast_rwlock_unlock(&tab->lock);
-			
-			return (void *) obj2; /* inside this code, the obj's are untouchable, but outside, they aren't */
-		}
-	}
+	obj2 = ast_hashtab_remove_object_via_lookup_nolock(tab,obj);
 
 	if (tab->do_locking)
 		ast_rwlock_unlock(&tab->lock);
 
-	return 0;
+	return (void *)obj2;
 }
 
 void *ast_hashtab_remove_object_via_lookup_nolock(struct ast_hashtab *tab, void *obj)
@@ -799,15 +747,12 @@
 
 	h = (*tab->hash)(obj) % tab->hash_tab_size;
 	for (b = tab->array[h]; b; b = b->next) {
-		void *obj2;
 		
 		if (!(*tab->compare)(obj, b->object)) {
+			const void *obj2;
 
 			obj2 = ast_hashtab_remove_object_internal(tab, b, h);
 			
-			if (tab->do_locking)
-				ast_rwlock_unlock(&tab->lock);
-			
 			return (void *) obj2; /* inside this code, the obj's are untouchable, but outside, they aren't */
 		}
 	}
@@ -816,6 +761,27 @@
 }
 
 void *ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj)
+{
+	/* looks up the object by hash and then comparing pts in bucket list instead of
+	   calling the compare routine; removes the bucket -- a slightly cheaper operation */
+	/* looks up the object; removes the corresponding bucket */
+	const void *obj2;
+
+	if (!tab || !obj)
+		return 0;
+ 
+	if (tab->do_locking)
+		ast_rwlock_wrlock(&tab->lock);
+
+	obj2 = ast_hashtab_remove_this_object_nolock(tab,obj);
+	
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+
+	return (void *)obj2;
+}
+
+void *ast_hashtab_remove_this_object_nolock(struct ast_hashtab *tab, void *obj)
 {
 	/* looks up the object by hash and then comparing pts in bucket list instead of
 	   calling the compare routine; removes the bucket -- a slightly cheaper operation */
@@ -826,49 +792,13 @@
 	if (!tab || !obj)
 		return 0;
  
-	if (tab->do_locking)
-		ast_rwlock_wrlock(&tab->lock);
-
 	h = (*tab->hash)(obj) % tab->hash_tab_size;
 	for (b = tab->array[h]; b; b = b->next) {
-		const void *obj2;
 		
 		if (obj == b->object) {
-			obj2 = ast_hashtab_remove_object_internal(tab, b, h);
-			if (tab->do_locking)
-				ast_rwlock_unlock(&tab->lock);
-
-			return (void *) obj2; /* inside this code, the obj's are untouchable, but outside, they aren't */
-		}
-	}
-	
-	if (tab->do_locking)
-		ast_rwlock_unlock(&tab->lock);
-
-	return 0;
-}
-
-void *ast_hashtab_remove_this_object_nolock(struct ast_hashtab *tab, void *obj)
-{
-	/* looks up the object by hash and then comparing pts in bucket list instead of
-	   calling the compare routine; removes the bucket -- a slightly cheaper operation */
-	/* looks up the object; removes the corresponding bucket */
-	unsigned int h;
-	struct ast_hashtab_bucket *b;
-
-	if (!tab || !obj)
-		return 0;
- 
-	h = (*tab->hash)(obj) % tab->hash_tab_size;
-	for (b = tab->array[h]; b; b = b->next) {
-		const void *obj2;
-		
-		if (obj == b->object) {
+			const void *obj2;
 			obj2 = ast_hashtab_remove_object_internal(tab, b, h);
 			
-			if (tab->do_locking)
-				ast_rwlock_unlock(&tab->lock);
-
 			return (void *) obj2; /* inside this code, the obj's are untouchable, but outside, they aren't */
 		}
 	}

Modified: trunk/res/res_features.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_features.c?view=diff&rev=89478&r1=89477&r2=89478
==============================================================================
--- trunk/res/res_features.c (original)
+++ trunk/res/res_features.c Wed Nov 21 09:11:43 2007
@@ -390,6 +390,7 @@
 	AST_LIST_LOCK(&parkinglot);
 	/* Check for channel variable PARKINGEXTEN */
 	parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
+	ast_log(LOG_NOTICE,"Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	if (!ast_strlen_zero(parkingexten)) {
 		if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) {
 			AST_LIST_UNLOCK(&parkinglot);
@@ -397,10 +398,12 @@
 			ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
 			return 0;	/* Continue execution if possible */
 		}
+		ast_log(LOG_NOTICE,"2. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 		ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
 		x = atoi(parkingexten);
 	} else {
 		/* Select parking space within range */
+		ast_log(LOG_NOTICE,"3. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 		parking_range = parking_stop - parking_start+1;
 		for (i = 0; i < parking_range; i++) {
 			x = (i + parking_offset) % parking_range + parking_start;
@@ -423,6 +426,7 @@
 			parking_offset = x - parking_start + 1;
 	}
 	
+	ast_log(LOG_NOTICE,"4. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	chan->appl = "Parked Call";
 	chan->data = NULL; 
 
@@ -435,6 +439,7 @@
 			!ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
 	}
 	
+	ast_log(LOG_NOTICE,"5. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	pu->start = ast_tvnow();
 	pu->parkingnum = x;
 	pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
@@ -451,16 +456,19 @@
 	pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
 	AST_LIST_INSERT_TAIL(&parkinglot, pu, list);
 
+	ast_log(LOG_NOTICE,"6. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	/* If parking a channel directly, don't quiet yet get parking running on it */
 	if (peer == chan) 
 		pu->notquiteyet = 1;
 	AST_LIST_UNLOCK(&parkinglot);
 	/* Wake up the (presumably select()ing) thread */
+	ast_log(LOG_NOTICE,"7. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	pthread_kill(parking_thread, SIGURG);
 	ast_verb(2, "Parked %s on %d@%s. Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parking_con, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
 
 	if (pu->parkingnum != -1)
 		snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
+	ast_log(LOG_NOTICE,"8. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	manager_event(EVENT_FLAG_CALL, "ParkedCall",
 		"Exten: %s\r\n"
 		"Channel: %s\r\n"
@@ -474,35 +482,43 @@
 		S_OR(pu->chan->cid.cid_name, "<unknown>")
 		);
 
+	ast_log(LOG_NOTICE,"9. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	if (peer && adsipark && ast_adsi_available(peer)) {
 		adsi_announce_park(peer, pu->parkingexten);	/* Only supports parking numbers */
 		ast_adsi_unload_session(peer);
 	}
 
+	ast_log(LOG_NOTICE,"10. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	con = ast_context_find(parking_con);
 	if (!con) 
 		con = ast_context_create(NULL, parking_con, registrar);
 	if (!con)	/* Still no context? Bad */
 		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
 	/* Tell the peer channel the number of the parking space */
+	ast_log(LOG_NOTICE,"11. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	if (peer && pu->parkingnum != -1) { /* Only say number if it's a number */
 		/* Make sure we don't start saying digits to the channel being parked */
 		ast_set_flag(peer, AST_FLAG_MASQ_NOSTREAM);
 		ast_say_digits(peer, pu->parkingnum, "", peer->language);
 		ast_clear_flag(peer, AST_FLAG_MASQ_NOSTREAM);
+		ast_log(LOG_NOTICE,"12. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	}
 	if (con) {
 		if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
 			notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_INUSE);
+		ast_log(LOG_NOTICE,"13. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	}
 	if (pu->notquiteyet) {
 		/* Wake up parking thread if we're really done */
+		ast_log(LOG_NOTICE,"14. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 		ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
 			S_OR(parkmohclass, NULL),
 			!ast_strlen_zero(parkmohclass) ? strlen(parkmohclass) + 1 : 0);
 		pu->notquiteyet = 0;
 		pthread_kill(parking_thread, SIGURG);
-	}
+		ast_log(LOG_NOTICE,"15. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
+	}
+	ast_log(LOG_NOTICE,"16. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	return 0;
 }
 
@@ -512,17 +528,20 @@
 	struct ast_channel *chan;
 	struct ast_frame *f;
 
+	ast_log(LOG_NOTICE,"a. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	/* Make a new, fake channel that we'll use to masquerade in the real one */
 	if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
 		ast_log(LOG_WARNING, "Unable to create parked channel\n");
 		return -1;
 	}
 
+	ast_log(LOG_NOTICE,"b. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	/* Make formats okay */
 	chan->readformat = rchan->readformat;
 	chan->writeformat = rchan->writeformat;
 	ast_channel_masquerade(chan, rchan);
 
+	ast_log(LOG_NOTICE,"c. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	/* Setup the extensions and such */
 	set_c_e_p(chan, rchan->context, rchan->exten, rchan->priority);
 
@@ -531,7 +550,9 @@
 	if (f)
 		ast_frfree(f);
 
+	ast_log(LOG_NOTICE,"d. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	ast_park_call(chan, peer, timeout, extout);
+	ast_log(LOG_NOTICE,"e. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	return 0;
 }
 
@@ -590,7 +611,9 @@
 	set_peers(&parker, &parkee, peer, chan, sense);
 	/* Setup the exten/priority to be s/1 since we don't know
 	   where this call should return */
+	ast_log(LOG_NOTICE,"A. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	strcpy(chan->exten, "s");
+	ast_log(LOG_NOTICE,"B. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	chan->priority = 1;
 	if (chan->_state != AST_STATE_UP)
 		res = ast_answer(chan);
@@ -598,6 +621,7 @@
 		res = ast_safe_sleep(chan, 1000);
 	if (!res)
 		res = ast_park_call(parkee, parker, 0, NULL);
+	ast_log(LOG_NOTICE,"C. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 
 	ast_module_user_remove(u);
 
@@ -766,6 +790,8 @@
 	char xferto[256];
 	int res;
 
+	ast_log(LOG_NOTICE,"W. Chan %s cont/ext/prio = %s/%s/%d\n", chan->name, chan->context, chan->exten, chan->priority);
+	ast_log(LOG_NOTICE,"W. Peer %s cont/ext/prio = %s/%s/%d\n", peer->name, peer->context, peer->exten, peer->priority);
 	set_peers(&transferer, &transferee, peer, chan, sense);
 	transferer_real_context = real_ctx(transferer, transferee);
 	/* Start autoservice on chan while we talk to the originator */
@@ -789,21 +815,30 @@
 		finishup(transferee);
 		return res;
 	}
+	ast_log(LOG_NOTICE,"X. Chan %s cont/ext/prio = %s/%s/%d\n", chan->name, chan->context, chan->exten, chan->priority);
+	ast_log(LOG_NOTICE,"X. Peer %s cont/ext/prio = %s/%s/%d\n", peer->name, peer->context, peer->exten, peer->priority);
 	if (!strcmp(xferto, ast_parking_ext())) {
 		res = finishup(transferee);
+		ast_log(LOG_NOTICE,"Y. Chan %s cont/ext/prio = %s/%s/%d\n", chan->name, chan->context, chan->exten, chan->priority);
+		ast_log(LOG_NOTICE,"Y. Peer %s cont/ext/prio = %s/%s/%d\n", peer->name, peer->context, peer->exten, peer->priority);
 		if (res)
 			res = -1;
 		else if (!ast_park_call(transferee, transferer, 0, NULL)) {	/* success */
 			/* We return non-zero, but tell the PBX not to hang the channel when
 			   the thread dies -- We have to be careful now though.  We are responsible for 
 			   hanging up the channel, else it will never be hung up! */
-
+			ast_log(LOG_NOTICE,"Y2. Chan %s cont/ext/prio = %s/%s/%d\n", chan->name, chan->context, chan->exten, chan->priority);
+			ast_log(LOG_NOTICE,"Y2. Peer %s cont/ext/prio = %s/%s/%d\n", peer->name, peer->context, peer->exten, peer->priority);
 			return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER;
 		} else {
+			ast_log(LOG_NOTICE,"Z. Chan %s cont/ext/prio = %s/%s/%d\n", chan->name, chan->context, chan->exten, chan->priority);
+			ast_log(LOG_NOTICE,"Z. Peer %s cont/ext/prio = %s/%s/%d\n", peer->name, peer->context, peer->exten, peer->priority);
 			ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
 		}
 		/*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
 	} else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
+		ast_log(LOG_NOTICE,"ZZ. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
+		ast_log(LOG_NOTICE,"ZZ. Peer cont/ext/prio = %s/%s/%d\n", peer->context, peer->exten, peer->priority);
 		pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", transferee->name);
 		pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", peer->name);
 		res=finishup(transferee);
@@ -823,13 +858,19 @@
 			if (option_verbose > 2) 
 				ast_verbose(VERBOSE_PREFIX_3 "Transferring %s to '%s' (context %s) priority 1\n"
 								,transferee->name, xferto, transferer_real_context);
+			ast_log(LOG_NOTICE,"ZZZ. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
+			ast_log(LOG_NOTICE,"ZZZ. Peer cont/ext/prio = %s/%s/%d\n", peer->context, peer->exten, peer->priority);
 			if (ast_async_goto(transferee, transferer_real_context, xferto, 1))
 				ast_log(LOG_WARNING, "Async goto failed :-(\n");
 		} else {
 			/* Set the channel's new extension, since it exists, using transferer context */
 			set_c_e_p(transferee, transferer_real_context, xferto, 0);
+			ast_log(LOG_NOTICE,"ZZZZ. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
+			ast_log(LOG_NOTICE,"ZZZZ. Peer cont/ext/prio = %s/%s/%d\n", peer->context, peer->exten, peer->priority);
 		}
 		check_goto_on_transfer(transferer);
+		ast_log(LOG_NOTICE,"ZZZZZ. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
+		ast_log(LOG_NOTICE,"ZZZZZ. Peer cont/ext/prio = %s/%s/%d\n", peer->context, peer->exten, peer->priority);
 		return res;
 	} else {
 		ast_verb(3, "Unable to find extension '%s' in context '%s'\n", xferto, transferer_real_context);
@@ -844,6 +885,8 @@
 		ast_verb(2, "Hungup during autoservice stop on '%s'\n", transferee->name);
 		return res;
 	}
+	ast_log(LOG_NOTICE,"ZZZZZZ. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
+	ast_log(LOG_NOTICE,"ZZZZZZ. Peer cont/ext/prio = %s/%s/%d\n", peer->context, peer->exten, peer->priority);
 	return FEATURE_RETURN_SUCCESS;
 }
 
@@ -2240,6 +2283,7 @@
 	if (!res)
 		res = ast_safe_sleep(chan, 1000);
 	/* Park the call */
+	ast_log(LOG_NOTICE,"PCE. Chan cont/ext/prio = %s/%s/%d\n", chan->context, chan->exten, chan->priority);
 	if (!res)
 		res = ast_park_call(chan, chan, 0, NULL);
 




More information about the svn-commits mailing list