Index: funcs/func_cdr.c
===================================================================
--- funcs/func_cdr.c (revision 228188)
+++ funcs/func_cdr.c (working copy)
@@ -100,7 +100,7 @@
Channel name.
- CDR sequence number.
+ CDR sequence number.
Index: main/loader.c
===================================================================
--- main/loader.c (revision 228188)
+++ main/loader.c (working copy)
@@ -443,26 +443,39 @@
void ast_module_shutdown(void)
{
struct ast_module *mod;
- AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module);
+ int somethingchanged = 1, final = 0;
- /* We have to call the unload() callbacks in reverse order that the modules
- * exist in the module list so it is the reverse order of how they were
- * loaded. */
+ AST_LIST_LOCK(&module_list);
- AST_LIST_LOCK(&module_list);
- while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry)))
- AST_LIST_INSERT_HEAD(&local_module_list, mod, entry);
+ /*!\note Some resources, like timers, are started up dynamically, and thus
+ * may be still in use, even if all channels are dead. We must therefore
+ * check the usecount before asking modules to unload. */
+ do {
+ if (!somethingchanged) {
+ /*!\note If we go through the entire list without changing
+ * anything, ignore the usecounts and unload, then exit. */
+ final = 1;
+ }
+
+ /* Reset flag before traversing the list */
+ somethingchanged = 0;
+
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
+ if (!final && mod->usecount) {
+ continue;
+ }
+ AST_LIST_REMOVE_CURRENT(entry);
+ if (mod->info->unload) {
+ mod->info->unload();
+ }
+ AST_LIST_HEAD_DESTROY(&mod->users);
+ free(mod);
+ somethingchanged = 1;
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ } while (somethingchanged && !final);
+
AST_LIST_UNLOCK(&module_list);
-
- while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) {
- if (mod->info->unload)
- mod->info->unload();
- /* Since this should only be called when shutting down "gracefully",
- * all channels should be down before we get to this point, meaning
- * there will be no module users left. */
- AST_LIST_HEAD_DESTROY(&mod->users);
- free(mod);
- }
}
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
Index: main/event.c
===================================================================
--- main/event.c (revision 228188)
+++ main/event.c (working copy)
@@ -999,6 +999,11 @@
struct ast_event_iterator iterator;
int res = 0;
+ /* Event has no IEs allocated */
+ if (event->event_len < sizeof(*event) + sizeof(ie_type)) {
+ return NULL;
+ }
+
for (ast_event_iterator_init(&iterator, event); !res; res = ast_event_iterator_next(&iterator)) {
if (ast_event_iterator_get_ie_type(&iterator) == ie_type) {
return ast_event_iterator_get_ie_raw(&iterator);
Index: res/res_pktccops.c
===================================================================
--- res/res_pktccops.c (revision 228188)
+++ res/res_pktccops.c (working copy)
@@ -1446,7 +1446,7 @@
static int unload_module(void)
{
if (!ast_mutex_lock(&pktccops_lock)) {
- if (pktccops_thread && (pktccops_thread != AST_PTHREADT_STOP)) {
+ if ((pktccops_thread != AST_PTHREADT_NULL) && (pktccops_thread != AST_PTHREADT_STOP)) {
pthread_cancel(pktccops_thread);
pthread_kill(pktccops_thread, SIGURG);
pthread_join(pktccops_thread, NULL);