mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	store feature_pvt list using linked list macros
(issue #6351, with additional changes to prevent a memory leak in unload_module) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@8665 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -71,9 +71,6 @@ AST_MUTEX_DEFINE_STATIC(usecnt_lock); | ||||
|  | ||||
| #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,15 +79,17 @@ struct feature_sub { | ||||
| 	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 */ | ||||
| @@ -366,7 +365,6 @@ static int features_call(struct ast_channel *ast, char *dest, int timeout) | ||||
| 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 @@ static int features_hangup(struct ast_channel *ast) | ||||
| 	} | ||||
| 	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 @@ static struct feature_pvt *features_alloc(char *data, int format) | ||||
| 			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 @@ static struct feature_pvt *features_alloc(char *data, int format) | ||||
| 			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 @@ static int features_show(int fd, int argc, char **argv) | ||||
|  | ||||
| 	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 : "<unowned>", 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; | ||||
| } | ||||
|  | ||||
| @@ -571,23 +556,23 @@ int reload() | ||||
| int unload_module() | ||||
| { | ||||
| 	struct feature_pvt *p; | ||||
| 	 | ||||
| 	/* First, take us out of the channel loop */ | ||||
| 	ast_cli_unregister(&cli_show_features); | ||||
| 	ast_channel_unregister(&features_tech); | ||||
| 	if (!ast_mutex_lock(&featurelock)) { | ||||
| 		/* Hangup all interfaces if they have an owner */ | ||||
| 		p = features; | ||||
| 		while(p) { | ||||
| 			if (p->owner) | ||||
| 				ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); | ||||
| 			p = p->next; | ||||
| 		} | ||||
| 		features = NULL; | ||||
| 		ast_mutex_unlock(&featurelock); | ||||
| 	} else { | ||||
| 		ast_log(LOG_WARNING, "Unable to lock the monitor\n"); | ||||
| 	 | ||||
| 	if (!AST_LIST_LOCK(&features)) | ||||
| 		return -1; | ||||
| 	}		 | ||||
| 	/* Hangup all interfaces if they have an owner */ | ||||
| 	AST_LIST_TRAVERSE_SAFE_BEGIN(&features, p, list) { | ||||
| 		if (p->owner) | ||||
| 			ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); | ||||
| 		AST_LIST_REMOVE_CURRENT(&features, list); | ||||
| 		free(p); | ||||
| 	} | ||||
| 	AST_LIST_TRAVERSE_SAFE_END | ||||
| 	AST_LIST_UNLOCK(&features); | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user