diff --git a/loader.c b/loader.c
index 5280d5a50e7de132acd911b19bad5346b211b0c7..5ac59a02d07dd5b99aef8d7a3d99e4488a7a3f71 100755
--- a/loader.c
+++ b/loader.c
@@ -103,6 +103,7 @@ AST_MUTEX_DEFINE_STATIC(modlock);
 AST_MUTEX_DEFINE_STATIC(reloadlock);
 
 static struct module *module_list=NULL;
+static int modlistver = 0;
 
 int ast_unload_resource(char *resource_name, int force)
 {
@@ -142,6 +143,7 @@ int ast_unload_resource(char *resource_name, int force)
 		ml = m;
 		m = m->next;
 	}
+	modlistver = rand();
 	ast_mutex_unlock(&modlock);
 	ast_update_use_count();
 	return res;
@@ -190,6 +192,8 @@ int ast_module_reload(const char *name)
 {
 	struct module *m;
 	int reloaded = 0;
+	int oldversion;
+	int (*reload)(void);
 	/* We'll do the logger and manager the favor of calling its reload here first */
 
 	if (ast_mutex_trylock(&reloadlock)) {
@@ -215,17 +219,23 @@ int ast_module_reload(const char *name)
 	time(&ast_lastreloadtime);
 
 	ast_mutex_lock(&modlock);
+	oldversion = modlistver;
 	m = module_list;
 	while(m) {
 		if (!name || !strcasecmp(name, m->resource)) {
 			if (reloaded < 1)
 				reloaded = 1;
-			if (m->reload) {
+			reload = m->reload;
+			ast_mutex_unlock(&modlock);
+			if (reload) {
 				reloaded = 2;
 				if (option_verbose > 2) 
 					ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description());
-				m->reload();
+				reload();
 			}
+			ast_mutex_lock(&modlock);
+			if (oldversion != modlistver)
+				break;
 		}
 		m = m->next;
 	}
@@ -380,6 +390,7 @@ int ast_load_resource(char *resource_name)
 		i->next = m;
 	}
 	
+	modlistver = rand();
 	ast_mutex_unlock(&modlock);
 	if ((res = m->load_module())) {
 		ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);