diff --git a/apps/app_while.c b/apps/app_while.c
index 8595916f30ff101df24c2fa082e8fa77f4d9a1f8..ddc581ed96c08dcfada11146f6ef7ff30e106d1c 100644
--- a/apps/app_while.c
+++ b/apps/app_while.c
@@ -125,7 +125,7 @@ static int find_matching_endwhile(struct ast_channel *chan)
 	struct ast_context *c;
 	int res=-1;
 
-	if (ast_lock_contexts()) {
+	if (ast_rdlock_contexts()) {
 		ast_log(LOG_ERROR, "Failed to lock contexts list\n");
 		return -1;
 	}
@@ -133,7 +133,7 @@ static int find_matching_endwhile(struct ast_channel *chan)
 	for (c=ast_walk_contexts(NULL); c; c=ast_walk_contexts(c)) {
 		struct ast_exten *e;
 
-		if (!ast_lock_context(c)) {
+		if (!ast_rdlock_context(c)) {
 			if (!strcmp(ast_get_context_name(c), chan->context)) {
 				/* This is the matching context we want */
 				int cur_priority = chan->priority + 1, level=1;
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index 56d50eb56f9655fd162e257a119429526fd8529a..2759b36d15ed94de76557d1d865ff583cffdfbee 100644
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -669,12 +669,20 @@ int ast_ignore_pattern(const char *context, const char *pattern);
 /* Locking functions for outer modules, especially for completion functions */
 
 /*! 
- * \brief Locks the context list
+ * \brief Write locks the context list
  *
  * \retval 0 on success 
  * \retval -1 on error
  */
-int ast_lock_contexts(void);
+int ast_wrlock_contexts(void);
+
+/*!
+ * \brief Read locks the context list
+ *
+ * \retval 0 on success
+ * \retval -1 on error
+ */
+int ast_rdlock_contexts(void);
 
 /*! 
  * \brief Unlocks contexts
@@ -685,14 +693,24 @@ int ast_lock_contexts(void);
 int ast_unlock_contexts(void);
 
 /*! 
- * \brief Locks a given context
+ * \brief Write locks a given context
  * 
  * \param con context to lock
  *
  * \retval 0 on success 
  * \retval -1 on failure
  */
-int ast_lock_context(struct ast_context *con);
+int ast_wrlock_context(struct ast_context *con);
+
+/*!
+ * \brief Read locks a given context
+ *
+ * \param con context to lock
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_rdlock_context(struct ast_context *con);
 
 /*! 
  * \retval Unlocks the given context
diff --git a/main/pbx.c b/main/pbx.c
index 2f5ad24d37fbd380b1fd135db5f78dd20c6127ca..f1296673022d3b2a013669fc4d3575f0f5f9e391 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -160,7 +160,7 @@ struct ast_ignorepat {
 
 /*! \brief ast_context: An extension context */
 struct ast_context {
-	ast_mutex_t lock; 			/*!< A lock to prevent multiple threads from clobbering the context */
+	ast_rwlock_t lock; 			/*!< A lock to prevent multiple threads from clobbering the context */
 	struct ast_exten *root;			/*!< The root of the list of extensions */
 	struct ast_context *next;		/*!< Link them together */
 	struct ast_include *includes;		/*!< Include other contexts */
@@ -473,7 +473,7 @@ static struct pbx_builtin {
 };
 
 static struct ast_context *contexts;
-AST_MUTEX_DEFINE_STATIC(conlock); 		/*!< Lock for the ast_context list */
+AST_RWLOCK_DEFINE_STATIC(conlock); 		/*!< Lock for the ast_context list */
 
 static AST_RWLIST_HEAD_STATIC(apps, ast_app);
 
@@ -875,12 +875,12 @@ int ast_extension_close(const char *pattern, const char *data, int needmore)
 struct ast_context *ast_context_find(const char *name)
 {
 	struct ast_context *tmp = NULL;
-	ast_mutex_lock(&conlock);
+	ast_rdlock_contexts();
 	while ( (tmp = ast_walk_contexts(tmp)) ) {
 		if (!name || !strcasecmp(name, tmp->name))
 			break;
 	}
-	ast_mutex_unlock(&conlock);
+	ast_unlock_contexts();
 	return tmp;
 }
 
@@ -1672,21 +1672,21 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
 
 	int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
 
-	ast_mutex_lock(&conlock);
+	ast_rdlock_contexts();
 	e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
 	if (e) {
 		if (matching_action) {
-			ast_mutex_unlock(&conlock);
+			ast_unlock_contexts();
 			return -1;	/* success, we found it */
 		} else if (action == E_FINDLABEL) { /* map the label to a priority */
 			res = e->priority;
-			ast_mutex_unlock(&conlock);
+			ast_unlock_contexts();
 			return res;	/* the priority we were looking for */
 		} else {	/* spawn */
 			if (!e->cached_app)
 				e->cached_app = pbx_findapp(e->app);
 			app = e->cached_app;
-			ast_mutex_unlock(&conlock);
+			ast_unlock_contexts();
 			if (!app) {
 				ast_log(LOG_WARNING, "No application '%s' for extension (%s, %s, %d)\n", e->app, context, exten, priority);
 				return -1;
@@ -1728,7 +1728,7 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
 			return pbx_exec(c, app, passdata);	/* 0 on success, -1 on failure */
 		}
 	} else if (q.swo) {	/* not found here, but in another switch */
-		ast_mutex_unlock(&conlock);
+		ast_unlock_contexts();
 		if (matching_action)
 			return -1;
 		else {
@@ -1739,7 +1739,7 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
 			return q.swo->exec(c, q.foundcontext ? q.foundcontext : context, exten, priority, callerid, q.data);
 		}
 	} else {	/* not found anywhere, see what happened */
-		ast_mutex_unlock(&conlock);
+		ast_unlock_contexts();
 		switch (q.status) {
 		case STATUS_NO_CONTEXT:
 			if (!matching_action)
@@ -1772,9 +1772,9 @@ static struct ast_exten *ast_hint_extension(struct ast_channel *c, const char *c
 	struct ast_exten *e;
 	struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
 
-	ast_mutex_lock(&conlock);
+	ast_rdlock_contexts();
 	e = pbx_find_extension(c, NULL, &q, context, exten, PRIORITY_HINT, NULL, "", E_MATCH);
-	ast_mutex_unlock(&conlock);
+	ast_unlock_contexts();
 
 	return e;
 }
@@ -2557,7 +2557,7 @@ static struct ast_context *find_context_locked(const char *context)
 {
 	struct ast_context *c = NULL;
 
-	ast_lock_contexts();
+	ast_rdlock_contexts();
 	while ( (c = ast_walk_contexts(c)) ) {
 		if (!strcmp(ast_get_context_name(c), context))
 			return c;
@@ -2598,7 +2598,7 @@ int ast_context_remove_include2(struct ast_context *con, const char *include, co
 	struct ast_include *i, *pi = NULL;
 	int ret = -1;
 
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 
 	/* find our include */
 	for (i = con->includes; i; pi = i, i = i->next) {
@@ -2616,7 +2616,8 @@ int ast_context_remove_include2(struct ast_context *con, const char *include, co
 		}
 	}
 
-	ast_mutex_unlock(&con->lock);
+	ast_unlock_context(con);
+
 	return ret;
 }
 
@@ -2651,7 +2652,7 @@ int ast_context_remove_switch2(struct ast_context *con, const char *sw, const ch
 	struct ast_sw *i;
 	int ret = -1;
 
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 
 	/* walk switches */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&con->alts, i, list) {
@@ -2666,7 +2667,7 @@ int ast_context_remove_switch2(struct ast_context *con, const char *sw, const ch
 	}
 	AST_LIST_TRAVERSE_SAFE_END
 
-	ast_mutex_unlock(&con->lock);
+	ast_unlock_context(con);
 
 	return ret;
 }
@@ -2703,7 +2704,7 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension
 	struct ast_exten *exten, *prev_exten = NULL;
 	struct ast_exten *peer;
 
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 
 	/* scan the extension list to find matching extension-registrar */
 	for (exten = con->root; exten; prev_exten = exten, exten = exten->next) {
@@ -2713,7 +2714,7 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension
 	}
 	if (!exten) {
 		/* we can't find right extension */
-		ast_mutex_unlock(&con->lock);
+		ast_unlock_context(con);
 		return -1;
 	}
 
@@ -2740,7 +2741,7 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension
 				break; /* found our priority */
 		}
 		if (!peer) { /* not found */
-			ast_mutex_unlock(&con->lock);
+			ast_unlock_context(con);
 			return -1;
 		}
 		/* we are first priority extension? */
@@ -2765,7 +2766,7 @@ int ast_context_remove_extension2(struct ast_context *con, const char *extension
 		destroy_exten(peer);
 		/* XXX should we return -1 ? */
 	}
-	ast_mutex_unlock(&con->lock);
+	ast_unlock_context(con);
 	return 0;
 }
 
@@ -2780,7 +2781,7 @@ int ast_context_lockmacro(const char *context)
 	struct ast_context *c = NULL;
 	int ret = -1;
 
-	ast_lock_contexts();
+	ast_rdlock_contexts();
 
 	while ((c = ast_walk_contexts(c))) {
 		if (!strcmp(ast_get_context_name(c), context)) {
@@ -2808,7 +2809,7 @@ int ast_context_unlockmacro(const char *context)
 	struct ast_context *c = NULL;
 	int ret = -1;
 
-	ast_lock_contexts();
+	ast_rdlock_contexts();
 
 	while ((c = ast_walk_contexts(c))) {
 		if (!strcmp(ast_get_context_name(c), context)) {
@@ -3189,7 +3190,7 @@ static char *complete_show_dialplan_context(const char *line, const char *word,
 	if (pos != 2)
 		return NULL;
 
-	ast_lock_contexts();
+	ast_rdlock_contexts();
 
 	wordlen = strlen(word);
 
@@ -3236,7 +3237,7 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
 	struct ast_context *c = NULL;
 	int res = 0, old_total_exten = dpc->total_exten;
 
-	ast_lock_contexts();
+	ast_rdlock_contexts();
 
 	/* walk all contexts ... */
 	while ( (c = ast_walk_contexts(c)) ) {
@@ -3251,7 +3252,7 @@ static int show_dialplan_helper(int fd, const char *context, const char *exten,
 
 		dpc->context_existence = 1;
 
-		ast_lock_context(c);
+		ast_rdlock_context(c);
 
 		/* are we looking for exten too? if yes, we print context
 		 * only if we find our extension.
@@ -3464,7 +3465,7 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
 		ast_log(LOG_DEBUG, "manager_show_dialplan: Context: -%s- Extension: -%s-\n", context, exten);
 
 	/* try to lock contexts */
-	if (ast_lock_contexts()) {
+	if (ast_rdlock_contexts()) {
 		astman_send_error(s, m, "Failed to lock contexts\r\n");
 		ast_log(LOG_WARNING, "Failed to lock contexts list for manager: listdialplan\n");
 		return -1;
@@ -3484,7 +3485,7 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
 		if (option_debug > 2)
 			ast_log(LOG_DEBUG, "manager_show_dialplan: Found Context: %s \n", ast_get_context_name(c));
 
-		if (ast_lock_context(c)) {	/* failed to lock */
+		if (ast_rdlock_context(c)) {	/* failed to lock */
 			if (option_debug > 2)
 				ast_log(LOG_DEBUG, "manager_show_dialplan: Failed to lock context\n");
 			continue;
@@ -3731,7 +3732,7 @@ static void unreference_cached_app(struct ast_app *app)
 	struct ast_context *context = NULL;
 	struct ast_exten *eroot = NULL, *e = NULL;
 
-	ast_lock_contexts();
+	ast_rdlock_contexts();
 	while ((context = ast_walk_contexts(context))) {
 		while ((eroot = ast_walk_context_extensions(context, eroot))) {
 			while ((e = ast_walk_extension_priorities(eroot, e))) {
@@ -3772,7 +3773,7 @@ static struct ast_context *__ast_context_create(struct ast_context **extcontexts
 	int length = sizeof(struct ast_context) + strlen(name) + 1;
 
 	if (!extcontexts) {
-		ast_mutex_lock(&conlock);
+		ast_wrlock_contexts();
 		local_contexts = &contexts;
 	} else
 		local_contexts = extcontexts;
@@ -3784,12 +3785,12 @@ static struct ast_context *__ast_context_create(struct ast_context **extcontexts
 				tmp = NULL;
 			}
 			if (!extcontexts)
-				ast_mutex_unlock(&conlock);
+				ast_unlock_contexts();
 			return tmp;
 		}
 	}
 	if ((tmp = ast_calloc(1, length))) {
-		ast_mutex_init(&tmp->lock);
+		ast_rwlock_init(&tmp->lock);
 		ast_mutex_init(&tmp->macrolock);
 		strcpy(tmp->name, name);
 		tmp->root = NULL;
@@ -3805,7 +3806,7 @@ static struct ast_context *__ast_context_create(struct ast_context **extcontexts
 	}
 
 	if (!extcontexts)
-		ast_mutex_unlock(&conlock);
+		ast_unlock_contexts();
 	return tmp;
 }
 
@@ -3850,7 +3851,7 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char
 	   in addition, the locks _must_ be taken in this order, because there are already
 	   other code paths that use this order
 	*/
-	ast_mutex_lock(&conlock);
+	ast_wrlock_contexts();
 	AST_RWLIST_WRLOCK(&hints);
 
 	/* preserve all watchers for hints associated with this registrar */
@@ -3928,7 +3929,7 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char
 	}
 
 	AST_RWLIST_UNLOCK(&hints);
-	ast_mutex_unlock(&conlock);
+	ast_unlock_contexts();
 
 	return;
 }
@@ -4232,13 +4233,13 @@ int ast_context_add_include2(struct ast_context *con, const char *value,
 	new_include->next      = NULL;
 	new_include->registrar = registrar;
 
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 
 	/* ... go to last include and check if context is already included too... */
 	for (i = con->includes; i; i = i->next) {
 		if (!strcasecmp(i->name, new_include->name)) {
 			free(new_include);
-			ast_mutex_unlock(&con->lock);
+			ast_unlock_context(con);
 			errno = EEXIST;
 			return -1;
 		}
@@ -4252,7 +4253,8 @@ int ast_context_add_include2(struct ast_context *con, const char *value,
 		con->includes = new_include;
 	if (option_verbose > 2)
 		ast_verbose(VERBOSE_PREFIX_3 "Including context '%s' in context '%s'\n", new_include->name, ast_get_context_name(con));
-	ast_mutex_unlock(&con->lock);
+
+	ast_unlock_context(con);
 
 	return 0;
 }
@@ -4322,13 +4324,13 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
 	new_sw->registrar = registrar;
 
 	/* ... try to lock this context ... */
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 
 	/* ... go to last sw and check if context is already swd too... */
 	AST_LIST_TRAVERSE(&con->alts, i, list) {
 		if (!strcasecmp(i->name, new_sw->name) && !strcasecmp(i->data, new_sw->data)) {
 			free(new_sw);
-			ast_mutex_unlock(&con->lock);
+			ast_unlock_context(con);
 			errno = EEXIST;
 			return -1;
 		}
@@ -4340,7 +4342,7 @@ int ast_context_add_switch2(struct ast_context *con, const char *value,
 	if (option_verbose > 2)
 		ast_verbose(VERBOSE_PREFIX_3 "Including switch '%s/%s' in context '%s'\n", new_sw->name, new_sw->data, ast_get_context_name(con));
 
-	ast_mutex_unlock(&con->lock);
+	ast_unlock_context(con);
 
 	return 0;
 }
@@ -4365,7 +4367,7 @@ int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat
 {
 	struct ast_ignorepat *ip, *ipl = NULL;
 
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 
 	for (ip = con->ignorepats; ip; ip = ip->next) {
 		if (!strcmp(ip->pattern, ignorepat) &&
@@ -4377,13 +4379,13 @@ int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat
 				con->ignorepats = ip->next;
 				free(ip);
 			}
-			ast_mutex_unlock(&con->lock);
+			ast_unlock_context(con);
 			return 0;
 		}
 		ipl = ip;
 	}
 
-	ast_mutex_unlock(&con->lock);
+	ast_unlock_context(con);
 	errno = EINVAL;
 	return -1;
 }
@@ -4418,12 +4420,12 @@ int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const
 	strcpy((char *)ignorepat->pattern, value);
 	ignorepat->next = NULL;
 	ignorepat->registrar = registrar;
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 	for (ignorepatc = con->ignorepats; ignorepatc; ignorepatc = ignorepatc->next) {
 		ignorepatl = ignorepatc;
 		if (!strcasecmp(ignorepatc->pattern, value)) {
 			/* Already there */
-			ast_mutex_unlock(&con->lock);
+			ast_unlock_context(con);
 			errno = EEXIST;
 			return -1;
 		}
@@ -4432,7 +4434,7 @@ int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const
 		ignorepatl->next = ignorepat;
 	else
 		con->ignorepats = ignorepat;
-	ast_mutex_unlock(&con->lock);
+	ast_unlock_context(con);
 	return 0;
 
 }
@@ -4723,7 +4725,7 @@ int ast_add_extension2(struct ast_context *con,
 	tmp->datad = datad;
 	tmp->registrar = registrar;
 
-	ast_mutex_lock(&con->lock);
+	ast_wrlock_context(con);
 	res = 0; /* some compilers will think it is uninitialized otherwise */
 	for (e = con->root; e; el = e, e = e->next) {   /* scan the extension list */
 		res = ext_cmp(e->exten, extension);
@@ -4742,7 +4744,7 @@ int ast_add_extension2(struct ast_context *con,
 	}
 	if (e && res == 0) { /* exact match, insert in the pri chain */
 		res = add_pri(con, tmp, el, e, replace);
-		ast_mutex_unlock(&con->lock);
+		ast_unlock_context(con);
 		if (res < 0) {
 			errno = EEXIST;	/* XXX do we care ? */
 			return 0; /* XXX should we return -1 maybe ? */
@@ -4757,7 +4759,7 @@ int ast_add_extension2(struct ast_context *con,
 			el->next = tmp;
 		else
 			con->root = tmp;
-		ast_mutex_unlock(&con->lock);
+		ast_unlock_context(con);
 		if (tmp->priority == PRIORITY_HINT)
 			ast_add_hint(tmp);
 	}
@@ -5214,7 +5216,7 @@ void __ast_context_destroy(struct ast_context *con, const char *registrar)
 	struct ast_exten *e, *el, *en;
 	struct ast_ignorepat *ipi;
 
-	ast_mutex_lock(&conlock);
+	ast_wrlock_contexts();
 	for (tmp = contexts; tmp; ) {
 		struct ast_context *next;	/* next starting point */
 		for (; tmp; tmpl = tmp, tmp = tmp->next) {
@@ -5226,7 +5228,7 @@ void __ast_context_destroy(struct ast_context *con, const char *registrar)
 		}
 		if (!tmp)	/* not found, we are done */
 			break;
-		ast_mutex_lock(&tmp->lock);
+		ast_wrlock_context(tmp);
 		if (option_debug)
 			ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar);
 		next = tmp->next;
@@ -5236,7 +5238,7 @@ void __ast_context_destroy(struct ast_context *con, const char *registrar)
 			contexts = next;
 		/* Okay, now we're safe to let it go -- in a sense, we were
 		   ready to let it go as soon as we locked it. */
-		ast_mutex_unlock(&tmp->lock);
+		ast_unlock_context(tmp);
 		for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
 			struct ast_include *tmpil = tmpi;
 			tmpi = tmpi->next;
@@ -5259,12 +5261,12 @@ void __ast_context_destroy(struct ast_context *con, const char *registrar)
 			e = e->next;
 			destroy_exten(el);
 		}
-		ast_mutex_destroy(&tmp->lock);
+		ast_rwlock_destroy(&tmp->lock);
 		free(tmp);
 		/* if we have a specific match, we are done, otherwise continue */
 		tmp = con ? NULL : next;
 	}
-	ast_mutex_unlock(&conlock);
+	ast_unlock_contexts();
 }
 
 void ast_context_destroy(struct ast_context *con, const char *registrar)
@@ -5985,27 +5987,37 @@ int load_pbx(void)
 /*
  * Lock context list functions ...
  */
-int ast_lock_contexts()
+int ast_wrlock_contexts()
+{
+	return ast_rwlock_wrlock(&conlock);
+}
+
+int ast_rdlock_contexts()
 {
-	return ast_mutex_lock(&conlock);
+	return ast_rwlock_rdlock(&conlock);
 }
 
 int ast_unlock_contexts()
 {
-	return ast_mutex_unlock(&conlock);
+	return ast_rwlock_unlock(&conlock);
 }
 
 /*
  * Lock context ...
  */
-int ast_lock_context(struct ast_context *con)
+int ast_wrlock_context(struct ast_context *con)
+{
+	return ast_rwlock_wrlock(&con->lock);
+}
+
+int ast_rdlock_context(struct ast_context *con)
 {
-	return ast_mutex_lock(&con->lock);
+	return ast_rwlock_rdlock(&con->lock);
 }
 
 int ast_unlock_context(struct ast_context *con)
 {
-	return ast_mutex_unlock(&con->lock);
+	return ast_rwlock_unlock(&con->lock);
 }
 
 /*
diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c
index 217fb23cecfddcba0f7553113543d5515756fc01..79a18da0b6b6fff5db814ab2fc07cb39754af0dc 100644
--- a/pbx/pbx_config.c
+++ b/pbx/pbx_config.c
@@ -138,7 +138,7 @@ static int lookup_ci(struct ast_context *c, const char *name)
 {
 	struct ast_include *i = NULL;
 
-	if (ast_lock_context(c))	/* error, skip */
+	if (ast_rdlock_context(c))	/* error, skip */
 		return 0;
 	while ( (i = ast_walk_context_includes(c, i)) )
 		if (!strcmp(name, ast_get_include_name(i)))
@@ -152,7 +152,7 @@ static int lookup_c_ip(struct ast_context *c, const char *name)
 {
 	struct ast_ignorepat *ip = NULL;
 
-	if (ast_lock_context(c))	/* error, skip */
+	if (ast_rdlock_context(c))	/* error, skip */
 		return 0;
 	while ( (ip = ast_walk_context_ignorepats(c, ip)) )
 		if (!strcmp(name, ast_get_ignorepat_name(ip)))
@@ -217,7 +217,7 @@ static char *complete_context_remove_include(const char *line, const char *word,
 	struct ast_context *c = NULL;
 
 	if (pos == 3) {		/* "dialplan remove include _X_" */
-		if (ast_lock_contexts()) {
+		if (ast_wrlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			return NULL;
 		}
@@ -225,7 +225,7 @@ static char *complete_context_remove_include(const char *line, const char *word,
 		while (!res && (c = ast_walk_contexts(c))) {
 			struct ast_include *i = NULL;
 
-			if (ast_lock_context(c))	/* error ? skip this one */
+			if (ast_rdlock_context(c))	/* error ? skip this one */
 				continue;
 
 			while ( !res && (i = ast_walk_context_includes(c, i)) ) {
@@ -269,7 +269,7 @@ static char *complete_context_remove_include(const char *line, const char *word,
 		}
 		strsep(&dupline, " ");
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock contexts list\n");
 			free(context);
 			return NULL;
@@ -305,7 +305,7 @@ static char *complete_context_remove_include(const char *line, const char *word,
 			return NULL;
 		}
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			free(context);
 			return NULL;
@@ -480,7 +480,7 @@ static char *complete_context_remove_extension(const char *line, const char *wor
 		le = strlen(exten);
 		lc = strlen(context);
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			goto error2;
 		}
@@ -526,7 +526,7 @@ static char *complete_context_remove_extension(const char *line, const char *wor
 		if (le == 0 || lc == 0)
 			goto error3;
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			goto error3;
 		}
@@ -625,7 +625,7 @@ static char *complete_context_add_include(const char *line, const char *word, in
 	int len = strlen(word);
 
 	if (pos == 3) {		/* 'dialplan add include _X_' (context) ... */
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			return NULL;
 		}
@@ -652,7 +652,7 @@ static char *complete_context_add_include(const char *line, const char *word, in
 		strsep(&dupline, " ");
 
 		/* check for context existence ... */
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			/* our fault, we can't check, so complete 'into' ... */
 			ret = strdup("into");
@@ -681,7 +681,7 @@ static char *complete_context_add_include(const char *line, const char *word, in
 			goto error3;
 		}
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock context list\n");
 			goto error3;
 		}
@@ -764,7 +764,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
 	cfg = ast_config_load("extensions.conf");
 
 	/* try to lock contexts list */
-	if (ast_lock_contexts()) {
+	if (ast_rdlock_contexts()) {
 		ast_cli(fd, "Failed to lock contexts list\n");
 		ast_mutex_unlock(&save_dialplan_lock);
 		ast_config_destroy(cfg);
@@ -816,7 +816,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
 		struct ast_sw *sw;
 
 		/* try to lock context and fireout all info */	
-		if (ast_lock_context(c)) { /* lock failure */
+		if (ast_rdlock_context(c)) { /* lock failure */
 			incomplete = 1;
 			continue;
 		}
@@ -1042,7 +1042,7 @@ static char *complete_context_add_extension(const char *line, const char *word,
 		char *res = NULL;
 
 		/* try to lock contexts list ... */
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_WARNING, "Failed to lock contexts list\n");
 			return NULL;
 		}
@@ -1125,7 +1125,7 @@ static char *complete_context_add_ignorepat(const char *line, const char *word,
 		}
 		ignorepat = strsep(&dupline, " ");
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_ERROR, "Failed to lock contexts list\n");
 			return NULL;
 		}
@@ -1193,7 +1193,7 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
 
 	if (pos == 3) {
 		int len = strlen(word);
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_WARNING, "Failed to lock contexts list\n");
 			return NULL;
 		}
@@ -1201,7 +1201,7 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
 		for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
 			struct ast_ignorepat *ip;
 
-			if (ast_lock_context(c))	/* error, skip it */
+			if (ast_rdlock_context(c))	/* error, skip it */
 				continue;
 			
 			for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
@@ -1243,14 +1243,14 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
 			return NULL;
 		}
 
-		if (ast_lock_contexts()) {
+		if (ast_rdlock_contexts()) {
 			ast_log(LOG_WARNING, "Failed to lock contexts list\n");
 			free(dupline);
 			return NULL;
 		}
 
 		for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
-			if (ast_lock_context(c))	/* fail, skip it */
+			if (ast_rdlock_context(c))	/* fail, skip it */
 				continue;
 			if (!partial_match(ast_get_context_name(c), word, len))
 				continue;
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index cd7e969370f18b8b986c26b2fdb2695380023b08..62c2c558b0c2af4d370149ccf04596f07653bad3 100644
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -3613,13 +3613,13 @@ static void dundi_precache_full(void)
 
 	AST_LIST_TRAVERSE(&mappings, cur, list) {
 		ast_log(LOG_NOTICE, "Should precache context '%s'\n", cur->dcontext);
-		ast_lock_contexts();
+		ast_rdlock_contexts();
 		con = NULL;
 		while ((con = ast_walk_contexts(con))) {
 			if (strcasecmp(cur->lcontext, ast_get_context_name(con)))
 				continue;
 			/* Found the match, now queue them all up */
-			ast_lock_context(con);
+			ast_rdlock_context(con);
 			e = NULL;
 			while ((e = ast_walk_context_extensions(con, e)))
 				reschedule_precache(ast_get_extension_name(e), cur->dcontext, 0);