diff options
Diffstat (limited to 'main/format.c')
-rw-r--r-- | main/format.c | 97 |
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); |