|
|
|
@ -336,101 +336,14 @@ static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Hashing function for sorcery wizards */
|
|
|
|
|
static int sorcery_wizard_hash(const void *obj, const int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery_internal_wizard *object;
|
|
|
|
|
const char *key;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
key = obj;
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
object = obj;
|
|
|
|
|
key = object->callbacks.name;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ast_assert(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return ast_str_hash(key);
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_HASH_FN(ast_sorcery_internal_wizard, callbacks.name)
|
|
|
|
|
|
|
|
|
|
/*! \brief Comparator function for sorcery wizards */
|
|
|
|
|
static int sorcery_wizard_cmp(void *obj, void *arg, int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery_internal_wizard *object_left = obj;
|
|
|
|
|
const struct ast_sorcery_internal_wizard *object_right = arg;
|
|
|
|
|
const char *right_key = arg;
|
|
|
|
|
int cmp;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
right_key = object_right->callbacks.name;
|
|
|
|
|
/* Fall through */
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
cmp = strcmp(object_left->callbacks.name, right_key);
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_PARTIAL_KEY:
|
|
|
|
|
cmp = strncmp(object_left->callbacks.name, right_key, strlen(right_key));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmp = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cmp) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return CMP_MATCH;
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_CMP_FN(ast_sorcery_internal_wizard, callbacks.name)
|
|
|
|
|
|
|
|
|
|
/*! \brief Hashing function for sorcery wizards */
|
|
|
|
|
static int object_type_field_hash(const void *obj, const int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery_object_field *object_field;
|
|
|
|
|
const char *key;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
key = obj;
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
object_field = obj;
|
|
|
|
|
key = object_field->name;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ast_assert(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return ast_str_hash(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int object_type_field_cmp(void *obj, void *arg, int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery_object_field *field_left = obj;
|
|
|
|
|
const struct ast_sorcery_object_field *field_right = arg;
|
|
|
|
|
const char *right_key = arg;
|
|
|
|
|
int cmp;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
right_key = field_right->name;
|
|
|
|
|
/* Fall through */
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
cmp = strcmp(field_left->name, right_key);
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_PARTIAL_KEY:
|
|
|
|
|
cmp = strncmp(field_left->name, right_key, strlen(right_key));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmp = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cmp) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return CMP_MATCH;
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_HASH_FN(ast_sorcery_object_field, name)
|
|
|
|
|
AO2_STRING_FIELD_CMP_FN(ast_sorcery_object_field, name)
|
|
|
|
|
|
|
|
|
|
/*! \brief Cleanup function for graceful shutdowns */
|
|
|
|
|
static void sorcery_cleanup(void)
|
|
|
|
@ -446,53 +359,10 @@ static void sorcery_cleanup(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Compare function for sorcery instances */
|
|
|
|
|
static int sorcery_instance_cmp(void *obj, void *arg, int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery *object_left = obj;
|
|
|
|
|
const struct ast_sorcery *object_right = arg;
|
|
|
|
|
const char *right_key = arg;
|
|
|
|
|
int cmp;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
right_key = object_right->module_name;
|
|
|
|
|
/* Fall through */
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
cmp = strcmp(object_left->module_name, right_key);
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_PARTIAL_KEY:
|
|
|
|
|
cmp = strncmp(object_left->module_name, right_key, strlen(right_key));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmp = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cmp) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return CMP_MATCH;
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_CMP_FN(ast_sorcery, module_name)
|
|
|
|
|
|
|
|
|
|
/*! \brief Hashing function for sorcery instances */
|
|
|
|
|
static int sorcery_instance_hash(const void *obj, const int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery *object;
|
|
|
|
|
const char *key;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
key = obj;
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
object = obj;
|
|
|
|
|
key = object->module_name;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ast_assert(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return ast_str_hash(key);
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_HASH_FN(ast_sorcery, module_name)
|
|
|
|
|
|
|
|
|
|
int ast_sorcery_init(void)
|
|
|
|
|
{
|
|
|
|
@ -511,7 +381,7 @@ int ast_sorcery_init(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wizards = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, WIZARD_BUCKETS,
|
|
|
|
|
sorcery_wizard_hash, NULL, sorcery_wizard_cmp);
|
|
|
|
|
ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
|
|
|
|
|
if (!wizards) {
|
|
|
|
|
sorcery_cleanup();
|
|
|
|
|
return -1;
|
|
|
|
@ -524,7 +394,7 @@ int ast_sorcery_init(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instances = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0, INSTANCE_BUCKETS,
|
|
|
|
|
sorcery_instance_hash, NULL, sorcery_instance_cmp);
|
|
|
|
|
ast_sorcery_hash_fn, NULL, ast_sorcery_cmp_fn);
|
|
|
|
|
if (!instances) {
|
|
|
|
|
sorcery_cleanup();
|
|
|
|
|
return -1;
|
|
|
|
@ -724,53 +594,10 @@ static void sorcery_destructor(void *obj)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Hashing function for sorcery types */
|
|
|
|
|
static int sorcery_type_hash(const void *obj, const int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery_object_type *object;
|
|
|
|
|
const char *key;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
key = obj;
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
object = obj;
|
|
|
|
|
key = object->name;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ast_assert(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return ast_str_hash(key);
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_HASH_FN(ast_sorcery_object_type, name)
|
|
|
|
|
|
|
|
|
|
/*! \brief Comparator function for sorcery types */
|
|
|
|
|
static int sorcery_type_cmp(void *obj, void *arg, int flags)
|
|
|
|
|
{
|
|
|
|
|
const struct ast_sorcery_object_type *object_left = obj;
|
|
|
|
|
const struct ast_sorcery_object_type *object_right = arg;
|
|
|
|
|
const char *right_key = arg;
|
|
|
|
|
int cmp;
|
|
|
|
|
|
|
|
|
|
switch (flags & OBJ_SEARCH_MASK) {
|
|
|
|
|
case OBJ_SEARCH_OBJECT:
|
|
|
|
|
right_key = object_right->name;
|
|
|
|
|
/* Fall through */
|
|
|
|
|
case OBJ_SEARCH_KEY:
|
|
|
|
|
cmp = strcmp(object_left->name, right_key);
|
|
|
|
|
break;
|
|
|
|
|
case OBJ_SEARCH_PARTIAL_KEY:
|
|
|
|
|
cmp = strncmp(object_left->name, right_key, strlen(right_key));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmp = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cmp) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return CMP_MATCH;
|
|
|
|
|
}
|
|
|
|
|
AO2_STRING_FIELD_CMP_FN(ast_sorcery_object_type, name)
|
|
|
|
|
|
|
|
|
|
struct ast_sorcery *__ast_sorcery_open(const char *module_name)
|
|
|
|
|
{
|
|
|
|
@ -787,7 +614,9 @@ struct ast_sorcery *__ast_sorcery_open(const char *module_name)
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(sorcery->types = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, TYPE_BUCKETS, sorcery_type_hash, sorcery_type_cmp))) {
|
|
|
|
|
sorcery->types = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, TYPE_BUCKETS,
|
|
|
|
|
ast_sorcery_object_type_hash_fn, ast_sorcery_object_type_cmp_fn);
|
|
|
|
|
if (!sorcery->types) {
|
|
|
|
|
ao2_ref(sorcery, -1);
|
|
|
|
|
sorcery = NULL;
|
|
|
|
|
goto done;
|
|
|
|
@ -863,7 +692,7 @@ static struct ast_sorcery_object_type *sorcery_object_type_alloc(const char *typ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object_type->fields = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
|
|
|
|
|
OBJECT_FIELD_BUCKETS, object_type_field_hash, NULL, object_type_field_cmp);
|
|
|
|
|
OBJECT_FIELD_BUCKETS, ast_sorcery_object_field_hash_fn, NULL, ast_sorcery_object_field_cmp_fn);
|
|
|
|
|
if (!object_type->fields) {
|
|
|
|
|
ao2_ref(object_type, -1);
|
|
|
|
|
return NULL;
|
|
|
|
|