mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Fixed Confbridge file recording deadlock and appending.
A deadlock occurred after starting/stopping and then restarting a confbridge recording. Upon starting a recording a record thread is created that holds a lock until just before exiting. Stopping the recording does not stop/exit the thread or release the lock. The thread waits until recording begins again. Starting a stopped recording signals the thread to continue and start recording again. However restarting the recording also created another record thread resulting in a deadlock. The fix was to make sure the record thread was only created once. Also it was noted that filenames for the recordings were being concatenated for each start/stop. This was fixed by creating a new file for each conference session and appending the actual recorded data within the file (e.g. passing the 'a' option to MixMonitor). (issue AST-1088) Reported by: John Bigelow Review: http://reviewboard.digium.internal/r/374/ ........ Merged revisions 381702 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@381703 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -596,6 +596,34 @@ static struct ast_channel *rec_request(const char *type, struct ast_format_cap * | ||||
| 	return tmp; | ||||
| } | ||||
|  | ||||
| static void set_rec_filename(struct conference_bridge *bridge, struct ast_str **filename) | ||||
| { | ||||
| 	char *rec_file = bridge->b_profile.rec_file; | ||||
| 	time_t now; | ||||
| 	char *ext; | ||||
|  | ||||
| 	if (ast_str_strlen(*filename)) { | ||||
| 		    return; | ||||
| 	} | ||||
|  | ||||
| 	time(&now); | ||||
|  | ||||
| 	ast_str_reset(*filename); | ||||
| 	if (ast_strlen_zero(rec_file)) { | ||||
| 		ast_str_set(filename, 0, "confbridge-%s-%u.wav", bridge->name, (unsigned int)now); | ||||
| 	} else { | ||||
| 		/* insert time before file extension */ | ||||
| 		ext = strrchr(rec_file, '.'); | ||||
| 		if (ext) { | ||||
| 			ast_str_set_substr(filename, 0, rec_file, ext - rec_file); | ||||
| 			ast_str_append(filename, 0, "-%u%s", (unsigned int)now, ext); | ||||
| 		} else { | ||||
| 			ast_str_set(filename, 0, "%s-%u", rec_file, (unsigned int)now); | ||||
| 		} | ||||
| 	} | ||||
| 	ast_str_append(filename, 0, ",a"); | ||||
| } | ||||
|  | ||||
| static void *record_thread(void *obj) | ||||
| { | ||||
| 	struct conference_bridge *conference_bridge = obj; | ||||
| @@ -614,16 +642,7 @@ static void *record_thread(void *obj) | ||||
|  | ||||
| 	/* XXX If we get an EXIT right here, START will essentially be a no-op */ | ||||
| 	while (conference_bridge->record_state != CONF_RECORD_EXIT) { | ||||
| 		if (!(ast_strlen_zero(conference_bridge->b_profile.rec_file))) { | ||||
| 			ast_str_append(&filename, 0, "%s", conference_bridge->b_profile.rec_file); | ||||
| 		} else { | ||||
| 			time_t now; | ||||
| 			time(&now); | ||||
| 			ast_str_append(&filename, 0, "confbridge-%s-%u.wav", | ||||
| 				conference_bridge->name, | ||||
| 				(unsigned int) now); | ||||
| 		} | ||||
|  | ||||
| 		set_rec_filename(conference_bridge, &filename); | ||||
| 		chan = ast_channel_ref(conference_bridge->record_chan); | ||||
| 		ast_answer(chan); | ||||
| 		pbx_exec(chan, mixmonapp, ast_str_buffer(filename)); | ||||
| @@ -757,6 +776,13 @@ static int start_conf_record_thread(struct conference_bridge *conference_bridge) | ||||
|  | ||||
| 	conf_start_record(conference_bridge); | ||||
|  | ||||
| 	/* | ||||
| 	 * if the thread has already been started, don't start another | ||||
| 	 */ | ||||
| 	if (conference_bridge->record_thread != AST_PTHREADT_NULL) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_pthread_create_background(&conference_bridge->record_thread, NULL, record_thread, conference_bridge)) { | ||||
| 		ast_log(LOG_WARNING, "Failed to create recording channel for conference %s\n", conference_bridge->name); | ||||
| 		ao2_ref(conference_bridge, -1); /* error so remove ref */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user