Index: channels/chan_features.c =================================================================== --- channels/chan_features.c (revision 8645) +++ channels/chan_features.c (working copy) @@ -71,9 +71,6 @@ #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0) -/* Protect the interface list (of feature_pvt's) */ -AST_MUTEX_DEFINE_STATIC(featurelock); - struct feature_sub { struct ast_channel *owner; int inthreeway; @@ -82,16 +79,18 @@ int alertpipebackup[2]; }; -static struct feature_pvt { +struct feature_pvt { ast_mutex_t lock; /* Channel private lock */ char tech[AST_MAX_EXTENSION]; /* Technology to abstract */ char dest[AST_MAX_EXTENSION]; /* Destination to abstract */ struct ast_channel *subchan; struct feature_sub subs[3]; /* Subs */ struct ast_channel *owner; /* Current Master Channel */ - struct feature_pvt *next; /* Next entity */ -} *features = NULL; + AST_LIST_ENTRY(feature_pvt) list; /* Next entity */ +}; +static AST_LIST_HEAD_STATIC(features, feature_pvt); + #define SUB_REAL 0 /* Active call */ #define SUB_CALLWAIT 1 /* Call-Waiting call on hold */ #define SUB_THREEWAY 2 /* Three-way call */ @@ -366,7 +365,6 @@ static int features_hangup(struct ast_channel *ast) { struct feature_pvt *p = ast->tech_pvt; - struct feature_pvt *cur, *prev=NULL; int x; ast_mutex_lock(&p->lock); @@ -378,24 +376,12 @@ } ast->tech_pvt = NULL; - if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { ast_mutex_unlock(&p->lock); /* Remove from list */ - ast_mutex_lock(&featurelock); - cur = features; - while(cur) { - if (cur == p) { - if (prev) - prev->next = cur->next; - else - features = cur->next; - break; - } - prev = cur; - cur = cur->next; - } - ast_mutex_unlock(&featurelock); + AST_LIST_LOCK(&features); + AST_LIST_REMOVE(&features, p, list); + AST_LIST_UNLOCK(&features); ast_mutex_lock(&p->lock); /* And destroy */ if (p->subchan) @@ -431,14 +417,12 @@ data); return NULL; } - ast_mutex_lock(&featurelock); - tmp = features; - while(tmp) { + AST_LIST_LOCK(&features); + AST_LIST_TRAVERSE(&features, tmp, list) { if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest)) break; - tmp = tmp->next; } - ast_mutex_unlock(&featurelock); + AST_LIST_UNLOCK(&features); if (!tmp) { chan = ast_request(tech, format, dest, &status); if (!chan) { @@ -454,10 +438,9 @@ strncpy(tmp->tech, tech, sizeof(tmp->tech) - 1); strncpy(tmp->dest, dest, sizeof(tmp->dest) - 1); tmp->subchan = chan; - ast_mutex_lock(&featurelock); - tmp->next = features; - features = tmp; - ast_mutex_unlock(&featurelock); + AST_LIST_LOCK(&features); + AST_LIST_INSERT_HEAD(&features, tmp, list); + AST_LIST_UNLOCK(&features); } } return tmp; @@ -530,17 +513,19 @@ if (argc != 3) return RESULT_SHOWUSAGE; - ast_mutex_lock(&featurelock); - p = features; - while(p) { + + if (AST_LIST_EMPTY(&features)) { + ast_cli(fd, "No feature channels in use\n"); + return RESULT_SUCCESS; + } + + AST_LIST_LOCK(&features); + AST_LIST_TRAVERSE(&features, p, list) { ast_mutex_lock(&p->lock); ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "", p->tech, p->dest); ast_mutex_unlock(&p->lock); - p = p->next; } - if (!features) - ast_cli(fd, "No feature channels in use\n"); - ast_mutex_unlock(&featurelock); + AST_LIST_UNLOCK(&features); return RESULT_SUCCESS; } @@ -574,16 +559,14 @@ /* First, take us out of the channel loop */ ast_cli_unregister(&cli_show_features); ast_channel_unregister(&features_tech); - if (!ast_mutex_lock(&featurelock)) { + if (!AST_LIST_LOCK(&features)) { /* Hangup all interfaces if they have an owner */ - p = features; - while(p) { + AST_LIST_TRAVERSE(&features, p, list) { if (p->owner) ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); - p = p->next; } - features = NULL; - ast_mutex_unlock(&featurelock); + AST_LIST_UNLOCK(&features); + AST_LIST_HEAD_INIT(&features); } else { ast_log(LOG_WARNING, "Unable to lock the monitor\n"); return -1;