1032
1032
const char *msg = prev ? "deadlock" : "initial deadlock";
1034
1034
struct ast_channel *c;
1035
const struct ast_channel *_prev = prev;
1036
1037
for (retries = 0; retries < 10; retries++) {
1038
1039
AST_LIST_LOCK(&channels);
1039
1040
AST_LIST_TRAVERSE(&channels, c, chan_list) {
1040
1042
if (prev) { /* look for next item */
1041
1043
if (c != prev) /* not this one */
1050
1052
/* We want prev to be NULL in case we end up doing more searching through
1051
1053
* the channel list to find the channel (ie: name searching). If we didn't
1052
1054
* set this to NULL the logic would just blow up
1055
* XXX Need a better explanation for this ...
1055
1058
if (name) { /* want match by name */
1093
1096
AST_LIST_UNLOCK(&channels);
1099
/* If we reach this point we basically tried to lock a channel and failed. Instead of
1100
* starting from the beginning of the list we can restore our saved pointer to the previous
1101
* channel and start from there.
1096
1104
usleep(1); /* give other threads a chance before retrying */
2340
2348
* However, only let emulation be forced if the other end cares about BEGIN frames */
2341
2349
if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
2342
2350
(ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
2343
if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
2351
if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
2352
ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
2344
2353
chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
2346
2355
ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
2348
2357
f = &ast_null_frame;
2350
2359
if (!ast_tvzero(chan->dtmf_tv) &&
2351
2360
ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
2352
2361
/* If it hasn't been long enough, defer this digit */
2353
if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
2362
if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
2363
ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
2354
2364
chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
2356
2366
ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
2358
2368
f = &ast_null_frame;
2369
2379
chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
2371
2381
chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
2372
ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %d queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
2382
ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
2375
2385
struct timeval now = ast_tvnow();
2376
ast_clear_flag(chan, AST_FLAG_IN_DTMF);
2378
f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
2386
if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
2387
ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
2388
ast_clear_flag(chan, AST_FLAG_IN_DTMF);
2390
f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
2391
} else if (!f->len) {
2392
ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
2393
f->len = AST_MIN_DTMF_DURATION;
2379
2395
if (f->len < AST_MIN_DTMF_DURATION) {
2396
ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
2380
2397
ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
2381
2398
chan->emulate_dtmf_digit = f->subclass;
2382
2399
chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
2383
2400
f = &ast_null_frame;
2402
ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
2385
2403
chan->dtmf_tv = now;
2388
2407
case AST_FRAME_DTMF_BEGIN:
2392
2411
ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
2394
2413
f = &ast_null_frame;
2414
ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
2396
2416
ast_set_flag(chan, AST_FLAG_IN_DTMF);
2397
2417
chan->dtmf_tv = ast_tvnow();
2418
ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
2400
2421
case AST_FRAME_NULL: