summaryrefslogtreecommitdiff
path: root/main/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/format.c')
-rw-r--r--main/format.c97
1 files changed, 35 insertions, 62 deletions
diff --git a/main/format.c b/main/format.c
index 82e3d2628..3af0f15f8 100644
--- a/main/format.c
+++ b/main/format.c
@@ -41,22 +41,17 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
#define FORMAT_CONFIG "codecs.conf"
-/*! This is the container for all the format attribute interfaces.
- * An ao2 container was chosen for fast lookup. */
+/*!
+ * \brief Container for all the format attribute interfaces.
+ * \note This container uses RWLOCKs instead of MUTEX locks. .
+ * \note An ao2 container was chosen for fast lookup.
+ */
static struct ao2_container *interfaces;
-/*! This is the lock used to protect the interfaces container. Yes, ao2_containers
- * do have their own locking, but we need the capability of performing read/write
- * locks on this specific container. */
-static ast_rwlock_t ilock;
-
/*! a wrapper is used put interfaces into the ao2 container. */
struct interface_ao2_wrapper {
enum ast_format_id id;
const struct ast_format_attr_interface *interface;
- /*! a read write lock must be used to protect the wrapper instead
- * of the ao2 lock. */
- ast_rwlock_t wraplock;
};
/*! \brief Format List container, This container is never directly accessed outside
@@ -84,12 +79,6 @@ static int interface_hash_cb(const void *obj, const int flags)
return wrapper->id;
}
-static void interface_destroy_cb(void *obj)
-{
- struct interface_ao2_wrapper *wrapper = obj;
- ast_rwlock_destroy(&wrapper->wraplock);
-}
-
void ast_format_copy(struct ast_format *dst, const struct ast_format *src)
{
memcpy(dst, src, sizeof(struct ast_format));
@@ -107,16 +96,11 @@ int ast_format_get_video_mark(const struct ast_format *format)
static struct interface_ao2_wrapper *find_interface(const struct ast_format *format)
{
- struct interface_ao2_wrapper *wrapper;
struct interface_ao2_wrapper tmp_wrapper = {
.id = format->id,
};
- ast_rwlock_rdlock(&ilock);
- wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_NOLOCK));
- ast_rwlock_unlock(&ilock);
-
- return wrapper;
+ return ao2_find(interfaces, &tmp_wrapper, OBJ_POINTER);
}
static int has_interface(const struct ast_format *format)
@@ -143,16 +127,16 @@ static int format_set_helper(struct ast_format *format, va_list ap)
return -1;
}
- ast_rwlock_rdlock(&wrapper->wraplock);
+ ao2_rdlock(wrapper);
if (!wrapper->interface || !wrapper->interface->format_attr_set) {
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return -1;
}
wrapper->interface->format_attr_set(&format->fattr, ap);
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return 0;
@@ -207,12 +191,12 @@ static int format_isset_helper(const struct ast_format *format, va_list ap)
return -1;
}
- ast_rwlock_rdlock(&wrapper->wraplock);
+ ao2_rdlock(wrapper);
if (!wrapper->interface ||
!wrapper->interface->format_attr_set ||
!wrapper->interface->format_attr_cmp) {
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return -1;
}
@@ -228,7 +212,7 @@ static int format_isset_helper(const struct ast_format *format, va_list ap)
res = (res == AST_FORMAT_CMP_NOT_EQUAL) ? -1 : 0;
}
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return res;
@@ -249,21 +233,22 @@ int ast_format_get_value(const struct ast_format *format, int key, void *value)
{
int res = 0;
struct interface_ao2_wrapper *wrapper;
+
if (!(wrapper = find_interface(format))) {
return -1;
}
- ast_rwlock_rdlock(&wrapper->wraplock);
+ ao2_rdlock(wrapper);
if (!wrapper->interface ||
!wrapper->interface->format_attr_get_val) {
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return -1;
}
res = wrapper->interface->format_attr_get_val(&format->fattr, key, value);
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return res;
@@ -281,16 +266,16 @@ static enum ast_format_cmp_res format_cmp_helper(const struct ast_format *format
return res;
}
- ast_rwlock_rdlock(&wrapper->wraplock);
+ ao2_rdlock(wrapper);
if (!wrapper->interface || !wrapper->interface->format_attr_cmp) {
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return res;
}
res = wrapper->interface->format_attr_cmp(&format1->fattr, &format2->fattr);
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
return res;
@@ -318,11 +303,11 @@ static int format_joint_helper(const struct ast_format *format1, const struct as
return res;
}
- ast_rwlock_rdlock(&wrapper->wraplock);
+ ao2_rdlock(wrapper);
if (wrapper->interface && wrapper->interface->format_attr_get_joint) {
res = wrapper->interface->format_attr_get_joint(&format1->fattr, &format2->fattr, &result->fattr);
}
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);
@@ -1066,21 +1051,13 @@ init_list_cleanup:
int ast_format_attr_init(void)
{
ast_cli_register_multiple(my_clis, ARRAY_LEN(my_clis));
- if (ast_rwlock_init(&ilock)) {
- return -1;
- }
- if (!(interfaces = ao2_container_alloc(283, interface_hash_cb, interface_cmp_cb))) {
- goto init_cleanup;
+ interfaces = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK,
+ 283, interface_hash_cb, interface_cmp_cb);
+ if (!interfaces) {
+ return -1;
}
return 0;
-
-init_cleanup:
- ast_rwlock_destroy(&ilock);
- if (interfaces) {
- ao2_ref(interfaces, -1);
- }
- return -1;
}
static int custom_celt_format(struct ast_format_list *entry, unsigned int maxbitrate, unsigned int framesize)
@@ -1310,28 +1287,28 @@ int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interf
* anticipation of adding a new interface and to prevent a
* duplicate from sneaking in between the check and add.
*/
- ast_rwlock_wrlock(&ilock);
+ ao2_wrlock(interfaces);
/* check for duplicates first*/
if ((wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_NOLOCK)))) {
- ast_rwlock_unlock(&ilock);
+ ao2_unlock(interfaces);
ast_log(LOG_WARNING, "Can not register attribute interface for format id %d, interface already exists.\n", interface->id);
ao2_ref(wrapper, -1);
return -1;
}
- if (!(wrapper = ao2_alloc(sizeof(*wrapper), interface_destroy_cb))) {
- ast_rwlock_unlock(&ilock);
+ wrapper = ao2_alloc_options(sizeof(*wrapper), NULL, AO2_ALLOC_OPT_LOCK_RWLOCK);
+ if (!wrapper) {
+ ao2_unlock(interfaces);
return -1;
}
wrapper->interface = interface;
wrapper->id = interface->id;
- ast_rwlock_init(&wrapper->wraplock);
/* The write lock is already held. */
- ao2_link_nolock(interfaces, wrapper);
- ast_rwlock_unlock(&ilock);
+ ao2_link_flags(interfaces, wrapper, OBJ_NOLOCK);
+ ao2_unlock(interfaces);
ao2_ref(wrapper, -1);
@@ -1359,17 +1336,13 @@ int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *inte
.id = interface->id,
};
- /* use the write lock whenever the interface container is modified */
- ast_rwlock_wrlock(&ilock);
- if (!(wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_UNLINK | OBJ_NOLOCK)))) {
- ast_rwlock_unlock(&ilock);
+ if (!(wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_UNLINK)))) {
return -1;
}
- ast_rwlock_unlock(&ilock);
- ast_rwlock_wrlock(&wrapper->wraplock);
+ ao2_wrlock(wrapper);
wrapper->interface = NULL;
- ast_rwlock_unlock(&wrapper->wraplock);
+ ao2_unlock(wrapper);
ao2_ref(wrapper, -1);