42 #include "asterisk/threadpool.h"
51 #define WIZARD_BUCKETS 7
54 #define TYPE_BUCKETS 53
57 #define INSTANCE_BUCKETS 17
60 #define OBJECT_FIELD_BUCKETS 29
62 #define NOTIFY_GENERIC_OBSERVERS(container, type, callback, ...) ({ \
63 struct ao2_iterator i = ao2_iterator_init(container, 0); \
64 struct type *observer; \
65 ao2_rdlock(container); \
66 while ((observer = ao2_iterator_next(&i))) { \
67 if (observer->callbacks->callback) { \
68 observer->callbacks->callback(__VA_ARGS__); \
70 ao2_cleanup(observer); \
72 ao2_unlock(container); \
73 ao2_iterator_cleanup(&i); \
76 #define NOTIFY_GLOBAL_OBSERVERS(container, callback, ...) \
77 NOTIFY_GENERIC_OBSERVERS(container, sorcery_global_observer, callback, __VA_ARGS__)
79 #define NOTIFY_INSTANCE_OBSERVERS(container, callback, ...) \
80 NOTIFY_GENERIC_OBSERVERS(container, sorcery_instance_observer, callback, __VA_ARGS__)
82 #define NOTIFY_WIZARD_OBSERVERS(container, callback, ...) \
83 NOTIFY_GENERIC_OBSERVERS(container, sorcery_wizard_observer, callback, __VA_ARGS__)
286 static int int_handler_fn(
const void *obj,
const intptr_t *args,
char **buf)
288 int *field = (
int *)(obj + args[0]);
292 static int uint_handler_fn(
const void *obj,
const intptr_t *args,
char **buf)
294 unsigned int *field = (
unsigned int *)(obj + args[0]);
300 double *field = (
double *)(obj + args[0]);
306 ast_string_field *field = (
const char **)(obj + args[0]);
310 static int bool_handler_fn(
const void *obj,
const intptr_t *args,
char **buf)
312 unsigned int *field = (
unsigned int *)(obj + args[0]);
313 return !(*buf =
ast_strdup(*field ?
"true" :
"false")) ? -1 : 0;
316 static int yesno_handler_fn(
const void *obj,
const intptr_t *args,
char **buf)
318 unsigned int *field = (
unsigned int *)(obj + args[0]);
319 return !(*buf =
ast_strdup(*field ?
"yes" :
"no")) ? -1 : 0;
330 char *field = (
char *)(obj + args[0]);
334 static int codec_handler_fn(
const void *obj,
const intptr_t *args,
char **buf)
371 ast_threadpool_shutdown(threadpool);
373 ao2_cleanup(wizards);
375 ao2_cleanup(observers);
377 ao2_cleanup(instances);
390 .
version = AST_THREADPOOL_OPTIONS_VERSION,
396 ast_assert(wizards == NULL);
398 threadpool = ast_threadpool_create(
"sorcery", NULL, &options);
404 ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
415 sorcery_proxy_hash_fn, NULL, sorcery_proxy_cmp_fn);
425 static void sorcery_internal_wizard_destructor(
void *obj)
437 ast_assert(!ast_strlen_zero(interface->
name));
442 ast_log(LOG_WARNING,
"Attempted to register sorcery wizard '%s' twice\n",
447 if (!(wizard = ao2_alloc(
sizeof(*wizard), sorcery_internal_wizard_destructor))) {
462 ast_verb(5,
"Sorcery registered wizard '%s'\n", interface->
name);
464 NOTIFY_GLOBAL_OBSERVERS(observers, wizard_registered,
465 interface->
name, interface);
477 interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL;
483 ast_verb(5,
"Sorcery unregistered wizard '%s'\n", interface->name);
495 return (observer->callbacks == arg) ?
CMP_MATCH : 0;
502 cb = ao2_alloc(
sizeof(*cb), NULL);
507 cb->callbacks = callbacks;
525 cb = ao2_alloc(
sizeof(*cb), NULL);
530 cb->callbacks = callbacks;
553 cb = ao2_alloc(
sizeof(*cb), NULL);
558 cb->callbacks = callbacks;
586 NOTIFY_GLOBAL_OBSERVERS(observers, instance_destroying, sorcery->
module_name, sorcery);
589 ao2_cleanup(sorcery->
types);
601 struct ast_sorcery *__ast_sorcery_open(
const char *
module_name,
const char *file,
int line,
const char *func)
606 ast_assert(module_name != NULL);
608 ao2_wrlock(instances);
610 __PRETTY_FUNCTION__, file, line, func);
612 ao2_unlock(instances);
617 proxy = ao2_t_weakproxy_alloc(
sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);
619 goto failure_cleanup;
625 goto failure_cleanup;
631 if (ao2_t_weakproxy_set_object(proxy, sorcery,
OBJ_NOLOCK,
"weakproxy link")) {
632 goto failure_cleanup;
636 goto failure_cleanup;
640 ast_sorcery_object_type_hash_fn, NULL, ast_sorcery_object_type_cmp_fn);
641 if (!sorcery->
types) {
642 goto failure_cleanup;
646 goto failure_cleanup;
650 ast_log(LOG_ERROR,
"Error attempting to apply configuration %s to sorcery.\n", module_name);
651 goto failure_cleanup;
657 NOTIFY_GLOBAL_OBSERVERS(observers, instance_created, module_name, sorcery);
659 ao2_unlock(instances);
664 ao2_unlock(instances);
665 ao2_cleanup(sorcery);
686 ao2_cleanup(object_type->
fields);
689 if (object_type->
info) {
691 ast_free(object_type->
info);
694 ast_free(object_type->
file);
702 #define INITIAL_WIZARD_VECTOR_SIZE 5
718 if (!object_type->
fields) {
731 sizeof(*object_type->
info) + 2 *
sizeof(object_type->
info->
files[0]));
732 if (!object_type->
info) {
738 sizeof(*object_type->
file) + 2 *
sizeof(object_type->
file->
types[0]));
739 if (!object_type->
file) {
747 if (!(object_type->
serializer = ast_threadpool_serializer(tps_name, threadpool))) {
770 if (object_wizard->
wizard) {
774 ao2_cleanup(object_wizard->
wizard);
806 if (wizard != NULL) {
814 *data = owizard->
data;
821 const char *object_type_name,
const char *module,
const char *wizard_type_name,
851 const char *type,
const char *module,
const char *name)
861 #define WIZARD_NAME_COMPARE(a, b) (strcmp((a)->wizard->callbacks.name, (b)) == 0)
863 #undef WIZARD_NAME_COMPARE
870 const char *object_type_name,
const char *module,
const char *wizard_type_name,
879 object_wizard = ao2_alloc(
sizeof(*object_wizard)
880 + (ast_strlen_zero(wizard_args) ? 0 : strlen(wizard_args) + 1),
883 if (!object_wizard) {
890 "Wizard '%s' could not be applied to object type '%s' as it was not found\n",
891 wizard_type_name, object_type_name);
907 #define WIZARD_COMPARE(a, b) ((a)->wizard == (b))
909 #undef WIZARD_COMPARE
912 ast_debug(1,
"Wizard %s already applied to object type %s\n",
913 internal_wizard->callbacks.name, object_type->name);
920 ast_debug(5,
"Calling wizard %s open callback on object type %s\n",
921 wizard_type_name, object_type->name);
922 if (internal_wizard->callbacks.open && !(object_wizard->data = internal_wizard->callbacks.open(wizard_args))) {
923 ast_log(LOG_WARNING,
"Wizard '%s' failed to open mapping for object type '%s' with data: %s\n",
924 wizard_type_name, object_type->name,
S_OR(wizard_args,
""));
930 object_wizard->wizard =
ao2_bump(internal_wizard);
934 strcpy(object_wizard->wizard_args, wizard_args);
937 if (position == AST_SORCERY_WIZARD_POSITION_LAST) {
952 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, wizard_mapped,
953 sorcery->
module_name, sorcery, object_type_name, &internal_wizard->callbacks, wizard_args,
954 object_wizard->data);
957 *wizard = &internal_wizard->callbacks;
960 *wizard_data = object_wizard->data;
968 const char *type,
const char *module,
const char *name,
969 const char *
data,
unsigned int caching,
int position)
973 position, NULL, NULL);
978 const char *type,
const char *module,
const char *name,
982 data, caching, AST_SORCERY_WIZARD_POSITION_LAST);
996 if (config == CONFIG_STATUS_FILEINVALID) {
1000 for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->
next) {
1003 char *options = mapping_name;
1004 char *type = strsep(&options,
"/");
1005 char *data = mapping_value;
1006 char *wizard = strsep(&data,
",");
1007 unsigned int caching = 0;
1010 if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
1015 if (!ast_strlen_zero(options) && strstr(options,
"cache")) {
1043 static int sorcery_extended_config_handler(
const struct aco_option *opt,
struct ast_variable *var,
void *obj)
1048 static int sorcery_extended_fields_handler(
const void *obj,
struct ast_variable **fields)
1066 ao2_wrlock(sorcery->
types);
1068 if (object_type && object_type->
type.
type == ACO_ITEM) {
1072 ao2_unlock(sorcery->
types);
1076 ao2_cleanup(object_type);
1084 if (!object_type || object_type->type.item_alloc) {
1088 object_type->type.name = object_type->name;
1089 object_type->type.type = ACO_ITEM;
1090 object_type->type.category =
".?";
1091 object_type->type.item_alloc = alloc;
1092 object_type->type.hidden = hidden;
1096 object_type->apply =
apply;
1097 object_type->file->types[0] = &object_type->type;
1098 object_type->file->types[1] = NULL;
1108 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, object_type_registered,
1122 low_water, high_water);
1136 object_type->copy =
copy;
1147 object_type->diff =
diff;
1150 static void sorcery_object_field_destructor(
void *obj)
1162 #define MAX_REGEX_ERROR_LEN 128
1167 if (!object_type || !object_type->type.item_alloc || !config_handler
1168 || !(object_field = ao2_alloc(
sizeof(*object_field), sorcery_object_field_destructor))) {
1179 if ((rc = regcomp(object_field->
name_regex, regex, REG_EXTENDED | REG_NOSUB))) {
1180 char *regerr =
ast_alloca(MAX_REGEX_ERROR_LEN);
1181 regerror(rc, object_field->
name_regex, regerr, MAX_REGEX_ERROR_LEN);
1182 ast_log(LOG_ERROR,
"Regular expression '%s' failed to compile: %s\n", regex, regerr);
1186 ao2_link(object_type->fields, object_field);
1200 if (!strcmp(type,
"id") || !object_type || !object_type->type.item_alloc) {
1204 if (!sorcery_handler) {
1205 sorcery_handler = sorcery_field_default_handler(opt_type);
1208 if (!(object_field = ao2_alloc(
sizeof(*object_field) + argc *
sizeof(object_field->
args[0]), NULL))) {
1213 object_field->
handler = sorcery_handler;
1216 va_start(args, argc);
1217 for (pos = 0; pos < argc; pos++) {
1218 object_field->
args[pos] = va_arg(args,
size_t);
1223 ao2_link(object_type->fields, object_field);
1228 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc);
1229 }
else if (argc == 1) {
1230 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1231 object_field->
args[0]);
1232 }
else if (argc == 2) {
1233 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1234 object_field->
args[0], object_field->
args[1]);
1235 }
else if (argc == 3) {
1236 __aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, no_doc, argc,
1237 object_field->
args[0], object_field->
args[1], object_field->
args[2]);
1250 return object_type && object_type->reloadable;
1253 static int sorcery_wizard_load(
void *obj,
void *arg,
int flags)
1257 void (*load)(
void *data,
const struct ast_sorcery *sorcery,
const char *type);
1288 ao2_cleanup(invocation->
object);
1296 invocation = ao2_alloc_options(
sizeof(*invocation),
1331 ao2_cleanup(invocation);
1336 static int sorcery_object_load(
void *obj,
void *arg,
int flags)
1348 ast_log(LOG_NOTICE,
"Type '%s' is not reloadable, maintaining previous values\n",
1353 NOTIFY_INSTANCE_OBSERVERS(details->
sorcery->
observers, object_type_loading,
1370 ao2_cleanup(invocation);
1384 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, instance_loading,
1389 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, instance_loaded,
1405 sorcery_object_load(object_type, &details, 0);
1415 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, instance_loading,
1420 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, instance_loaded,
1433 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, instance_loading,
1438 NOTIFY_INSTANCE_OBSERVERS(sorcery->
observers, instance_loaded,
1454 sorcery_object_load(object_type, &details, 0);
1470 sorcery_object_load(object_type, &details, 0);
1487 if (!(object_field->
handler(
object, object_field->
args, &buf))) {
1488 tmp = ast_variable_new(object_field->
name,
S_OR(buf,
""),
"");
1527 for (; (object_field = ao2_iterator_next(&i));
ao2_ref(object_field, -1)) {
1532 if ((tmp = get_multiple_fields_as_var_list(
object, object_field)) ||
1533 (tmp = get_single_field_as_var_list(
object, object_field))) {
1538 if ((tmp = get_single_field_as_var_list(
object, object_field)) ||
1539 (tmp = get_multiple_fields_as_var_list(
object, object_field))) {
1544 if ((tmp = get_multiple_fields_as_var_list(
object, object_field))) {
1549 if ((tmp = get_single_field_as_var_list(
object, object_field))) {
1574 if (!object_type || !json) {
1581 for (; !res && (object_field = ao2_iterator_next(&i));
ao2_ref(object_field, -1)) {
1582 if (object_field->multiple_handler) {
1586 if ((res = object_field->multiple_handler(
object, &tmp))) {
1592 for (field = tmp; field; field = field->
next) {
1602 }
else if (object_field->handler) {
1606 if (object_field->handler(
object, object_field->args, &buf)
1610 ast_debug(5,
"Skipping field '%s' for object type '%s'\n",
1611 object_field->name, object_type->name);
1644 if (object_type->transform && (transformed = object_type->transform(objectset))) {
1645 field = transformed;
1650 for (; field; field = field->
next) {
1656 if (!res && object_type->apply) {
1657 res = object_type->apply(sorcery,
object);
1671 if (original == modified) {
1675 for (field = modified; field; field = field->
next) {
1678 if (!old_value || strcmp(old_value, field->
value)) {
1681 if (!(tmp = ast_variable_new(field->
name, field->
value,
""))) {
1686 tmp->
next = *changes;
1700 static void sorcery_object_destructor(
void *
object)
1715 sorcery_object_destructor, lockobj,
"");
1722 details->
object =
object + size;
1738 details->
object =
object + size;
1749 if (!object_type || !object_type->type.item_alloc ||
1750 !(details = object_type->type.item_alloc(
id))) {
1754 if (ast_strlen_zero(
id)) {
1755 char uuid[AST_UUID_STR_LEN];
1788 }
else if (object_type->copy) {
1789 res = object_type->copy(
object, copy);
1815 if (original == modified) {
1817 }
else if (!object_type->diff) {
1826 return object_type->diff(original, modified, changes);
1856 void *
object = NULL;
1858 unsigned int cached = 0;
1860 if (ast_strlen_zero(
id)) {
1883 if (!cached &&
object) {
1900 void *
object = NULL;
1902 unsigned int cached = 0;
1921 if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1941 if (!(flags & AST_RETRIEVE_FLAG_MULTIPLE) && !cached &&
object) {
2057 ao2_cleanup(invocation);
2083 object_wizard = found_wizard;
2087 if (object_wizard) {
2102 ao2_cleanup(invocation);
2109 return object_wizard ? 0 : -1;
2130 ao2_cleanup(invocation);
2171 object_wizard = found_wizard;
2175 if (object_wizard) {
2190 ao2_cleanup(invocation);
2197 return object_wizard ? 0 : -1;
2218 ao2_cleanup(invocation);
2259 object_wizard = found_wizard;
2263 if (object_wizard) {
2278 ao2_cleanup(invocation);
2285 return object_wizard ? 0 : -1;
2306 ast_debug(5,
"After calling wizard '%s', object '%s' is %s\n",
2309 res ?
"stale" :
"not stale");
2341 if (!strcmp(field->
name + 1, name)) {
2342 return field->
value;
2352 struct ast_variable *extended = ast_variable_new(name, value,
""), *previous = NULL;
2359 for (field = details->
object->
extended; field; previous = field, field = field->
next) {
2360 if (!strcmp(field->name, name)) {
2362 previous->next = field->next;
2397 if (!object_type || !callbacks) {
2401 if (!(observer = ao2_alloc(
sizeof(*observer), NULL))) {
2407 if (!
ao2_link(object_type->observers, observer)) {
2442 const void *object_left = obj;
2443 const void *object_right = arg;
2444 const char *right_key = arg;
2500 static int is_registered_cb(
void *obj,
void *arg,
int flags)
2507 && !regexec(object_field->
name_regex, name, 0, NULL, 0)) {
2515 const char *field_name)
2520 ast_assert(object_type != NULL);
2524 if (!object_field) {
2525 object_field =
ao2_callback(object_type->
fields, 0, is_registered_cb, (
char *)field_name);
2528 if (!object_field) {
2532 ao2_cleanup(object_field);
void * ast_sorcery_lockable_alloc(size_t size, ao2_destructor_fn destructor, void *lockobj)
Allocate a generic sorcery capable object with locking.
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Type for default handler for ast_sockaddrs.
struct ast_variable * next
Type for default option handler for format capabilities.
int(* aco_option_handler)(const struct aco_option *opt, struct ast_variable *var, void *obj)
A callback function for handling a particular option.
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Try both handlers, list first.
int(* sorcery_field_handler)(const void *obj, const intptr_t *args, char **buf)
A callback function for translating a value into a string.
static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
Allocator function for observer invocation.
static int sockaddr_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default handler for ast_sockaddrs.
static void sorcery_object_type_destructor(void *obj)
Destructor function for object types.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
enum ast_sorcery_apply_result __ast_sorcery_object_type_insert_wizard(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, enum ast_sorcery_wizard_apply_flags flags, int position, struct ast_sorcery_wizard **wizard, void **wizard_data)
Insert an additional object wizard mapping at a specific position in the wizard list returning wizard...
int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value)
Set an extended field value on a sorcery object.
unsigned int force
Whether this is forced or not.
Structure used when calling create, update, or delete.
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
Asterisk main include file. File version handling, generic pbx functions.
AO2_STRING_FIELD_HASH_FN(transport_monitor, key)
Hashing function for struct transport_monitor.
int(* update)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for updating an object.
static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default handler for character arrays.
static int sorcery_observer_notify_create(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object has been created...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
ast_sorcery_field_handler_flags
Field handler flags.
static int sorcery_cache_create(void *obj, void *arg, int flags)
Internal function used to create an object in caching wizards.
char * id
Unique identifier of this object.
enum ast_sorcery_apply_result __ast_sorcery_apply_config(struct ast_sorcery *sorcery, const char *name, const char *module)
Apply configured wizard mappings.
struct aco_file * file
Configuration framework file information.
static int sorcery_generic_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing a generic observer.
void(* deleted)(const void *object)
Callback for when an object is deleted.
char wizard_args[0]
Wizard arguments.
String manipulation functions.
unsigned int allow_duplicates
Wizard allows others of the same type.
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
static int sorcery_observer_notify_loaded(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object type has been loaded...
The arg parameter is a search key, but is not an object.
void ast_sorcery_object_set_copy_handler(struct ast_sorcery *sorcery, const char *type, sorcery_copy_handler copy)
Set the copy handler for an object type.
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
struct ao2_container * observers
Registered global observers.
Interface for the global sorcery observer.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
const char * ast_sorcery_get_module(const struct ast_sorcery *sorcery)
Get the module that has opened the provided sorcery instance.
int ast_sorcery_is_stale(const struct ast_sorcery *sorcery, void *object)
Determine if a sorcery object is stale with respect to its backing datastore.
static struct ao2_container * instances
Registered sorcery instances.
int(* sorcery_fields_handler)(const void *obj, struct ast_variable **fields)
A callback function for translating multiple values into an ast_variable list.
void * obj
Pointer to the object itself.
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
int ast_sorcery_get_wizard_mapping_count(struct ast_sorcery *sorcery, const char *type)
Return the number of wizards mapped to an object type.
static int sorcery_wizard_create(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if the wizard has created the object.
sorcery_transform_handler transform
Optional transformation callback.
Structure for registered object type observer.
char * module_name
Pointer to module_name in the associated sorcery_proxy.
int(* sorcery_apply_handler)(const struct ast_sorcery *sorcery, void *obj)
A callback function for when an object set is successfully applied to an object.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
struct ao2_container * observers
Observers.
int ast_sorcery_get_wizard_mapping(struct ast_sorcery *sorcery, const char *type, int index, struct ast_sorcery_wizard **wizard, void **data)
By index, return a wizard mapped to an object type.
int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
Register an object type.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Structure for variables, used for configurations and for channel variables.
void(* created)(const void *object)
Callback for when an object is created.
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
int ast_sorcery_object_set_congestion_levels(struct ast_sorcery *sorcery, const char *type, long low_water, long high_water)
Set the high and low alert water marks of the sorcery object type.
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
static int uint_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for unsigned integers.
static int sorcery_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing an observer.
Assume that the ao2_container is already locked.
Full structure for sorcery.
AO2_STRING_FIELD_CMP_FN(transport_monitor, key)
Comparison function for struct transport_monitor.
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
#define ao2_alloc_with_lockobj(data_size, destructor_fn, lockobj, tag)
Allocate and initialize an object with separate locking.
struct ao2_container * observers
Observers.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static int codec_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for codec preferences/capabilities.
Return all matching objects.
void ast_sorcery_wizard_observer_remove(struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
Remove an observer from a sorcery wizard.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
#define ast_strdup(str)
A wrapper for strdup()
struct ast_module * module
Pointer to the Asterisk module this wizard is implemented by.
int ast_taskprocessor_alert_set_levels(struct ast_taskprocessor *tps, long low_water, long high_water)
Set the high and low alert water marks of the given taskprocessor queue.
The representation of a single configuration file to be processed.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
const char * name
Name of the wizard.
int(* create)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for creating an object.
Socket address structure.
struct ast_sorcery_wizard callbacks
Wizard interface itself.
void * object
Pointer to the object.
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks)
Remove a global observer from sorcery.
intptr_t args[]
Position of the field.
void *(* retrieve_fields)(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)
Optional callback for retrieving an object using fields.
const struct ast_sorcery * sorcery
Sorcery structure in use.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
void(* close)(void *data)
Callback for closing a wizard.
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
void(* retrieve_prefix)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len)
Optional callback for retrieving multiple objects by matching their id with a prefix.
Type for a custom (user-defined) option handler.
int(* delete)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for deleting an object.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void(* retrieve_regex)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex)
Callback for retrieving multiple objects using a regex on their id.
Structure used for observer invocations.
Type for default option handler for character array strings.
Type for default option handler for bools (ast_true/ast_false)
unsigned int caching
Wizard is acting as an object cache.
const char * type
Type of object being loaded.
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
static int bool_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for bools (ast_true/ast_false)
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
ao2_destructor_fn destructor
Optional object destructor.
#define OBJECT_FIELD_BUCKETS
Number of buckets for object fields (should be prime for performance reasons)
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
struct ao2_container * ast_sorcery_retrieve_by_prefix(const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
Retrieve multiple objects whose id begins with the specified prefix.
ast_sorcery_wizard_apply_flags
Wizard Apply Flags.
struct ast_taskprocessor * serializer
Serializer for observers.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
void *(* aco_type_item_alloc)(const char *category)
Allocate a configurable ao2 object.
static int int_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for signed integers.
static int stringfield_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for stringfields.
static int sorcery_wizard_update(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if a wizard has updated the object.
Structure for registered object type.
Asterisk JSON abstraction layer.
unsigned int read_only
Wizard is read_only.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Type for default option handler for unsigned integers.
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks)
Add a global observer to sorcery.
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching)
Internal function which creates an object type and adds a wizard mapping.
Interface for the sorcery instance observer.
Proxy object for sorcery.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
sorcery_diff_handler diff
Optional object diff callback.
Structure for registered object field.
static void sorcery_destructor(void *obj)
Destructor called when sorcery structure is destroyed.
struct ao2_container * fields
Object fields.
struct ast_variable * extended
Extended object fields.
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
unsigned int reload
Whether this is a reload or not.
int __aco_option_register(struct aco_info *info, const char *name, enum aco_matchtype match_type, struct aco_type **types, const char *default_val, enum aco_option_type type, aco_option_handler handler, unsigned int flags, unsigned int no_doc, size_t argc,...)
register a config option
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
Structure for internal sorcery object information.
aco_type_item_alloc item_alloc
int(* sorcery_diff_handler)(const void *original, const void *modified, struct ast_variable **changes)
A callback function for generating a changeset between two objects.
#define ast_debug(level,...)
Log a DEBUG message.
struct aco_type type
Type details.
Structure for passing load/reload details.
struct ast_variable * ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *new_var)
Appends a variable list to the end of another list.
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
static struct ast_threadpool * threadpool
Thread pool for observers.
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type, const char *field_name)
Determine if a particular object field has been registered with sorcery.
aco_option_type
The option types.
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static int sorcery_observers_notify_loaded(void *data)
Internal callback function which notifies observers that an object type has been loaded.
unsigned int reloadable
Specifies if object type is reloadable or not.
enum ast_sorcery_apply_result __ast_sorcery_apply_default(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data)
Apply default object wizard mappings.
sorcery_copy_handler copy
Optional object copy callback.
Configuration option-handling.
Structure which contains details about a sorcery object.
int(* sorcery_copy_handler)(const void *src, void *dst)
A callback function for copying the contents of one object to another.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
#define MAX_OBJECT_TYPE
Maximum size of an object type.
void(* retrieve_multiple)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
Optional callback for retrieving multiple objects using some optional field criteria.
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name, const char *data, unsigned int caching, int position)
Internal function which creates an object type and inserts a wizard mapping.
Support for dynamic strings.
struct aco_file * files[]
Structure for an internal wizard instance.
struct timeval created
Time that the object was created.
void(* force_reload)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for forcing a reload to occur, even if wizard has determined no changes...
#define ao2_unlink(container, obj)
Remove an object from a container.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
Interface for a sorcery object type observer.
Type for default option handler for bools (ast_true/ast_false)
static void sorcery_observer_invocation_destroy(void *obj)
Destructor for observer invocation.
static int sorcery_observer_notify_update(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object has been updated...
void(* ao2_destructor_fn)(void *vdoomed)
Typedef for an object destructor.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
Register a regex for multiple fields within an object.
static struct sorcery_test_observer observer
Global scope observer structure for testing.
sorcery_field_handler handler
Callback function for translation of a single value.
unsigned int ast_sorcery_object_has_dynamic_contents(const void *object)
Get whether an object contains dynamic contents or not.
struct ao2_container * types
Container for known object types.
struct ast_sorcery_object_wizards wizards
Wizard instances.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
void ast_sorcery_ref(struct ast_sorcery *sorcery)
Increase the reference count of a sorcery structure.
#define ao2_weakproxy_find(c, arg, flags, tag)
Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object...
char module_name[0]
The name of the module owning this sorcery instance.
AST_VECTOR_RW(ast_sorcery_object_wizards, struct ast_sorcery_object_wizard *)
Interface for a sorcery object type wizards.
A global observer wrapper.
sorcery_apply_handler apply
Optional object set apply callback.
static int sorcery_reloadable(const struct ast_sorcery *sorcery, const char *type)
Retrieves whether or not the type is reloadable.
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
#define ast_calloc(num, len)
A wrapper for calloc()
static void sorcery_cleanup(void)
Hashing and comparison functions for sorcery wizards.
static struct ao2_container * wizards
Registered sorcery wizards.
struct ao2_container * observers
Observers.
static int sorcery_observers_notify_update(void *data)
Internal callback function which notifies observers that an object has been updated.
Type for default option handler for doubles.
int ast_sorcery_wizard_observer_add(struct ast_sorcery_wizard *interface, const struct ast_sorcery_wizard_observer *callbacks)
Add an observer to a sorcery wizard.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects even if no changes determin...
Support for logging to various files, console and syslog Configuration in file logger.conf.
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Vector container support.
regex_t * name_regex
The compiled name regex if name is a regex.
An API for managing task processing threads that can be shared across modules.
struct ast_variable *(* sorcery_transform_handler)(struct ast_variable *set)
A callback function for performing a transformation on an object set.
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
sorcery_fields_handler multiple_handler
Callback function for translation of multiple values.
Structure used to handle boolean flags.
#define TYPE_BUCKETS
Number of buckets for types (should be prime for performance reasons)
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order...
#define INSTANCE_BUCKETS
Number of buckets for instances (should be prime for performance reasons)
struct aco_info * info
Configuration framework general information.
char name[MAX_OBJECT_FIELD]
Name of the field.
An instance observer wrapper.
#define ast_module_unref(mod)
Release a reference to the module.
static int sorcery_wizard_delete(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
Internal function which returns if a wizard has deleted the object.
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Interface for a sorcery wizard.
int __ast_sorcery_object_field_register(struct ast_sorcery *sorcery, const char *type, const char *name, const char *default_val, enum aco_option_type opt_type, aco_option_handler config_handler, sorcery_field_handler sorcery_handler, sorcery_fields_handler multiple_handler, unsigned int flags, unsigned int no_doc, unsigned int alias, size_t argc,...)
Register a field within an object.
static void sorcery_proxy_cb(void *weakproxy, void *data)
Hashing function for sorcery types.
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
void * data
Unique data for the wizard.
static void sorcery_object_wizard_destructor(void *obj)
Object wizard destructor.
The arg parameter is an object of the same type.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
A ast_taskprocessor structure is a singleton by name.
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
int __ast_sorcery_object_type_remove_wizard(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args)
Remove an object wizard mapping.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
Structure for a wizard instance which operates on objects.
Type information about a category-level configurable object.
Interface for the sorcery wizard observer.
An opaque threadpool structure.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
const char * ast_sorcery_object_get_extended(const void *object, const char *name)
Get an extended field value from a sorcery object.
void ast_sorcery_force_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects, even if no changes determined.
int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
Create a changeset of two objects.
struct ast_variable * ast_sorcery_objectset_create2(const struct ast_sorcery *sorcery, const void *object, enum ast_sorcery_field_handler_flags flags)
Create an object set (KVP list) for an object.
#define WIZARD_BUCKETS
Number of buckets for wizards (should be prime for performance reasons)
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Try both handlers, string first.
unsigned int has_dynamic_contents
Whether this object has dynamic contents or not.
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
struct ast_sorcery * ast_sorcery_retrieve_by_module_name(const char *module_name)
Search function for sorcery instances.
int __ast_sorcery_remove_wizard_mapping(struct ast_sorcery *sorcery, const char *type, const char *module, const char *name)
Internal function removes a wizard mapping.
void(* load)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for loading persistent objects.
Abstract JSON element (object, array, string, int, ...).
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Type for default option handler for stringfields.
A wizard observer wrapper.
int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
int ast_sorcery_object_id_hash(const void *obj, int flags)
ao2 object hasher based on sorcery id.
int(* is_stale)(const struct ast_sorcery *sorcery, void *data, void *object)
Callback for whether or not the wizard believes the object is stale.
static struct ast_sorcery_object_type * sorcery_object_type_alloc(const char *type, const char *module)
Internal function which allocates an object type structure.
void(* reload)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for reloading persistent objects.
Search option field mask.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
struct aco_type * types[]
int __ast_sorcery_wizard_register(const struct ast_sorcery_wizard *interface, struct ast_module *module)
Register a sorcery wizard.
Type for default option handler for signed integers.
int aco_process_var(struct aco_type *type, const char *cat, struct ast_variable *var, void *obj)
Parse a single ast_variable and apply it to an object.
static int sorcery_observer_notify_delete(void *obj, void *arg, int flags)
Internal callback function which notifies an individual observer that an object has been deleted...
Asterisk module definitions.
void ast_sorcery_object_set_diff_handler(struct ast_sorcery *sorcery, const char *type, sorcery_diff_handler diff)
Set the diff handler for an object type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static int double_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj)
Default option handler for doubles.
struct ast_sorcery_object_type * object_type
Pointer to the object type.
int ast_sorcery_init(void)
Compare function for sorcery instances.
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void(* updated)(const void *object)
Callback for when an object is updated.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
char name[MAX_OBJECT_TYPE]
Unique name of the object type.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
static int sorcery_observers_notify_delete(void *data)
Internal callback function which notifies observers that an object has been deleted.
char type[MAX_OBJECT_TYPE]
Type of object.
Sorcery Data Access Layer API.
static int sorcery_observers_notify_create(void *data)
Internal callback function which notifies observers that an object has been created.
const struct timeval ast_sorcery_object_get_created(const void *object)
Get when the sorcery object was created.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
const struct ast_sorcery_observer * callbacks
Pointer to the observer implementation.
struct ast_json * ast_sorcery_objectset_json_create(const struct ast_sorcery *sorcery, const void *object)
Create an object set in JSON format for an object.
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
void ast_sorcery_object_set_has_dynamic_contents(const void *object)
Set the dynamic contents flag on a sorcery object.
#define ao2_link(container, obj)
Add an object to a container.