mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Cleanup ast_run_atexits() atexits list.
* Convert atexits list to a mutex instead of a rd/wr lock. The lock is only write locked. * Move CLI verbose Asterisk ending message to where AMI message is output in really_quit() to avoid further surprises about using stuff already shutdown. (issue ASTERISK-20649) Reported by: Corey Farrell ........ Merged revisions 377165 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 377166 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 377167 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@377168 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -308,10 +308,10 @@ struct console { | ||||
|  | ||||
| struct ast_atexit { | ||||
| 	void (*func)(void); | ||||
| 	AST_RWLIST_ENTRY(ast_atexit) list; | ||||
| 	AST_LIST_ENTRY(ast_atexit) list; | ||||
| }; | ||||
|  | ||||
| static AST_RWLIST_HEAD_STATIC(atexits, ast_atexit); | ||||
| static AST_LIST_HEAD_STATIC(atexits, ast_atexit); | ||||
|  | ||||
| struct timeval ast_startuptime; | ||||
| struct timeval ast_lastreloadtime; | ||||
| @@ -1047,39 +1047,57 @@ static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct | ||||
|  | ||||
| #endif /* ! LOW_MEMORY */ | ||||
|  | ||||
| static void ast_run_atexits(void) | ||||
| { | ||||
| 	struct ast_atexit *ae; | ||||
|  | ||||
| 	AST_LIST_LOCK(&atexits); | ||||
| 	while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) { | ||||
| 		if (ae->func) { | ||||
| 			ae->func(); | ||||
| 		} | ||||
| 		ast_free(ae); | ||||
| 	} | ||||
| 	AST_LIST_UNLOCK(&atexits); | ||||
| } | ||||
|  | ||||
| static void __ast_unregister_atexit(void (*func)(void)) | ||||
| { | ||||
| 	struct ast_atexit *ae; | ||||
|  | ||||
| 	AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) { | ||||
| 		if (ae->func == func) { | ||||
| 			AST_LIST_REMOVE_CURRENT(list); | ||||
| 			ast_free(ae); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_LIST_TRAVERSE_SAFE_END; | ||||
| } | ||||
|  | ||||
| int ast_register_atexit(void (*func)(void)) | ||||
| { | ||||
| 	struct ast_atexit *ae; | ||||
|  | ||||
| 	if (!(ae = ast_calloc(1, sizeof(*ae)))) | ||||
| 	ae = ast_calloc(1, sizeof(*ae)); | ||||
| 	if (!ae) { | ||||
| 		return -1; | ||||
|  | ||||
| 	} | ||||
| 	ae->func = func; | ||||
|  | ||||
| 	ast_unregister_atexit(func); | ||||
|  | ||||
| 	AST_RWLIST_WRLOCK(&atexits); | ||||
| 	AST_RWLIST_INSERT_HEAD(&atexits, ae, list); | ||||
| 	AST_RWLIST_UNLOCK(&atexits); | ||||
| 	AST_LIST_LOCK(&atexits); | ||||
| 	__ast_unregister_atexit(func); | ||||
| 	AST_LIST_INSERT_HEAD(&atexits, ae, list); | ||||
| 	AST_LIST_UNLOCK(&atexits); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void ast_unregister_atexit(void (*func)(void)) | ||||
| { | ||||
| 	struct ast_atexit *ae = NULL; | ||||
|  | ||||
| 	AST_RWLIST_WRLOCK(&atexits); | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) { | ||||
| 		if (ae->func == func) { | ||||
| 			AST_RWLIST_REMOVE_CURRENT(list); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	AST_RWLIST_TRAVERSE_SAFE_END; | ||||
| 	AST_RWLIST_UNLOCK(&atexits); | ||||
|  | ||||
| 	free(ae); | ||||
| 	AST_LIST_LOCK(&atexits); | ||||
| 	__ast_unregister_atexit(func); | ||||
| 	AST_LIST_UNLOCK(&atexits); | ||||
| } | ||||
|  | ||||
| /* Sending commands from consoles back to the daemon requires a terminating NULL */ | ||||
| @@ -1751,17 +1769,6 @@ int ast_set_priority(int pri) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void ast_run_atexits(void) | ||||
| { | ||||
| 	struct ast_atexit *ae; | ||||
| 	AST_RWLIST_RDLOCK(&atexits); | ||||
| 	AST_RWLIST_TRAVERSE(&atexits, ae, list) { | ||||
| 		if (ae->func) | ||||
| 			ae->func(); | ||||
| 	} | ||||
| 	AST_RWLIST_UNLOCK(&atexits); | ||||
| } | ||||
|  | ||||
| static int can_safely_quit(shutdown_nice_t niceness, int restart); | ||||
| static void really_quit(int num, shutdown_nice_t niceness, int restart); | ||||
|  | ||||
| @@ -1845,6 +1852,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /*! Called when exiting is certain. */ | ||||
| static void really_quit(int num, shutdown_nice_t niceness, int restart) | ||||
| { | ||||
| 	int active_channels; | ||||
| @@ -1903,11 +1911,12 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart) | ||||
| 		"Restart: %s\r\n", | ||||
| 		active_channels ? "Uncleanly" : "Cleanly", | ||||
| 		restart ? "True" : "False"); | ||||
| 	ast_verb(0, "Asterisk %s ending (%d).\n", | ||||
| 		active_channels ? "uncleanly" : "cleanly", num); | ||||
|  | ||||
| 	ast_verb(0, "Executing last minute cleanups\n"); | ||||
| 	ast_run_atexits(); | ||||
| 	/* Called on exit */ | ||||
| 	ast_verb(0, "Asterisk %s ending (%d).\n", active_channels ? "uncleanly" : "cleanly", num); | ||||
|  | ||||
| 	ast_debug(1, "Asterisk ending (%d).\n", num); | ||||
| 	if (ast_socket > -1) { | ||||
| 		pthread_cancel(lthread); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user