summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/res_pjsip/pjsip_options.c3
-rw-r--r--res/res_sorcery_memory.c16
2 files changed, 18 insertions, 1 deletions
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 089703b26..73f12a00c 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -107,6 +107,8 @@ static void *contact_status_alloc(const char *name)
return status;
}
+AST_MUTEX_DEFINE_STATIC(creation_lock);
+
/*!
* \brief Retrieve a ast_sip_contact_status object from sorcery creating
* one if not found.
@@ -114,6 +116,7 @@ static void *contact_status_alloc(const char *name)
struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const struct ast_sip_contact *contact)
{
struct ast_sip_contact_status *status;
+ SCOPED_MUTEX(lock, &creation_lock);
status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS,
ast_sorcery_object_get_id(contact));
diff --git a/res/res_sorcery_memory.c b/res/res_sorcery_memory.c
index 153235838..95cb24835 100644
--- a/res/res_sorcery_memory.c
+++ b/res/res_sorcery_memory.c
@@ -98,7 +98,21 @@ static int sorcery_memory_cmp(void *obj, void *arg, int flags)
static int sorcery_memory_create(const struct ast_sorcery *sorcery, void *data, void *object)
{
- ao2_link(data, object);
+ void *existing;
+
+ ao2_lock(data);
+
+ existing = ao2_find(data, ast_sorcery_object_get_id(object), OBJ_KEY | OBJ_NOLOCK);
+ if (existing) {
+ ao2_ref(existing, -1);
+ ao2_unlock(data);
+ return -1;
+ }
+
+ ao2_link_flags(data, object, OBJ_NOLOCK);
+
+ ao2_unlock(data);
+
return 0;
}