mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	core_unreal.c: Fix memory leak in ast_unreal_new_channels()
When the channel tech is multistream capable, the reference to chan_topology was passed to the new channel. When the channel tech isn't multistream capable, the reference to chan_topology was never released. "Local" channels are multistream capable so it didn't affect them but the confbridge "CBAnn" and the bridge_media "Recorder" channels are not so they caused a leak every time one of them was created. Also added tracing to ast_stream_topology_alloc() and stream_topology_destroy() to assist with debugging. Resolves: #938
This commit is contained in:
		
				
					committed by
					
						![asterisk-org-access-app[bot]](/avatar/58a64b62d62d5b23df7bc832f016f9db?size=40) asterisk-org-access-app[bot]
						asterisk-org-access-app[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							97770a947c
						
					
				
				
					commit
					35d6da06a6
				
			| @@ -1169,7 +1169,7 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p, | ||||
| 	struct ast_assigned_ids id2 = {NULL, NULL}; | ||||
| 	int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1); | ||||
| 	int i; | ||||
| 	struct ast_stream_topology *chan_topology; | ||||
| 	RAII_VAR(struct ast_stream_topology *, chan_topology, NULL, ast_stream_topology_free); | ||||
| 	struct ast_stream *stream; | ||||
|  | ||||
| 	/* set unique ids for the two channels */ | ||||
| @@ -1221,7 +1221,6 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p, | ||||
| 		"%s/%s-%08x;1", tech->type, p->name, (unsigned)generated_seqno); | ||||
| 	if (!owner) { | ||||
| 		ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n"); | ||||
| 		ast_stream_topology_free(chan_topology); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| @@ -1295,7 +1294,7 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p, | ||||
| 	ast_channel_nativeformats_set(chan, p->reqcap); | ||||
|  | ||||
| 	if (ast_channel_is_multistream(chan)) { | ||||
| 		ast_channel_set_stream_topology(chan, chan_topology); | ||||
| 		ast_channel_set_stream_topology(chan, ao2_bump(chan_topology)); | ||||
| 	} | ||||
|  | ||||
| 	/* Format was already determined when setting up owner */ | ||||
|   | ||||
| @@ -641,27 +641,30 @@ struct ast_stream *ast_stream_create_resolved(struct ast_stream *pending_stream, | ||||
| static void stream_topology_destroy(void *data) | ||||
| { | ||||
| 	struct ast_stream_topology *topology = data; | ||||
| 	SCOPE_ENTER(4, "Topology: %p: %s\n", topology, ast_str_tmp(128, ast_stream_topology_to_str(topology, &STR_TMP))); | ||||
|  | ||||
| 	AST_VECTOR_CALLBACK_VOID(&topology->streams, ast_stream_free); | ||||
| 	AST_VECTOR_FREE(&topology->streams); | ||||
| 	SCOPE_EXIT_RTN("Destroyed: %p\n", topology); | ||||
| } | ||||
|  | ||||
| #define TOPOLOGY_INITIAL_STREAM_COUNT 2 | ||||
| struct ast_stream_topology *ast_stream_topology_alloc(void) | ||||
| { | ||||
| 	struct ast_stream_topology *topology; | ||||
| 	SCOPE_ENTER(4, "Topology Create\n"); | ||||
|  | ||||
| 	topology = ao2_alloc_options(sizeof(*topology), stream_topology_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK); | ||||
| 	if (!topology) { | ||||
| 		return NULL; | ||||
| 		SCOPE_EXIT_RTN_VALUE(NULL, "Allocation failed\n"); | ||||
| 	} | ||||
|  | ||||
| 	if (AST_VECTOR_INIT(&topology->streams, TOPOLOGY_INITIAL_STREAM_COUNT)) { | ||||
| 		ao2_ref(topology, -1); | ||||
| 		topology = NULL; | ||||
| 		SCOPE_EXIT_RTN_VALUE(NULL, "Vector init failed\n"); | ||||
| 	} | ||||
|  | ||||
| 	return topology; | ||||
| 	SCOPE_EXIT_RTN_VALUE(topology, "Created: %p\n", topology); | ||||
| } | ||||
|  | ||||
| struct ast_stream_topology *ast_stream_topology_clone( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user