diff --git a/main/pbx.c b/main/pbx.c index bbc6df9d377f37c3d5ceb8aa1e8360aec0ee165b..b520f5fc98ebe896d51f06418f9f4fc2d7ffad67 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -3148,10 +3148,15 @@ static int internal_extension_state_extended(struct ast_channel *c, const char * } if (e->exten[0] == '_') { - /* Create this hint on-the-fly */ + /* Create this hint on-the-fly, we explicitly lock hints here to ensure the + * same locking order as if this were done through configuration file - that is + * hints is locked first and then (if needed) contexts is locked + */ + ao2_lock(hints); ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr, e->registrar); + ao2_unlock(hints); if (!(e = ast_hint_extension(c, context, exten))) { /* Improbable, but not impossible */ return -1; @@ -3228,9 +3233,11 @@ int ast_hint_presence_state(struct ast_channel *c, const char *context, const ch if (e->exten[0] == '_') { /* Create this hint on-the-fly */ + ao2_lock(hints); ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr, e->registrar); + ao2_unlock(hints); if (!(e = ast_hint_extension(c, context, exten))) { /* Improbable, but not impossible */ return -1; @@ -3766,9 +3773,11 @@ static int extension_state_add_destroy(const char *context, const char *exten, * individual extension, because the pattern will no longer match first. */ if (e->exten[0] == '_') { + ao2_lock(hints); ast_add_extension(e->parent->name, 0, exten, e->priority, e->label, e->matchcid ? e->cidmatch : NULL, e->app, ast_strdup(e->data), ast_free_ptr, e->registrar); + ao2_unlock(hints); e = ast_hint_extension(NULL, context, exten); if (!e || e->exten[0] == '_') { return -1;