[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