~davewalker/ubuntu/maverick/asterisk/lp_705014

« back to all changes in this revision

Viewing changes to main/channel.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2007-08-09 22:47:00 UTC
  • mto: (1.2.1 upstream) (8.2.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 32.
  • Revision ID: james.westby@ubuntu.com-20070809224700-ilafdtbyau4lw1gz
Tags: upstream-1.4.10~dfsg
ImportĀ upstreamĀ versionĀ 1.4.10~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
#include "asterisk.h"
27
27
 
28
 
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 76132 $")
 
28
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 78275 $")
29
29
 
30
30
#include <stdio.h>
31
31
#include <stdlib.h>
1032
1032
        const char *msg = prev ? "deadlock" : "initial deadlock";
1033
1033
        int retries;
1034
1034
        struct ast_channel *c;
 
1035
        const struct ast_channel *_prev = prev;
1035
1036
 
1036
1037
        for (retries = 0; retries < 10; retries++) {
1037
1038
                int done;
1038
1039
                AST_LIST_LOCK(&channels);
1039
1040
                AST_LIST_TRAVERSE(&channels, c, chan_list) {
 
1041
                        prev = _prev;
1040
1042
                        if (prev) {     /* look for next item */
1041
1043
                                if (c != prev)  /* not this one */
1042
1044
                                        continue;
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 ...
1053
1056
                                 */
1054
1057
                        }
1055
1058
                        if (name) { /* want match by name */
1093
1096
                AST_LIST_UNLOCK(&channels);
1094
1097
                if (done)
1095
1098
                        return c;
 
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.
 
1102
                 */
 
1103
                prev = _prev;
1096
1104
                usleep(1);      /* give other threads a chance before retrying */
1097
1105
        }
1098
1106
 
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;
2345
 
                                else
 
2354
                                } else
2346
2355
                                        ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
2347
2356
                                ast_frfree(f);
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;
2355
 
                                        else
 
2365
                                        } else
2356
2366
                                                ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
2357
2367
                                        ast_frfree(f);
2358
2368
                                        f = &ast_null_frame;
2369
2379
                                                        chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
2370
2380
                                        } else
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);
2373
2383
                                }
2374
2384
                        } else {
2375
2385
                                struct timeval now = ast_tvnow();
2376
 
                                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
2377
 
                                if (!f->len)
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);
 
2389
                                        if (!f->len)
 
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;
 
2394
                                }
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;
2384
 
                                } else
 
2401
                                } else {
 
2402
                                        ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
2385
2403
                                        chan->dtmf_tv = now;
 
2404
                                }
2386
2405
                        }
2387
2406
                        break;
2388
2407
                case AST_FRAME_DTMF_BEGIN:
2392
2411
                              ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
2393
2412
                                ast_frfree(f);
2394
2413
                                f = &ast_null_frame;
 
2414
                                ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
2395
2415
                        } else {
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);
2398
2419
                        }
2399
2420
                        break;
2400
2421
                case AST_FRAME_NULL: