diff --git a/main/hashtab.c b/main/hashtab.c index 0be0d21cdc93ff0d47d7571412349f79b36db149..c69eb969adfdf5eac3698b459d6d067fbddf84ce 100644 --- a/main/hashtab.c +++ b/main/hashtab.c @@ -383,66 +383,27 @@ void ast_hashtab_destroy( struct ast_hashtab *tab, void (*objdestroyfunc)(void * 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; + int res=0; - if (!tab) - return 0; - - if (!obj) - return 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 @@ static void *ast_hashtab_remove_object_internal(struct ast_hashtab *tab, struct 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 @@ void *ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj) 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 @@ void *ast_hashtab_remove_object_via_lookup_nolock(struct ast_hashtab *tab, void 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 */ } } @@ -820,8 +765,7 @@ 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 */ - unsigned int h; - struct ast_hashtab_bucket *b; + const void *obj2; if (!tab || !obj) return 0; @@ -829,23 +773,12 @@ void *ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj) 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 */ - } - } + obj2 = ast_hashtab_remove_this_object_nolock(tab,obj); if (tab->do_locking) ast_rwlock_unlock(&tab->lock); - return 0; + return (void *)obj2; } void *ast_hashtab_remove_this_object_nolock(struct ast_hashtab *tab, void *obj) @@ -861,14 +794,11 @@ void *ast_hashtab_remove_this_object_nolock(struct ast_hashtab *tab, void *obj) 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 */ } } diff --git a/res/res_features.c b/res/res_features.c index 14550b80f3fe407f364f9f16c3ae4c809be9b9db..0403cd5b0588eabea0eb65db69e4e88a2580986f 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -390,6 +390,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou 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 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou 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 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou 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 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou !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 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou 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 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou 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 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int 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 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int 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 @@ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, 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 @@ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, 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 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p 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 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p 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 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p 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 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p 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 @@ static int park_call_exec(struct ast_channel *chan, void *data) 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);