Asterisk - The Open Source Telephony Project  GIT-master-8beac82
Data Structures | Macros | Functions | Variables
sorcery.c File Reference

Sorcery Data Access Layer API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/sorcery.h"
#include "asterisk/astobj2.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/strings.h"
#include "asterisk/config_options.h"
#include "asterisk/netsock2.h"
#include "asterisk/module.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/threadpool.h"
#include "asterisk/json.h"
#include "asterisk/vector.h"

Go to the source code of this file.

Data Structures

struct  ast_sorcery
 Full structure for sorcery. More...
 
struct  ast_sorcery_internal_wizard
 Structure for an internal wizard instance. More...
 
struct  ast_sorcery_object
 Structure for internal sorcery object information. More...
 
struct  ast_sorcery_object_field
 Structure for registered object field. More...
 
struct  ast_sorcery_object_type
 Structure for registered object type. More...
 
struct  ast_sorcery_object_type_observer
 Structure for registered object type observer. More...
 
struct  ast_sorcery_object_wizard
 Structure for a wizard instance which operates on objects. More...
 
struct  sorcery_details
 Structure used when calling create, update, or delete. More...
 
struct  sorcery_global_observer
 A global observer wrapper. More...
 
struct  sorcery_instance_observer
 An instance observer wrapper. More...
 
struct  sorcery_load_details
 Structure for passing load/reload details. More...
 
struct  sorcery_observer_invocation
 Structure used for observer invocations. More...
 
struct  sorcery_proxy
 Proxy object for sorcery. More...
 
struct  sorcery_wizard_observer
 A wizard observer wrapper. More...
 

Macros

#define INITIAL_WIZARD_VECTOR_SIZE   5
 
#define INSTANCE_BUCKETS   17
 Number of buckets for instances (should be prime for performance reasons) More...
 
#define MAX_REGEX_ERROR_LEN   128
 
#define NOTIFY_GENERIC_OBSERVERS(container, type, callback, ...)
 
#define NOTIFY_GLOBAL_OBSERVERS(container, callback, ...)   NOTIFY_GENERIC_OBSERVERS(container, sorcery_global_observer, callback, __VA_ARGS__)
 
#define NOTIFY_INSTANCE_OBSERVERS(container, callback, ...)   NOTIFY_GENERIC_OBSERVERS(container, sorcery_instance_observer, callback, __VA_ARGS__)
 
#define NOTIFY_WIZARD_OBSERVERS(container, callback, ...)   NOTIFY_GENERIC_OBSERVERS(container, sorcery_wizard_observer, callback, __VA_ARGS__)
 
#define OBJECT_FIELD_BUCKETS   29
 Number of buckets for object fields (should be prime for performance reasons) More...
 
#define TYPE_BUCKETS   53
 Number of buckets for types (should be prime for performance reasons) More...
 
#define WIZARD_BUCKETS   7
 Number of buckets for wizards (should be prime for performance reasons) More...
 
#define WIZARD_COMPARE(a, b)   ((a)->wizard == (b))
 
#define WIZARD_NAME_COMPARE(a, b)   (strcmp((a)->wizard->callbacks.name, (b)) == 0)
 

Functions

enum ast_sorcery_apply_result __ast_sorcery_apply_config (struct ast_sorcery *sorcery, const char *name, const char *module)
 Apply configured wizard mappings. More...
 
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. More...
 
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping (struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, unsigned int caching)
 Internal function which creates an object type and adds a wizard mapping. More...
 
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping (struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, unsigned int caching, int position)
 Internal function which creates an object type and inserts a wizard mapping. More...
 
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. More...
 
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. More...
 
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 information. More...
 
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. More...
 
struct ast_sorcery__ast_sorcery_open (const char *module_name, const char *file, int line, const char *func)
 Open a new sorcery structure. More...
 
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. More...
 
int __ast_sorcery_wizard_register (const struct ast_sorcery_wizard *interface, struct ast_module *module)
 Register a sorcery wizard. More...
 
void * ast_sorcery_alloc (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Allocate an object. More...
 
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. More...
 
void * ast_sorcery_copy (const struct ast_sorcery *sorcery, const void *object)
 Create a copy of an object. More...
 
int ast_sorcery_create (const struct ast_sorcery *sorcery, void *object)
 Create and potentially persist an object using an available wizard. More...
 
int ast_sorcery_delete (const struct ast_sorcery *sorcery, void *object)
 Delete an object. More...
 
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. More...
 
void ast_sorcery_force_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects, even if no changes determined. More...
 
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 determined. More...
 
void * ast_sorcery_generic_alloc (size_t size, ao2_destructor_fn destructor)
 Allocate a generic sorcery capable object. More...
 
const char * ast_sorcery_get_module (const struct ast_sorcery *sorcery)
 Get the module that has opened the provided sorcery instance. More...
 
struct ast_sorcery_object_typeast_sorcery_get_object_type (const struct ast_sorcery *sorcery, const char *type)
 Get the sorcery object type given a type name. More...
 
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. More...
 
int ast_sorcery_get_wizard_mapping_count (struct ast_sorcery *sorcery, const char *type)
 Return the number of wizards mapped to an object type. More...
 
int ast_sorcery_global_observer_add (const struct ast_sorcery_global_observer *callbacks)
 Add a global observer to sorcery. More...
 
void ast_sorcery_global_observer_remove (const struct ast_sorcery_global_observer *callbacks)
 Remove a global observer from sorcery. More...
 
int ast_sorcery_init (void)
 Compare function for sorcery instances. More...
 
int ast_sorcery_instance_observer_add (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Add an observer to a sorcery instance. More...
 
void ast_sorcery_instance_observer_remove (struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
 Remove an observer from a sorcery instance. More...
 
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. More...
 
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. More...
 
void ast_sorcery_load (const struct ast_sorcery *sorcery)
 Inform any wizards to load persistent objects. More...
 
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. More...
 
void * ast_sorcery_lockable_alloc (size_t size, ao2_destructor_fn destructor, void *lockobj)
 Allocate a generic sorcery capable object with locking. More...
 
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. More...
 
const struct timeval ast_sorcery_object_get_created (const void *object)
 Get when the socery object was created. More...
 
const char * ast_sorcery_object_get_extended (const void *object, const char *name)
 Get an extended field value from a sorcery object. More...
 
const char * ast_sorcery_object_get_id (const void *object)
 Get the unique identifier of a sorcery object. More...
 
const char * ast_sorcery_object_get_type (const void *object)
 Get the type of a sorcery object. More...
 
unsigned int ast_sorcery_object_has_dynamic_contents (const void *object)
 Get whether an object contains dynamic contents or not. More...
 
int ast_sorcery_object_id_compare (void *obj, void *arg, int flags)
 ao2 object comparator based on sorcery id. More...
 
int ast_sorcery_object_id_hash (const void *obj, int flags)
 ao2 object hasher based on sorcery id. More...
 
int ast_sorcery_object_id_sort (const void *obj, const void *arg, int flags)
 ao2 object sorter based on sorcery id. More...
 
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. More...
 
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. More...
 
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. More...
 
int ast_sorcery_object_set_extended (const void *object, const char *name, const char *value)
 Set an extended field value on a sorcery object. More...
 
void ast_sorcery_object_set_has_dynamic_contents (const void *object)
 Set the dynamic contents flag on a sorcery object. More...
 
int ast_sorcery_object_unregister (struct ast_sorcery *sorcery, const char *type)
 Unregister an object type. More...
 
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. More...
 
struct ast_variableast_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. More...
 
struct ast_jsonast_sorcery_objectset_json_create (const struct ast_sorcery *sorcery, const void *object)
 Create an object set in JSON format for an object. More...
 
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. More...
 
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. More...
 
void ast_sorcery_ref (struct ast_sorcery *sorcery)
 Increase the reference count of a sorcery structure. More...
 
void ast_sorcery_reload (const struct ast_sorcery *sorcery)
 Inform any wizards to reload persistent objects. More...
 
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. More...
 
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. More...
 
void * ast_sorcery_retrieve_by_id (const struct ast_sorcery *sorcery, const char *type, const char *id)
 Retrieve an object using its unique identifier. More...
 
struct ast_sorceryast_sorcery_retrieve_by_module_name (const char *module_name)
 Search function for sorcery instances. More...
 
struct ao2_containerast_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. More...
 
struct ao2_containerast_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. More...
 
int ast_sorcery_update (const struct ast_sorcery *sorcery, void *object)
 Update an object. More...
 
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. More...
 
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. More...
 
int ast_sorcery_wizard_unregister (const struct ast_sorcery_wizard *interface)
 Unregister a sorcery wizard. More...
 
 AST_VECTOR_RW (ast_sorcery_object_wizards, struct ast_sorcery_object_wizard *)
 Interface for a sorcery object type wizards. More...
 
static int bool_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int chararray_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int codec_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int double_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static struct ast_variableget_multiple_fields_as_var_list (const void *object, struct ast_sorcery_object_field *object_field)
 
static struct ast_variableget_single_field_as_var_list (const void *object, struct ast_sorcery_object_field *object_field)
 
static int int_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int is_registered_cb (void *obj, void *arg, int flags)
 
static int sockaddr_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int sorcery_cache_create (void *obj, void *arg, int flags)
 Internal function used to create an object in caching wizards. More...
 
static void sorcery_cleanup (void)
 Hashing and comparison functions for sorcery wizards. More...
 
static void sorcery_destructor (void *obj)
 Destructor called when sorcery structure is destroyed. More...
 
static int sorcery_extended_config_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int sorcery_extended_fields_handler (const void *obj, struct ast_variable **fields)
 
static sorcery_field_handler sorcery_field_default_handler (enum aco_option_type type)
 
static int sorcery_generic_observer_remove (void *obj, void *arg, int flags)
 Internal callback function for removing a generic observer. More...
 
static void sorcery_internal_wizard_destructor (void *obj)
 
static void sorcery_object_destructor (void *object)
 
static void sorcery_object_field_destructor (void *obj)
 
static int sorcery_object_load (void *obj, void *arg, int flags)
 
static struct ast_sorcery_object_typesorcery_object_type_alloc (const char *type, const char *module)
 Internal function which allocates an object type structure. More...
 
static void sorcery_object_type_destructor (void *obj)
 Destructor function for object types. More...
 
static void sorcery_object_wizard_destructor (void *obj)
 Object wizard destructor. More...
 
static struct sorcery_observer_invocationsorcery_observer_invocation_alloc (struct ast_sorcery_object_type *object_type, void *object)
 Allocator function for observer invocation. More...
 
static void sorcery_observer_invocation_destroy (void *obj)
 Destructor for observer invocation. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static int sorcery_observer_remove (void *obj, void *arg, int flags)
 Internal callback function for removing an observer. More...
 
static int sorcery_observers_notify_create (void *data)
 Internal callback function which notifies observers that an object has been created. More...
 
static int sorcery_observers_notify_delete (void *data)
 Internal callback function which notifies observers that an object has been deleted. More...
 
static int sorcery_observers_notify_loaded (void *data)
 Internal callback function which notifies observers that an object type has been loaded. More...
 
static int sorcery_observers_notify_update (void *data)
 Internal callback function which notifies observers that an object has been updated. More...
 
static void sorcery_proxy_cb (void *weakproxy, void *data)
 Hashing function for sorcery types. More...
 
static int sorcery_reloadable (const struct ast_sorcery *sorcery, const char *type)
 Retrieves whether or not the type is reloadable. More...
 
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. More...
 
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. More...
 
static int sorcery_wizard_load (void *obj, void *arg, int flags)
 
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. More...
 
static int stringfield_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int uint_handler_fn (const void *obj, const intptr_t *args, char **buf)
 
static int yesno_handler_fn (const void *obj, const intptr_t *args, char **buf)
 

Variables

static struct ao2_containerinstances
 Registered sorcery instances. More...
 
struct ao2_containerobservers
 Registered global observers. More...
 
static struct ast_threadpoolthreadpool
 Thread pool for observers. More...
 
static struct ao2_containerwizards
 Registered sorcery wizards. More...
 

Detailed Description

Sorcery Data Access Layer API.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file sorcery.c.

Macro Definition Documentation

◆ INITIAL_WIZARD_VECTOR_SIZE

#define INITIAL_WIZARD_VECTOR_SIZE   5

◆ INSTANCE_BUCKETS

#define INSTANCE_BUCKETS   17

Number of buckets for instances (should be prime for performance reasons)

Definition at line 57 of file sorcery.c.

Referenced by ast_sorcery_init().

◆ MAX_REGEX_ERROR_LEN

#define MAX_REGEX_ERROR_LEN   128

◆ NOTIFY_GENERIC_OBSERVERS

#define NOTIFY_GENERIC_OBSERVERS (   container,
  type,
  callback,
  ... 
)

Definition at line 62 of file sorcery.c.

◆ NOTIFY_GLOBAL_OBSERVERS

#define NOTIFY_GLOBAL_OBSERVERS (   container,
  callback,
  ... 
)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_global_observer, callback, __VA_ARGS__)

◆ NOTIFY_INSTANCE_OBSERVERS

#define NOTIFY_INSTANCE_OBSERVERS (   container,
  callback,
  ... 
)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_instance_observer, callback, __VA_ARGS__)

◆ NOTIFY_WIZARD_OBSERVERS

#define NOTIFY_WIZARD_OBSERVERS (   container,
  callback,
  ... 
)    NOTIFY_GENERIC_OBSERVERS(container, sorcery_wizard_observer, callback, __VA_ARGS__)

Definition at line 82 of file sorcery.c.

Referenced by sorcery_wizard_load().

◆ OBJECT_FIELD_BUCKETS

#define OBJECT_FIELD_BUCKETS   29

Number of buckets for object fields (should be prime for performance reasons)

Definition at line 60 of file sorcery.c.

Referenced by sorcery_object_type_alloc().

◆ TYPE_BUCKETS

#define TYPE_BUCKETS   53

Number of buckets for types (should be prime for performance reasons)

Definition at line 54 of file sorcery.c.

Referenced by __ast_sorcery_open().

◆ WIZARD_BUCKETS

#define WIZARD_BUCKETS   7

Number of buckets for wizards (should be prime for performance reasons)

Definition at line 51 of file sorcery.c.

Referenced by ast_sorcery_init().

◆ WIZARD_COMPARE

#define WIZARD_COMPARE (   a,
  b 
)    ((a)->wizard == (b))

◆ WIZARD_NAME_COMPARE

#define WIZARD_NAME_COMPARE (   a,
  b 
)    (strcmp((a)->wizard->callbacks.name, (b)) == 0)

Function Documentation

◆ __ast_sorcery_apply_config()

enum ast_sorcery_apply_result __ast_sorcery_apply_config ( struct ast_sorcery sorcery,
const char *  name,
const char *  module 
)

Apply configured wizard mappings.

Parameters
sorceryPointer to a sorcery structure
nameName of the category to use within the configuration file, normally the module name
moduleThe module name (AST_MODULE)

This function is called automatically by __ast_sorcery_open() using the module name as the configuration category. The only reason you should call this function is if your module wishes to apply configuration from additional sections of sorcery.conf.

If a configuration section attempts to apply the same sorcery wizard to an object type more than once, the wizard will only be applied one time.

Returns
What happened when attempting to apply the config.

Definition at line 985 of file sorcery.c.

References __ast_sorcery_apply_wizard_mapping(), ast_config_destroy(), ast_config_load2(), ast_free, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_NO_CONFIGURATION, AST_SORCERY_APPLY_SUCCESS, ast_strdup, ast_strlen_zero(), ast_variable_browse(), config, CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, RAII_VAR, strsep(), type, and ast_variable::value.

Referenced by __ast_sorcery_open().

986 {
987  struct ast_flags flags = { 0 };
988  struct ast_config *config = ast_config_load2("sorcery.conf", "sorcery", flags);
989  struct ast_variable *mapping;
990  int res = AST_SORCERY_APPLY_SUCCESS;
991 
992  if (!config) {
994  }
995 
996  if (config == CONFIG_STATUS_FILEINVALID) {
997  return AST_SORCERY_APPLY_FAIL;
998  }
999 
1000  for (mapping = ast_variable_browse(config, name); mapping; mapping = mapping->next) {
1001  RAII_VAR(char *, mapping_name, ast_strdup(mapping->name), ast_free);
1002  RAII_VAR(char *, mapping_value, ast_strdup(mapping->value), ast_free);
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;
1008 
1009  /* If no object type or wizard exists just skip, nothing we can do */
1010  if (ast_strlen_zero(type) || ast_strlen_zero(wizard)) {
1011  continue;
1012  }
1013 
1014  /* If the wizard is configured as a cache treat it as such */
1015  if (!ast_strlen_zero(options) && strstr(options, "cache")) {
1016  caching = 1;
1017  }
1018 
1019  /* Any error immediately causes us to stop */
1020  if (__ast_sorcery_apply_wizard_mapping(sorcery, type, module, wizard, data, caching) == AST_SORCERY_APPLY_FAIL) {
1021  res = AST_SORCERY_APPLY_FAIL;
1022  break;
1023  }
1024  }
1025 
1026  ast_config_destroy(config);
1027 
1028  return res;
1029 }
struct ast_variable * next
static const char type[]
Definition: chan_ooh323.c:109
static const char name[]
Definition: format_mp3.c:68
static const char config[]
Definition: chan_ooh323.c:111
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define CONFIG_STATUS_FILEINVALID
unsigned int flags
Definition: utils.h:200
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3154
Structure for variables, used for configurations and for channel variables.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, unsigned int caching)
Internal function which creates an object type and adds a wizard mapping.
Definition: sorcery.c:977
#define ast_free(a)
Definition: astmm.h:182
Structure used to handle boolean flags.
Definition: utils.h:199
char * strsep(char **str, const char *delims)
static struct test_options options

◆ __ast_sorcery_apply_default()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object to apply to
moduleThe name of the module, typically AST_MODULE
nameName of the wizard to use
dataData to be passed to wizard
Returns
What occurred when applying the default
Note
This should be called after applying configuration sourced mappings
Only a single default can exist per object type

Definition at line 1031 of file sorcery.c.

References __ast_sorcery_apply_wizard_mapping(), ao2_cleanup, ao2_find, AST_SORCERY_APPLY_DEFAULT_UNNECESSARY, OBJ_KEY, RAII_VAR, and ast_sorcery::types.

1032 {
1033  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1034 
1035  /* Defaults can not be added if any existing mapping exists */
1036  if (object_type) {
1038  }
1039 
1040  return __ast_sorcery_apply_wizard_mapping(sorcery, type, module, name, data, 0);
1041 }
static const char type[]
Definition: chan_ooh323.c:109
static const char name[]
Definition: format_mp3.c:68
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, unsigned int caching)
Internal function which creates an object type and adds a wizard mapping.
Definition: sorcery.c:977
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ __ast_sorcery_apply_wizard_mapping()

enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping ( struct ast_sorcery sorcery,
const char *  object_type_name,
const char *  module,
const char *  wizard_type_name,
const char *  wizard_args,
unsigned int  caching 
)

Internal function which creates an object type and adds a wizard mapping.

Apply additional object wizard mappings.

Definition at line 977 of file sorcery.c.

References __ast_sorcery_insert_wizard_mapping(), and AST_SORCERY_WIZARD_POSITION_LAST.

Referenced by __ast_sorcery_apply_config(), and __ast_sorcery_apply_default().

980 {
981  return __ast_sorcery_insert_wizard_mapping(sorcery, object_type_name, module, wizard_type_name,
982  wizard_args, caching, AST_SORCERY_WIZARD_POSITION_LAST);
983 }
enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping(struct ast_sorcery *sorcery, const char *object_type_name, const char *module, const char *wizard_type_name, const char *wizard_args, unsigned int caching, int position)
Internal function which creates an object type and inserts a wizard mapping.
Definition: sorcery.c:967

◆ __ast_sorcery_insert_wizard_mapping()

enum ast_sorcery_apply_result __ast_sorcery_insert_wizard_mapping ( struct ast_sorcery sorcery,
const char *  object_type_name,
const char *  module,
const char *  wizard_type_name,
const char *  wizard_args,
unsigned int  caching,
int  position 
)

Internal function which creates an object type and inserts a wizard mapping.

Insert an additional object wizard mapping at a specific position in the wizard list.

Definition at line 967 of file sorcery.c.

References __ast_sorcery_object_type_insert_wizard(), AST_SORCERY_WIZARD_APPLY_CACHING, AST_SORCERY_WIZARD_APPLY_NONE, and NULL.

Referenced by __ast_sorcery_apply_wizard_mapping().

970 {
971  return __ast_sorcery_object_type_insert_wizard(sorcery, object_type_name, module, wizard_type_name,
973  position, NULL, NULL);
974 }
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...
Definition: sorcery.c:869
#define NULL
Definition: resample.c:96

◆ __ast_sorcery_object_field_register()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object
nameName of the field
default_valDefault value of the field
config_handlerA custom handler for translating the string representation of the fields
sorcery_handlerA custom handler for translating the native representation of the fields
multiple_handlerA custom handler for translating the native representation of the fields
opt_typeOption type
flagsOption type specific flags
no_docField should not be documented
aliasInterpret and apply field value only
Return values
0success
-1failure

Definition at line 1192 of file sorcery.c.

References __aco_option_register(), ACO_EXACT, ao2_alloc, ao2_cleanup, ao2_find, ao2_link, args, ast_assert, ast_copy_string(), ast_sorcery_object_field::multiple_handler, NULL, OBJ_KEY, RAII_VAR, sorcery_field_default_handler(), and ast_sorcery::types.

1194 {
1195  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1196  RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1197  int pos;
1198  va_list args;
1199 
1200  if (!strcmp(type, "id") || !object_type || !object_type->type.item_alloc) {
1201  return -1;
1202  }
1203 
1204  if (!sorcery_handler) {
1205  sorcery_handler = sorcery_field_default_handler(opt_type);
1206  }
1207 
1208  if (!(object_field = ao2_alloc(sizeof(*object_field) + argc * sizeof(object_field->args[0]), NULL))) {
1209  return -1;
1210  }
1211 
1212  ast_copy_string(object_field->name, name, sizeof(object_field->name));
1213  object_field->handler = sorcery_handler;
1214  object_field->multiple_handler = multiple_handler;
1215 
1216  va_start(args, argc);
1217  for (pos = 0; pos < argc; pos++) {
1218  object_field->args[pos] = va_arg(args, size_t);
1219  }
1220  va_end(args);
1221 
1222  if (!alias) {
1223  ao2_link(object_type->fields, object_field);
1224  }
1225 
1226  /* TODO: Improve this hack */
1227  if (!argc) {
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]);
1238  } else {
1239  ast_assert(0); /* The hack... she does us no good for this */
1240  }
1241 
1242  return 0;
1243 }
static const char type[]
Definition: chan_ooh323.c:109
static const char name[]
Definition: format_mp3.c:68
#define OBJ_KEY
Definition: astobj2.h:1155
#define ast_assert(a)
Definition: utils.h:710
const char * args
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure for registered object field.
Definition: sorcery.c:205
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
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type type)
Definition: sorcery.c:341
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ __ast_sorcery_object_register()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object
hiddenAll objects of this type are internal and should not be manipulated by users
reloadableAll objects of this type are reloadable
allocRequired object allocation callback
transformOptional transformation callback
applyOptional object set apply callback
Note
In general, this function should not be used directly. One of the various macro'd versions should be used instead.
Return values
0success
-1failure

Definition at line 1080 of file sorcery.c.

References aco_info_init(), ACO_ITEM, ao2_cleanup, ao2_find, ast_sorcery_object_type::apply, ast_sorcery_object_fields_register(), ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, OBJ_KEY, ast_sorcery::observers, RAII_VAR, ast_sorcery_object_type::reloadable, sorcery_extended_config_handler(), sorcery_extended_fields_handler(), ast_sorcery_object_type::transform, and ast_sorcery::types.

1081 {
1082  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1083 
1084  if (!object_type || object_type->type.item_alloc) {
1085  return -1;
1086  }
1087 
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;
1093 
1094  object_type->reloadable = reloadable;
1095  object_type->transform = transform;
1096  object_type->apply = apply;
1097  object_type->file->types[0] = &object_type->type;
1098  object_type->file->types[1] = NULL;
1099 
1100  if (aco_info_init(object_type->info)) {
1101  return -1;
1102  }
1103 
1105  return -1;
1106  }
1107 
1108  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, object_type_registered,
1109  sorcery->module_name, sorcery, type);
1110 
1111  return 0;
1112 }
static const char type[]
Definition: chan_ooh323.c:109
static int sorcery_extended_fields_handler(const void *obj, struct ast_variable **fields)
Definition: sorcery.c:1048
#define OBJ_KEY
Definition: astobj2.h:1155
static int sorcery_extended_config_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: sorcery.c:1043
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
#define NULL
Definition: resample.c:96
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
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.
Definition: sorcery.c:1160
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition: sorcery.c:79

◆ __ast_sorcery_object_type_insert_wizard()

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 information.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to apply to
moduleThe name of the module, typically AST_MODULE
wizard_type_nameName of the wizard type to use
wizard_argsOpaque string to be passed to the wizard May be NULL but see note below
flagsOne or more of enum ast_sorcery_wizard_apply_flags
positionAn index to insert to or one of ast_sorcery_wizard_position
[out]wizardA variable to receive a pointer to the ast_sorcery_wizard structure. May be NULL if not needed.
[out]wizard_dataA variable to receive a pointer to the wizard's internal data. May be NULL if not needed.
Returns
What occurred when applying the mapping
Note
This should be called after applying default mappings
Although wizard_args is an optional parameter it is highly recommended to supply one. If you use the AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE flag, and you intend to ever remove a wizard mapping, you'll need wizard_args to remove specific instances of a wizard type.

Definition at line 869 of file sorcery.c.

References ast_sorcery_object_wizard::allow_duplicates, ao2_alloc, ao2_bump, ao2_cleanup, ao2_find, ao2_link, ast_debug, ast_log, ast_module_running_ref, ast_module_unref, AST_SORCERY_APPLY_DUPLICATE, AST_SORCERY_APPLY_FAIL, AST_SORCERY_APPLY_SUCCESS, AST_SORCERY_WIZARD_APPLY_ALLOW_DUPLICATE, AST_SORCERY_WIZARD_APPLY_CACHING, AST_SORCERY_WIZARD_APPLY_READONLY, AST_SORCERY_WIZARD_POSITION_LAST, ast_strlen_zero(), AST_VECTOR_GET_CMP, AST_VECTOR_INSERT_AT, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, AST_VECTOR_SIZE, LOG_ERROR, LOG_WARNING, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, NULL, OBJ_KEY, ast_sorcery::observers, RAII_VAR, S_OR, sorcery_object_type_alloc(), sorcery_object_wizard_destructor(), ast_sorcery::types, and WIZARD_COMPARE.

Referenced by __ast_sorcery_insert_wizard_mapping().

873 {
874  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, object_type_name, OBJ_KEY), ao2_cleanup);
875  RAII_VAR(struct ast_sorcery_internal_wizard *, internal_wizard, ao2_find(wizards, wizard_type_name, OBJ_KEY), ao2_cleanup);
876  RAII_VAR(struct ast_sorcery_object_wizard *, object_wizard, NULL, ao2_cleanup);
877  int created = 0;
878 
879  object_wizard = ao2_alloc(sizeof(*object_wizard)
880  + (ast_strlen_zero(wizard_args) ? 0 : strlen(wizard_args) + 1),
882 
883  if (!object_wizard) {
884  return AST_SORCERY_APPLY_FAIL;
885  }
886 
887  if (!internal_wizard
888  || internal_wizard->callbacks.module != ast_module_running_ref(internal_wizard->callbacks.module)) {
890  "Wizard '%s' could not be applied to object type '%s' as it was not found\n",
891  wizard_type_name, object_type_name);
892  return AST_SORCERY_APPLY_FAIL;
893  }
894 
895  if (!object_type) {
896  if (!(object_type = sorcery_object_type_alloc(object_type_name, module))) {
897  ast_module_unref(internal_wizard->callbacks.module);
898  return AST_SORCERY_APPLY_FAIL;
899  }
900  created = 1;
901  }
902 
903  AST_VECTOR_RW_WRLOCK(&object_type->wizards);
904  if (!created) {
905  struct ast_sorcery_object_wizard *found;
906 
907 #define WIZARD_COMPARE(a, b) ((a)->wizard == (b))
908  found = AST_VECTOR_GET_CMP(&object_type->wizards, internal_wizard, WIZARD_COMPARE);
909 #undef WIZARD_COMPARE
910  if (found
912  ast_debug(1, "Wizard %s already applied to object type %s\n",
913  internal_wizard->callbacks.name, object_type->name);
914  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
915  ast_module_unref(internal_wizard->callbacks.module);
917  }
918  }
919 
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, ""));
925  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
926  ast_module_unref(internal_wizard->callbacks.module);
927  return AST_SORCERY_APPLY_FAIL;
928  }
929 
930  object_wizard->wizard = ao2_bump(internal_wizard);
931  object_wizard->caching = !!(flags & AST_SORCERY_WIZARD_APPLY_CACHING);
932  object_wizard->read_only = !!(flags & AST_SORCERY_WIZARD_APPLY_READONLY);
933  if (wizard_args) {
934  strcpy(object_wizard->wizard_args, wizard_args); /* Safe */
935  }
936 
937  if (position == AST_SORCERY_WIZARD_POSITION_LAST) {
938  position = AST_VECTOR_SIZE(&object_type->wizards);
939  }
940 
941  if (AST_VECTOR_INSERT_AT(&object_type->wizards, position, object_wizard) != 0) {
942  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
943  return AST_SORCERY_APPLY_FAIL;
944  }
945  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
946  ao2_bump(object_wizard);
947 
948  if (created) {
949  ao2_link(sorcery->types, object_type);
950  }
951 
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);
955 
956  if (wizard) {
957  *wizard = &internal_wizard->callbacks;
958  }
959  if (wizard_data) {
960  *wizard_data = object_wizard->data;
961  }
962 
964 }
char wizard_args[0]
Wizard arguments.
Definition: sorcery.c:120
unsigned int allow_duplicates
Wizard allows others of the same type.
Definition: sorcery.c:117
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define LOG_WARNING
Definition: logger.h:274
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define LOG_ERROR
Definition: logger.h:285
Structure for an internal wizard instance.
Definition: sorcery.c:89
#define WIZARD_COMPARE(a, b)
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:890
static struct ao2_container * wizards
Registered sorcery wizards.
Definition: sorcery.c:257
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:733
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
static void sorcery_object_wizard_destructor(void *obj)
Object wizard destructor.
Definition: sorcery.c:762
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:338
static struct ast_sorcery_object_type * sorcery_object_type_alloc(const char *type, const char *module)
Internal function which allocates an object type structure.
Definition: sorcery.c:700
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition: sorcery.c:79
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ __ast_sorcery_object_type_remove_wizard()

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.

Since
13.26.0
16.3.0
Parameters
sorceryPointer to a sorcery structure
object_type_nameName of the object type to remove from
moduleThe name of the module, typically AST_MODULE
wizard_type_nameThe name of the of the wizard type to remove
wizard_argsOpaque string originally passed to the wizard
Return values
0success
-1failure
Note
If there were multiple instances of the same wizard type added to this object type without using wizard_args, then only the first wizard matching wizard_type will be removed.

Definition at line 820 of file sorcery.c.

References ao2_cleanup, ao2_find, AST_VECTOR_GET, AST_VECTOR_REMOVE_ORDERED, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_wizard::name, OBJ_SEARCH_KEY, RAII_VAR, S_OR, ast_sorcery::types, ast_sorcery_object_wizard::wizard, and ast_sorcery_object_wizard::wizard_args.

823 {
824  RAII_VAR(struct ast_sorcery_object_type *, object_type,
825  ao2_find(sorcery->types, object_type_name, OBJ_SEARCH_KEY), ao2_cleanup);
826  int res = -1;
827  int i;
828 
829  if (!object_type) {
830  return res;
831  }
832 
833  AST_VECTOR_RW_WRLOCK(&object_type->wizards);
834  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
835  struct ast_sorcery_object_wizard *wizard = AST_VECTOR_GET(&object_type->wizards, i);
836 
837  if (strcmp(wizard->wizard->callbacks.name, wizard_type_name) == 0
838  && strcmp(S_OR(wizard->wizard_args, ""), S_OR(wizard_args, "")) == 0) {
839  ao2_cleanup(AST_VECTOR_REMOVE_ORDERED(&object_type->wizards, i));
840  res = 0;
841  break;
842  }
843  }
844  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
845 
846  return res;
847 }
char wizard_args[0]
Wizard arguments.
Definition: sorcery.c:120
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
const char * name
Name of the wizard.
Definition: sorcery.h:278
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
Definition: vector.h:448
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:890
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ __ast_sorcery_open()

struct ast_sorcery* __ast_sorcery_open ( const char *  module,
const char *  file,
int  line,
const char *  func 
)

Open a new sorcery structure.

Parameters
moduleThe module name (AST_MODULE)

When called, this will automatically also call __ast_sorcery_apply_config() with the module name as the configuration section.

Return values
non-NULLsuccess
NULLif allocation failed

Definition at line 601 of file sorcery.c.

References __ao2_alloc(), __ao2_weakproxy_find(), __ast_sorcery_apply_config(), AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_hash, ao2_container_alloc_list, ao2_link_flags, ao2_ref, ao2_t_weakproxy_alloc, ao2_t_weakproxy_set_object, ao2_unlock, ao2_weakproxy_subscribe(), ao2_wrlock, ast_assert, ast_log, AST_SORCERY_APPLY_FAIL, LOG_ERROR, sorcery_proxy::module_name, ast_sorcery::module_name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_NOLOCK, OBJ_SEARCH_KEY, ast_sorcery::observers, sorcery, sorcery_destructor(), sorcery_proxy_cb(), TYPE_BUCKETS, and ast_sorcery::types.

602 {
603  struct sorcery_proxy *proxy;
604  struct ast_sorcery *sorcery;
605 
607 
610  __PRETTY_FUNCTION__, file, line, func);
611  if (sorcery) {
613 
614  return sorcery;
615  }
616 
617  proxy = ao2_t_weakproxy_alloc(sizeof(*proxy) + strlen(module_name) + 1, NULL, module_name);
618  if (!proxy) {
619  goto failure_cleanup;
620  }
621  strcpy(proxy->module_name, module_name); /* Safe */
622 
623  sorcery = __ao2_alloc(sizeof(*sorcery), sorcery_destructor, AO2_ALLOC_OPT_LOCK_MUTEX, module_name, file, line, func);
624  if (!sorcery) {
625  goto failure_cleanup;
626  }
627 
628  sorcery->module_name = proxy->module_name;
629 
630  /* We have exclusive access to proxy and sorcery, no need for locking here. */
631  if (ao2_t_weakproxy_set_object(proxy, sorcery, OBJ_NOLOCK, "weakproxy link")) {
632  goto failure_cleanup;
633  }
634 
636  goto failure_cleanup;
637  }
638 
640  ast_sorcery_object_type_hash_fn, NULL, ast_sorcery_object_type_cmp_fn);
641  if (!sorcery->types) {
642  goto failure_cleanup;
643  }
644 
646  goto failure_cleanup;
647  }
648 
650  ast_log(LOG_ERROR, "Error attempting to apply configuration %s to sorcery.\n", module_name);
651  goto failure_cleanup;
652  }
653 
655  ao2_ref(proxy, -1);
656 
657  NOTIFY_GLOBAL_OBSERVERS(observers, instance_created, module_name, sorcery);
658 
660  return sorcery;
661 
662 failure_cleanup:
663  /* cleanup of sorcery may result in locking instances, so make sure we unlock first. */
665  ao2_cleanup(sorcery);
666  ao2_cleanup(proxy);
667 
668  return NULL;
669 }
enum ast_sorcery_apply_result __ast_sorcery_apply_config(struct ast_sorcery *sorcery, const char *name, const char *module)
Apply configured wizard mappings.
Definition: sorcery.c:985
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
struct ao2_container * observers
Registered global observers.
Definition: sorcery.c:281
static struct ao2_container * instances
Registered sorcery instances.
Definition: sorcery.c:284
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition: astobj2.c:765
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
Full structure for sorcery.
Definition: sorcery.c:230
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
#define ast_assert(a)
Definition: utils.h:710
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
Definition: astobj2.c:931
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ao2_wrlock(a)
Definition: astobj2.h:720
#define ast_log
Definition: astobj2.c:42
Proxy object for sorcery.
Definition: sorcery.c:223
static void sorcery_destructor(void *obj)
Destructor called when sorcery structure is destroyed.
Definition: sorcery.c:581
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void * __ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
#define ao2_t_weakproxy_set_object(weakproxy, obj, flags, tag)
Definition: astobj2.h:586
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
char module_name[0]
The name of the module owning this sorcery instance.
Definition: sorcery.c:226
#define TYPE_BUCKETS
Number of buckets for types (should be prime for performance reasons)
Definition: sorcery.c:54
static void sorcery_proxy_cb(void *weakproxy, void *data)
Hashing function for sorcery types.
Definition: sorcery.c:596
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define NOTIFY_GLOBAL_OBSERVERS(container, callback,...)
Definition: sorcery.c:76
#define ao2_t_weakproxy_alloc(data_size, destructor_fn, tag)
Definition: astobj2.h:557

◆ __ast_sorcery_remove_wizard_mapping()

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.

Remove an object wizard mapping.

Definition at line 850 of file sorcery.c.

References ao2_cleanup, ao2_find, AST_VECTOR_REMOVE_CMP_ORDERED, AST_VECTOR_RW_UNLOCK, AST_VECTOR_RW_WRLOCK, OBJ_KEY, RAII_VAR, ast_sorcery::types, and WIZARD_NAME_COMPARE.

852 {
853  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
854  int res;
855 
856  if (!object_type) {
857  return -1;
858  }
859 
860  AST_VECTOR_RW_WRLOCK(&object_type->wizards);
861 #define WIZARD_NAME_COMPARE(a, b) (strcmp((a)->wizard->callbacks.name, (b)) == 0)
862  res = AST_VECTOR_REMOVE_CMP_ORDERED(&object_type->wizards, name, WIZARD_NAME_COMPARE, ao2_cleanup);
863 #undef WIZARD_NAME_COMPARE
864  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
865 
866  return res;
867 }
static const char type[]
Definition: chan_ooh323.c:109
static const char name[]
Definition: format_mp3.c:68
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define WIZARD_NAME_COMPARE(a, b)
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:890
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order...
Definition: vector.h:540
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ __ast_sorcery_wizard_register()

int __ast_sorcery_wizard_register ( const struct ast_sorcery_wizard interface,
struct ast_module module 
)

Register a sorcery wizard.

Parameters
interfacePointer to a wizard interface
modulePointer to the module implementing the interface
Return values
0success
-1failure

Definition at line 432 of file sorcery.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_find, ao2_link_flags, ao2_lock, ao2_unlock, ast_assert, ast_log, ast_strlen_zero(), ast_verb, ast_sorcery_internal_wizard::callbacks, done, LOG_WARNING, ast_sorcery_wizard::module, ast_sorcery_wizard::name, NOTIFY_GLOBAL_OBSERVERS, NULL, OBJ_KEY, OBJ_NOLOCK, ast_sorcery_internal_wizard::observers, and sorcery_internal_wizard_destructor().

Referenced by ast_bucket_init().

433 {
434  struct ast_sorcery_internal_wizard *wizard;
435  int res = -1;
436 
437  ast_assert(!ast_strlen_zero(interface->name));
438 
439  ao2_lock(wizards);
440 
441  if ((wizard = ao2_find(wizards, interface->name, OBJ_KEY | OBJ_NOLOCK))) {
442  ast_log(LOG_WARNING, "Attempted to register sorcery wizard '%s' twice\n",
443  interface->name);
444  goto done;
445  }
446 
447  if (!(wizard = ao2_alloc(sizeof(*wizard), sorcery_internal_wizard_destructor))) {
448  goto done;
449  }
450 
451  wizard->callbacks = *interface;
452  wizard->callbacks.module = module;
453 
455  if (!wizard->observers) {
456  goto done;
457  }
458 
460  res = 0;
461 
462  ast_verb(2, "Sorcery registered wizard '%s'\n", interface->name);
463 
464  NOTIFY_GLOBAL_OBSERVERS(observers, wizard_registered,
465  interface->name, interface);
466 
467 done:
468  ao2_cleanup(wizard);
470 
471  return res;
472 }
struct ao2_container * observers
Registered global observers.
Definition: sorcery.c:281
#define OBJ_KEY
Definition: astobj2.h:1155
#define LOG_WARNING
Definition: logger.h:274
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ast_assert(a)
Definition: utils.h:710
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_module * module
Pointer to the Asterisk module this wizard is implemented by.
Definition: sorcery.h:281
#define NULL
Definition: resample.c:96
const char * name
Name of the wizard.
Definition: sorcery.h:278
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
#define ast_verb(level,...)
Definition: logger.h:463
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_lock(a)
Definition: astobj2.h:718
Structure for an internal wizard instance.
Definition: sorcery.c:89
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static struct ao2_container * wizards
Registered sorcery wizards.
Definition: sorcery.c:257
struct ao2_container * observers
Observers.
Definition: sorcery.c:99
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void sorcery_internal_wizard_destructor(void *obj)
Definition: sorcery.c:425
#define NOTIFY_GLOBAL_OBSERVERS(container, callback,...)
Definition: sorcery.c:76

◆ ast_sorcery_alloc()

void* ast_sorcery_alloc ( const struct ast_sorcery sorcery,
const char *  type,
const char *  id 
)

Allocate an object.

Parameters
sorceryPointer to a sorcery structure
typeType of object to allocate
idOptional unique identifier, if none is provided one will be generated
Return values
non-NULLsuccess
NULLfailure

Definition at line 1744 of file sorcery.c.

References aco_set_defaults(), ao2_cleanup, ao2_find, ao2_ref, ast_copy_string(), ast_strdup, ast_strlen_zero(), ast_tvnow(), ast_uuid_generate_str(), AST_UUID_STR_LEN, ast_sorcery_object::created, ast_sorcery_object::id, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by alloc_artificial_auth(), apply_list_configuration(), ast_ari_asterisk_update_object(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_mwi_mailbox_alloc(), ast_sip_initialize_system(), ast_sip_location_create_contact(), ast_sorcery_copy(), AST_TEST_DEFINE(), attestation_to_str(), create_artificial_endpoint(), create_object(), global_loaded_observer(), load_module(), mock_retrieve_id(), permanent_uri_handler(), sip_cli_print_global(), sip_cli_print_system(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_memory_cache_ami_populate(), sorcery_memory_cache_thrash_update(), sorcery_realtime_retrieve_fields(), sorcery_realtime_retrieve_multiple(), sorcery_test_retrieve_id(), stir_shaken_general_loaded(), and subscription_persistence_create().

1745 {
1746  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1747  struct ast_sorcery_object_details *details;
1748 
1749  if (!object_type || !object_type->type.item_alloc ||
1750  !(details = object_type->type.item_alloc(id))) {
1751  return NULL;
1752  }
1753 
1754  if (ast_strlen_zero(id)) {
1755  char uuid[AST_UUID_STR_LEN];
1756 
1757  ast_uuid_generate_str(uuid, sizeof(uuid));
1758  details->object->id = ast_strdup(uuid);
1759  } else {
1760  details->object->id = ast_strdup(id);
1761  }
1762  if (!details->object->id) {
1763  ao2_ref(details, -1);
1764  return NULL;
1765  }
1766 
1767  details->object->created = ast_tvnow();
1768  ast_copy_string(details->object->type, type, sizeof(details->object->type));
1769 
1770  if (aco_set_defaults(&object_type->type, id, details)) {
1771  ao2_ref(details, -1);
1772  return NULL;
1773  }
1774 
1775  return details;
1776 }
static const char type[]
Definition: chan_ooh323.c:109
char * id
Unique identifier of this object.
Definition: sorcery.c:129
#define AST_UUID_STR_LEN
Definition: uuid.h:27
#define OBJ_KEY
Definition: astobj2.h:1155
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct timeval created
Time that the object was created.
Definition: sorcery.c:141
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
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.
Definition: uuid.c:143
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_changeset_create()

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.

Parameters
originalOriginal object set
modifiedModified object set
changesPointer to hold any changes between the object sets
Return values
0success
-1failure
Note
The returned ast_variable list must be destroyed using ast_variables_destroy

Definition at line 1663 of file sorcery.c.

References ast_variable_find_in_list(), ast_variable_new, ast_variables_destroy(), ast_variable::name, ast_variable::next, NULL, tmp(), and ast_variable::value.

Referenced by ast_sorcery_diff(), AST_TEST_DEFINE(), can_reuse_registration(), and sorcery_is_criteria_met().

1664 {
1665  const struct ast_variable *field;
1666  int res = 0;
1667 
1668  *changes = NULL;
1669 
1670  /* Unless the ast_variable list changes when examined... it can't differ from itself */
1671  if (original == modified) {
1672  return 0;
1673  }
1674 
1675  for (field = modified; field; field = field->next) {
1676  const char *old_value = ast_variable_find_in_list(original, field->name);
1677 
1678  if (!old_value || strcmp(old_value, field->value)) {
1679  struct ast_variable *tmp;
1680 
1681  if (!(tmp = ast_variable_new(field->name, field->value, ""))) {
1682  res = -1;
1683  break;
1684  }
1685 
1686  tmp->next = *changes;
1687  *changes = tmp;
1688  }
1689  }
1690 
1691  /* If an error occurred do not return a partial changeset */
1692  if (res) {
1693  ast_variables_destroy(*changes);
1694  *changes = NULL;
1695  }
1696 
1697  return res;
1698 }
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
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.
Definition: main/config.c:830
#define ast_variable_new(name, value, filename)

◆ ast_sorcery_copy()

void* ast_sorcery_copy ( const struct ast_sorcery sorcery,
const void *  object 
)

Create a copy of an object.

Parameters
sorceryPointer to a sorcery structure
objectExisting object
Return values
non-NULLsuccess
NULLfailure

Definition at line 1778 of file sorcery.c.

References ao2_cleanup, ao2_find, ast_sorcery_alloc(), ast_sorcery_objectset_apply(), ast_sorcery_objectset_create, ast_variables_destroy(), copy(), ast_sorcery_object::id, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_clone(), ast_bucket_file_clone(), ast_mwi_mailbox_copy(), AST_TEST_DEFINE(), and register_aor_core().

1779 {
1780  const struct ast_sorcery_object_details *details = object;
1781  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1782  struct ast_sorcery_object_details *copy = ast_sorcery_alloc(sorcery, details->object->type, details->object->id);
1783  RAII_VAR(struct ast_variable *, objectset, NULL, ast_variables_destroy);
1784  int res = 0;
1785 
1786  if (!copy) {
1787  return NULL;
1788  } else if (object_type->copy) {
1789  res = object_type->copy(object, copy);
1790  } else if ((objectset = ast_sorcery_objectset_create(sorcery, object))) {
1791  res = ast_sorcery_objectset_apply(sorcery, copy, objectset);
1792  } else {
1793  /* No native copy available and could not create an objectset, this copy has failed */
1794  res = -1;
1795  }
1796 
1797  if (res) {
1798  ao2_cleanup(copy);
1799  copy = NULL;
1800  }
1801 
1802  return copy;
1803 }
char * id
Unique identifier of this object.
Definition: sorcery.c:129
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
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.
Definition: sorcery.c:1632
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for variables, used for configurations and for channel variables.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1136
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_create()

int ast_sorcery_create ( const struct ast_sorcery sorcery,
void *  object 
)

Create and potentially persist an object using an available wizard.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2057 of file sorcery.c.

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery, sorcery_details::sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_create(), sorcery_wizard_create(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by apply_list_configuration(), ast_ari_asterisk_update_object(), ast_bucket_create(), ast_bucket_file_create(), ast_mwi_mailbox_update(), ast_sip_location_create_contact(), AST_TEST_DEFINE(), attestation_to_str(), load_module(), and subscription_persistence_create().

2058 {
2059  const struct ast_sorcery_object_details *details = object;
2060  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2061  struct ast_sorcery_object_wizard *object_wizard = NULL;
2062  struct ast_sorcery_object_wizard *found_wizard;
2063  int i;
2064  struct sorcery_details sdetails = {
2065  .sorcery = sorcery,
2066  .obj = object,
2067  };
2068 
2069  if (!object_type) {
2070  return -1;
2071  }
2072 
2073  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2074  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2075  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2076  if (!found_wizard->caching
2077  && sorcery_wizard_create(found_wizard, &sdetails) == CMP_MATCH) {
2078  object_wizard = found_wizard;
2079  }
2080  }
2081 
2082  if (object_wizard) {
2083  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2084  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2085  if (found_wizard->caching) {
2086  sorcery_wizard_create(found_wizard, &sdetails);
2087  }
2088  }
2089 
2090  if (ao2_container_count(object_type->observers)) {
2091  struct sorcery_observer_invocation *invocation;
2092 
2093  invocation = sorcery_observer_invocation_alloc(object_type, object);
2094  if (invocation
2096  invocation)) {
2097  ao2_cleanup(invocation);
2098  }
2099  }
2100  }
2101 
2103 
2104  return object_wizard ? 0 : -1;
2105 }
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition: sorcery.c:1833
static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
Allocator function for observer invocation.
Definition: sorcery.c:1292
Structure used when calling create, update, or delete.
Definition: sorcery.c:1831
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
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.
Definition: sorcery.c:2020
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
Structure used for observer invocations.
Definition: sorcery.c:196
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_taskprocessor * serializer
Serializer for observers.
Definition: sorcery.c:183
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition: sorcery.c:165
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
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.
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition: sorcery.c:198
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
static int sorcery_observers_notify_create(void *data)
Internal callback function which notifies observers that an object has been created.
Definition: sorcery.c:2047
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_delete()

int ast_sorcery_delete ( const struct ast_sorcery sorcery,
void *  object 
)

Delete an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2233 of file sorcery.c.

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery, sorcery_details::sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_delete(), sorcery_wizard_delete(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by apply_list_configuration(), ast_ari_asterisk_delete_object(), ast_bucket_delete(), ast_bucket_file_delete(), ast_sip_location_delete_contact(), AST_TEST_DEFINE(), attestation_to_str(), bucket_http_wizard_retrieve_id(), mwi_mailbox_delete(), sub_persistence_recreate(), subscription_persistence_recreate(), subscription_persistence_remove(), and unload_module().

2234 {
2235  const struct ast_sorcery_object_details *details = object;
2236  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2237  struct ast_sorcery_object_wizard *object_wizard = NULL;
2238  struct ast_sorcery_object_wizard *found_wizard;
2239  int i;
2240  struct sorcery_details sdetails = {
2241  .sorcery = sorcery,
2242  .obj = object,
2243  };
2244 
2245  if (!object_type) {
2246  return -1;
2247  }
2248 
2249  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2250  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2251  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2252  if (!found_wizard->caching
2253  && sorcery_wizard_delete(found_wizard, &sdetails) == CMP_MATCH) {
2254  object_wizard = found_wizard;
2255  }
2256  }
2257 
2258  if (object_wizard) {
2259  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2260  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2261  if (found_wizard->caching) {
2262  sorcery_wizard_delete(found_wizard, &sdetails);
2263  }
2264  }
2265 
2266  if (ao2_container_count(object_type->observers)) {
2267  struct sorcery_observer_invocation *invocation;
2268 
2269  invocation = sorcery_observer_invocation_alloc(object_type, object);
2270  if (invocation
2272  invocation)) {
2273  ao2_cleanup(invocation);
2274  }
2275  }
2276  }
2277 
2279 
2280  return object_wizard ? 0 : -1;
2281 }
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition: sorcery.c:1833
static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
Allocator function for observer invocation.
Definition: sorcery.c:1292
Structure used when calling create, update, or delete.
Definition: sorcery.c:1831
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
Structure used for observer invocations.
Definition: sorcery.c:196
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_taskprocessor * serializer
Serializer for observers.
Definition: sorcery.c:183
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition: sorcery.c:165
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
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.
Definition: sorcery.c:2219
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
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.
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition: sorcery.c:198
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
static int sorcery_observers_notify_delete(void *data)
Internal callback function which notifies observers that an object has been deleted.
Definition: sorcery.c:2208
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_diff()

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.

Parameters
sorceryPointer to a sorcery structure
originalOriginal object
modifiedModified object
changesPointer which will be populated with changes if any exist
Return values
0success
-1failure
Note
The returned ast_variable list must be destroyed using ast_variables_destroy
While the objects must be of the same type they do not have to be the same object

Definition at line 1805 of file sorcery.c.

References ao2_cleanup, ao2_find, ast_sorcery_changeset_create(), ast_sorcery_object_get_type(), ast_sorcery_objectset_create, ast_variables_destroy(), NULL, OBJ_KEY, RAII_VAR, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE(), and transport_apply().

1806 {
1808 
1809  *changes = NULL;
1810 
1811  if (strcmp(ast_sorcery_object_get_type(original), ast_sorcery_object_get_type(modified))) {
1812  return -1;
1813  }
1814 
1815  if (original == modified) {
1816  return 0;
1817  } else if (!object_type->diff) {
1818  RAII_VAR(struct ast_variable *, objectset1, NULL, ast_variables_destroy);
1819  RAII_VAR(struct ast_variable *, objectset2, NULL, ast_variables_destroy);
1820 
1821  objectset1 = ast_sorcery_objectset_create(sorcery, original);
1822  objectset2 = ast_sorcery_objectset_create(sorcery, modified);
1823 
1824  return ast_sorcery_changeset_create(objectset1, objectset2, changes);
1825  } else {
1826  return object_type->diff(original, modified, changes);
1827  }
1828 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for variables, used for configurations and for channel variables.
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition: sorcery.c:2324
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
sorcery_diff_handler diff
Optional object diff callback.
Definition: sorcery.c:162
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1136
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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.
Definition: sorcery.c:1663
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition: sorcery.c:198

◆ ast_sorcery_force_reload()

void ast_sorcery_force_reload ( const struct ast_sorcery sorcery)

Inform any wizards to reload persistent objects, even if no changes determined.

Parameters
sorceryPointer to a sorcery structure
Since
13.32.0
16.9.0
17.3.0

Definition at line 1425 of file sorcery.c.

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery, sorcery_load_details::sorcery, sorcery_object_load(), and ast_sorcery::types.

1426 {
1427  struct sorcery_load_details details = {
1428  .sorcery = sorcery,
1429  .reload = 1,
1430  .force = 1,
1431  };
1432 
1433  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1434  sorcery->module_name, sorcery, 1);
1435 
1436  ao2_callback(sorcery->types, OBJ_NODATA, sorcery_object_load, &details);
1437 
1438  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loaded,
1439  sorcery->module_name, sorcery, 1);
1440 }
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244
Structure for passing load/reload details.
Definition: sorcery.c:242
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
static struct ast_sorcery * sorcery
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition: sorcery.c:79
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336

◆ ast_sorcery_force_reload_object()

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 determined.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to reload
Since
13.32.0
16.9.0
17.3.0

Definition at line 1457 of file sorcery.c.

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery, sorcery_load_details::sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by acl_change_stasis_cb().

1458 {
1459  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1460  struct sorcery_load_details details = {
1461  .sorcery = sorcery,
1462  .reload = 1,
1463  .force = 1,
1464  };
1465 
1466  if (!object_type) {
1467  return;
1468  }
1469 
1470  sorcery_object_load(object_type, &details, 0);
1471 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure for passing load/reload details.
Definition: sorcery.c:242
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336

◆ ast_sorcery_generic_alloc()

void* ast_sorcery_generic_alloc ( size_t  size,
ao2_destructor_fn  destructor 
)

Allocate a generic sorcery capable object.

Parameters
sizeSize of the object
destructorOptional destructor function
Return values
non-NULLsuccess
NULLfailure
Note
The returned object does not support AO2 locking.

Definition at line 1728 of file sorcery.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_sorcery_object::destructor, NULL, ast_sorcery_object_details::object, and sorcery_object_destructor().

Referenced by acl_alloc(), aeap_server_alloc(), ast_sip_endpoint_alloc(), asterisk_publication_config_alloc(), auth_alloc(), bucket_alloc(), bucket_file_alloc(), contact_alloc(), domain_alias_alloc(), global_alloc(), ip_identify_alloc(), mapping_alloc(), mwi_sorcery_object_alloc(), phoneprov_alloc(), publication_resource_alloc(), resource_list_alloc(), sip_nat_hook_alloc(), sip_outbound_publish_alloc(), sip_outbound_registration_alloc(), sip_transport_alloc(), sorcery_memory_cache_ami_populate(), stir_shaken_certificate_alloc(), stir_shaken_general_alloc(), stir_shaken_store_alloc(), subscription_persistence_alloc(), system_alloc(), test_data_alloc(), and test_sorcery_object_alloc().

1729 {
1730  void *object = ao2_alloc_options(size + sizeof(struct ast_sorcery_object),
1732  struct ast_sorcery_object_details *details = object;
1733 
1734  if (!object) {
1735  return NULL;
1736  }
1737 
1738  details->object = object + size;
1739  details->object->destructor = destructor;
1740 
1741  return object;
1742 }
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
ao2_destructor_fn destructor
Optional object destructor.
Definition: sorcery.c:135
Structure for internal sorcery object information.
Definition: sorcery.c:127
static void sorcery_object_destructor(void *object)
Definition: sorcery.c:1700
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_get_module()

const char* ast_sorcery_get_module ( const struct ast_sorcery sorcery)

Get the module that has opened the provided sorcery instance.

Parameters
sorceryThe sorcery instance
Returns
The module

Definition at line 2531 of file sorcery.c.

References ast_sorcery::module_name.

Referenced by sorcery_memory_cache_load().

2532 {
2533  return sorcery->module_name;
2534 }
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238

◆ ast_sorcery_get_object_type()

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.

Parameters
sorceryThe sorcery from which to retrieve the object type
typeThe type name

Definition at line 2489 of file sorcery.c.

References ao2_find, OBJ_SEARCH_KEY, and ast_sorcery::types.

Referenced by ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), AST_TEST_DEFINE(), sorcery_astdb_filter_objectset(), sorcery_is_explicit_name_met(), and sorcery_realtime_filter_objectset().

2491 {
2492  return ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
2493 }
static const char type[]
Definition: chan_ooh323.c:109
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ ast_sorcery_get_wizard_mapping()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object
indexIndex of the wizard
wizardA pointer to receive the wizard pointer
dataA pointer to receive the data pointer
Return values
0success
-1failure
Warning
The wizard will have its reference count bumped so you must call ao2_cleanup when you're done with it.
Note
The wizard and data returned are valid only for this object type and only while the wizard is applied to the object type.
Since
13.4.0

Definition at line 790 of file sorcery.c.

References ao2_bump, ao2_cleanup, ao2_find, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, NULL, OBJ_KEY, RAII_VAR, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by AST_TEST_DEFINE().

792 {
793  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
794  struct ast_sorcery_object_wizard *owizard;
795 
796  if (!object_type) {
797  return -1;
798  }
799 
800  if (index < 0 || index >= AST_VECTOR_SIZE(&object_type->wizards)) {
801  return -1;
802  }
803 
804  owizard = AST_VECTOR_GET(&object_type->wizards, index);
805 
806  if (wizard != NULL) {
807  *wizard = &(owizard->wizard->callbacks);
808  ao2_bump(owizard->wizard);
809  } else {
810  return -1;
811  }
812 
813  if (data != NULL) {
814  *data = owizard->data;
815  }
816 
817  return 0;
818 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
#define NULL
Definition: resample.c:96
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * data
Unique data for the wizard.
Definition: sorcery.c:108
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_sorcery_get_wizard_mapping_count()

int ast_sorcery_get_wizard_mapping_count ( struct ast_sorcery sorcery,
const char *  type 
)

Return the number of wizards mapped to an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
Returns
Number of wizards or -1 for error
Since
13.4.0

Definition at line 778 of file sorcery.c.

References ao2_cleanup, ao2_find, AST_VECTOR_SIZE, OBJ_KEY, RAII_VAR, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE().

780 {
781  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
782 
783  if (!object_type) {
784  return -1;
785  }
786 
787  return AST_VECTOR_SIZE(&object_type->wizards);
788 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_sorcery_global_observer_add()

int ast_sorcery_global_observer_add ( const struct ast_sorcery_global_observer callbacks)

Add a global observer to sorcery.

Parameters
callbacksImplementation of the global observer interface
Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 498 of file sorcery.c.

References ao2_alloc, ao2_link, ao2_ref, sorcery_global_observer::callbacks, ast_sorcery_internal_wizard::callbacks, and NULL.

Referenced by AST_TEST_DEFINE(), and load_module().

499 {
500  struct sorcery_global_observer *cb;
501 
502  cb = ao2_alloc(sizeof(*cb), NULL);
503  if (!cb) {
504  return -1;
505  }
506 
507  cb->callbacks = callbacks;
508  ao2_link(observers, cb);
509  ao2_ref(cb, -1);
510 
511  return 0;
512 }
struct ao2_container * observers
Registered global observers.
Definition: sorcery.c:281
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
A global observer wrapper.
Definition: sorcery.c:266
const struct ast_sorcery_global_observer * callbacks
Definition: sorcery.c:267
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_sorcery_global_observer_remove()

void ast_sorcery_global_observer_remove ( const struct ast_sorcery_global_observer callbacks)

Remove a global observer from sorcery.

A global observer is notified... After a new wizard is registered. After a new sorcery instance is opened. Before an instance is destroyed. Before a wizard is unregistered.

Parameters
callbacksImplementation of the global observer interface

Definition at line 514 of file sorcery.c.

References ao2_callback, OBJ_NODATA, OBJ_UNLINK, and sorcery_generic_observer_remove().

Referenced by AST_TEST_DEFINE(), and unload_module().

516 {
518 }
static int sorcery_generic_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing a generic observer.
Definition: sorcery.c:491
struct ao2_container * observers
Registered global observers.
Definition: sorcery.c:281
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716

◆ ast_sorcery_init()

int ast_sorcery_init ( void  )

Compare function for sorcery instances.

Initialize the sorcery API.

Hashing function for sorcery instances

Definition at line 387 of file sorcery.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_hash, ao2_container_alloc_list, ast_assert, ast_register_cleanup(), ast_threadpool_create(), AST_THREADPOOL_OPTIONS_VERSION, INSTANCE_BUCKETS, NULL, sorcery_cleanup(), ast_threadpool_options::version, and WIZARD_BUCKETS.

Referenced by asterisk_daemon().

388 {
391  .auto_increment = 1,
392  .max_size = 0,
393  .idle_timeout = 60,
394  .initial_size = 0,
395  };
396  ast_assert(wizards == NULL);
397 
398  threadpool = ast_threadpool_create("sorcery", NULL, &options);
399  if (!threadpool) {
400  return -1;
401  }
402 
404  ast_sorcery_internal_wizard_hash_fn, NULL, ast_sorcery_internal_wizard_cmp_fn);
405  if (!wizards) {
406  return -1;
407  }
408 
410  if (!observers) {
411  return -1;
412  }
413 
415  sorcery_proxy_hash_fn, NULL, sorcery_proxy_cmp_fn);
416  if (!instances) {
417  return -1;
418  }
419 
421 
422  return 0;
423 }
struct ao2_container * observers
Registered global observers.
Definition: sorcery.c:281
static struct ao2_container * instances
Registered sorcery instances.
Definition: sorcery.c:284
#define AST_THREADPOOL_OPTIONS_VERSION
Definition: threadpool.h:71
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define ast_assert(a)
Definition: utils.h:710
#define NULL
Definition: resample.c:96
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static struct ast_threadpool * threadpool
Thread pool for observers.
Definition: sorcery.c:86
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static void sorcery_cleanup(void)
Hashing and comparison functions for sorcery wizards.
Definition: sorcery.c:369
static struct ao2_container * wizards
Registered sorcery wizards.
Definition: sorcery.c:257
struct ast_threadpool * ast_threadpool_create(const char *name, struct ast_threadpool_listener *listener, const struct ast_threadpool_options *options)
Create a new threadpool.
Definition: threadpool.c:915
#define INSTANCE_BUCKETS
Number of buckets for instances (should be prime for performance reasons)
Definition: sorcery.c:57
#define WIZARD_BUCKETS
Number of buckets for wizards (should be prime for performance reasons)
Definition: sorcery.c:51
static struct test_options options

◆ ast_sorcery_instance_observer_add()

int ast_sorcery_instance_observer_add ( struct ast_sorcery sorcery,
const struct ast_sorcery_instance_observer callbacks 
)

Add an observer to a sorcery instance.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the instance observer interface

An instance observer is notified... Before an instance is loaded or reloaded. After an instance is loaded or reloaded. After a wizard is mapped to an object type. After an object type is registered. Before an object type is loaded or reloaded. After an object type is loaded or reloaded.

Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 520 of file sorcery.c.

References ao2_alloc, ao2_link, ao2_ref, sorcery_instance_observer::callbacks, ast_sorcery_internal_wizard::callbacks, NULL, and ast_sorcery::observers.

Referenced by ast_sip_initialize_sorcery_global(), AST_TEST_DEFINE(), instance_created_observer(), load_module(), pjsip_outbound_registration_metrics_init(), and stir_shaken_general_load().

522 {
523  struct sorcery_instance_observer *cb;
524 
525  cb = ao2_alloc(sizeof(*cb), NULL);
526  if (!cb) {
527  return -1;
528  }
529 
530  cb->callbacks = callbacks;
531  ao2_link(sorcery->observers, cb);
532  ao2_ref(cb, -1);
533 
534  return 0;
535 }
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
An instance observer wrapper.
Definition: sorcery.c:271
const struct ast_sorcery_instance_observer * callbacks
Definition: sorcery.c:272
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_sorcery_instance_observer_remove()

void ast_sorcery_instance_observer_remove ( struct ast_sorcery sorcery,
const struct ast_sorcery_instance_observer callbacks 
)

Remove an observer from a sorcery instance.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the instance observer interface

Definition at line 537 of file sorcery.c.

References ao2_callback, OBJ_NODATA, OBJ_UNLINK, ast_sorcery::observers, and sorcery_generic_observer_remove().

Referenced by ast_sip_destroy_sorcery_global(), AST_TEST_DEFINE(), instance_destroying_observer(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), stir_shaken_general_unload(), and unload_module().

539 {
541 }
static int sorcery_generic_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing a generic observer.
Definition: sorcery.c:491
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ao2_container * observers
Observers.
Definition: sorcery.c:235

◆ ast_sorcery_is_object_field_registered()

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.

Parameters
object_typeThe object type to check against
field_nameThe name of the field to check
Return values
0The field is not registered for this sorcery type
1The field is registered for this sorcery type

Definition at line 2509 of file sorcery.c.

References ao2_callback, ao2_cleanup, ao2_find, ast_assert, ast_sorcery_object_type::fields, is_registered_cb(), NULL, and OBJ_SEARCH_KEY.

Referenced by AST_TEST_DEFINE(), sorcery_astdb_filter_objectset(), sorcery_is_explicit_name_met(), and sorcery_realtime_filter_objectset().

2511 {
2512  struct ast_sorcery_object_field *object_field;
2513  int res = 1;
2514 
2515  ast_assert(object_type != NULL);
2516 
2517  object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
2518 
2519  if (!object_field) {
2520  object_field = ao2_callback(object_type->fields, 0, is_registered_cb, (char *)field_name);
2521  }
2522 
2523  if (!object_field) {
2524  res = 0;
2525  }
2526 
2527  ao2_cleanup(object_field);
2528  return res;
2529 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ast_assert(a)
Definition: utils.h:710
#define NULL
Definition: resample.c:96
Structure for registered object field.
Definition: sorcery.c:205
struct ao2_container * fields
Object fields.
Definition: sorcery.c:168
static int is_registered_cb(void *obj, void *arg, int flags)
Definition: sorcery.c:2495
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_sorcery_is_stale()

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.

Since
14.0.0

This function will query the wizard(s) backing the particular sorcery object to determine if the in-memory object is now stale. No action is taken to update the object. Callers of this function may use one of the ast_sorcery_retrieve functions to obtain a new instance of the object if desired.

Return values
0the object is not stale
1the object is stale

Definition at line 2283 of file sorcery.c.

References ao2_cleanup, ao2_find, ast_debug, ast_sorcery_object_get_id(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, ast_sorcery_wizard::is_stale, ast_sorcery_wizard::name, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by ast_bucket_file_is_stale(), ast_bucket_is_stale(), and AST_TEST_DEFINE().

2284 {
2285  const struct ast_sorcery_object_details *details = object;
2286  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2287  struct ast_sorcery_object_wizard *found_wizard;
2288  int res = 0;
2289  int i;
2290 
2291  if (!object_type) {
2292  return -1;
2293  }
2294 
2295  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2296  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2297  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2298 
2299  if (found_wizard->wizard->callbacks.is_stale) {
2300  res |= found_wizard->wizard->callbacks.is_stale(sorcery, found_wizard->data, object);
2301  ast_debug(5, "After calling wizard '%s', object '%s' is %s\n",
2302  found_wizard->wizard->callbacks.name,
2303  ast_sorcery_object_get_id(object),
2304  res ? "stale" : "not stale");
2305  }
2306  }
2307  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2308 
2309  return res;
2310 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
const char * name
Name of the wizard.
Definition: sorcery.h:278
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * data
Unique data for the wizard.
Definition: sorcery.c:108
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
int(* is_stale)(const struct ast_sorcery *sorcery, void *data, void *object)
Definition: sorcery.h:325
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_load()

void ast_sorcery_load ( const struct ast_sorcery sorcery)

Inform any wizards to load persistent objects.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1377 of file sorcery.c.

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery, sorcery_load_details::sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by ast_res_pjsip_initialize_configuration(), ast_sip_initialize_system(), AST_TEST_DEFINE(), and load_module().

1378 {
1379  struct sorcery_load_details details = {
1380  .sorcery = sorcery,
1381  .reload = 0,
1382  };
1383 
1384  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1385  sorcery->module_name, sorcery, 0);
1386 
1387  ao2_callback(sorcery->types, OBJ_NODATA, sorcery_object_load, &details);
1388 
1389  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loaded,
1390  sorcery->module_name, sorcery, 0);
1391 }
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244
Structure for passing load/reload details.
Definition: sorcery.c:242
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
static struct ast_sorcery * sorcery
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition: sorcery.c:79
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336

◆ ast_sorcery_load_object()

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.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to load

Definition at line 1393 of file sorcery.c.

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery, sorcery_load_details::sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by AST_TEST_DEFINE(), load_module(), and reregister_all().

1394 {
1395  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1396  struct sorcery_load_details details = {
1397  .sorcery = sorcery,
1398  .reload = 0,
1399  };
1400 
1401  if (!object_type) {
1402  return;
1403  }
1404 
1405  sorcery_object_load(object_type, &details, 0);
1406 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure for passing load/reload details.
Definition: sorcery.c:242
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336

◆ ast_sorcery_lockable_alloc()

void* ast_sorcery_lockable_alloc ( size_t  size,
ao2_destructor_fn  destructor,
void *  lockobj 
)

Allocate a generic sorcery capable object with locking.

Since
14.1.0

Sorcery objects may be replaced with new allocations during reloads. If locking is required on sorcery objects it must be shared between the old object and the new one. lockobj can be any AO2 object with locking enabled, but in most cases named locks should be used to provide stable locking.

Parameters
sizeSize of the object
destructorOptional destructor function
lockobjAn AO2 object that will provide locking.
Return values
non-NULLsuccess
NULLfailure

Definition at line 1712 of file sorcery.c.

References ao2_alloc_with_lockobj, ast_sorcery_object::destructor, NULL, ast_sorcery_object_details::object, and sorcery_object_destructor().

Referenced by aor_alloc().

1713 {
1714  void *object = ao2_alloc_with_lockobj(size + sizeof(struct ast_sorcery_object),
1715  sorcery_object_destructor, lockobj, "");
1716  struct ast_sorcery_object_details *details = object;
1717 
1718  if (!object) {
1719  return NULL;
1720  }
1721 
1722  details->object = object + size;
1723  details->object->destructor = destructor;
1724 
1725  return object;
1726 }
#define ao2_alloc_with_lockobj(data_size, destructor_fn, lockobj, tag)
Allocate and initialize an object with separate locking.
Definition: astobj2.h:433
#define NULL
Definition: resample.c:96
ao2_destructor_fn destructor
Optional object destructor.
Definition: sorcery.c:135
Structure for internal sorcery object information.
Definition: sorcery.c:127
static void sorcery_object_destructor(void *object)
Definition: sorcery.c:1700
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_fields_register()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object
regexA regular expression pattern for the fields
config_handlerA custom handler for translating the string representation of the fields
sorcery_handlerA custom handler for translating the native representation of the fields
Return values
0success
-1failure

Definition at line 1160 of file sorcery.c.

References __aco_option_register(), ACO_REGEX, ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ast_alloca, ast_calloc, ast_copy_string(), ast_log, LOG_ERROR, MAX_REGEX_ERROR_LEN, NULL, OBJ_KEY, OPT_CUSTOM_T, RAII_VAR, sorcery_object_field_destructor(), and ast_sorcery::types.

Referenced by __ast_sorcery_object_register(), AST_TEST_DEFINE(), and load_module().

1161 {
1162 #define MAX_REGEX_ERROR_LEN 128
1163  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1164  RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
1165  int rc;
1166 
1167  if (!object_type || !object_type->type.item_alloc || !config_handler
1168  || !(object_field = ao2_alloc(sizeof(*object_field), sorcery_object_field_destructor))) {
1169  return -1;
1170  }
1171 
1172  ast_copy_string(object_field->name, regex, sizeof(object_field->name));
1173  object_field->multiple_handler = sorcery_handler;
1174 
1175  if (!(object_field->name_regex = ast_calloc(1, sizeof(regex_t)))) {
1176  return -1;
1177  }
1178 
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);
1183  return -1;
1184  }
1185 
1186  ao2_link(object_type->fields, object_field);
1187  __aco_option_register(object_type->info, regex, ACO_REGEX, object_type->file->types, "", OPT_CUSTOM_T, config_handler, 0, 1, 0);
1188 
1189  return 0;
1190 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
#define NULL
Definition: resample.c:96
Type for a custom (user-defined) option handler.
#define MAX_REGEX_ERROR_LEN
#define ast_log
Definition: astobj2.c:42
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure for registered object field.
Definition: sorcery.c:205
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
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define LOG_ERROR
Definition: logger.h:285
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static void sorcery_object_field_destructor(void *obj)
Definition: sorcery.c:1150
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_sorcery_object_get_created()

const struct timeval ast_sorcery_object_get_created ( const void *  object)

Get when the socery object was created.

Since
14.0.0
Parameters
objectPointer to a sorcery object
Return values
Thetime when the object was created

Definition at line 2318 of file sorcery.c.

References ast_sorcery_object::created, and ast_sorcery_object_details::object.

2319 {
2320  const struct ast_sorcery_object_details *details = object;
2321  return details->object->created;
2322 }
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct timeval created
Time that the object was created.
Definition: sorcery.c:141
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_get_extended()

const char* ast_sorcery_object_get_extended ( const void *  object,
const char *  name 
)

Get an extended field value from a sorcery object.

Parameters
objectPointer to a sorcery object
nameName of the extended field value
Return values
non-NULLif found
NULLif not found
Note
The returned string does NOT need to be freed and is guaranteed to remain valid for the lifetime of the object

Definition at line 2330 of file sorcery.c.

References ast_sorcery_object::extended, ast_variable::name, ast_variable::next, NULL, ast_sorcery_object_details::object, and ast_variable::value.

Referenced by AST_TEST_DEFINE(), asterisk_start_devicestate_publishing(), asterisk_start_mwi_publishing(), delete_existing_cb(), and publisher_start().

2331 {
2332  const struct ast_sorcery_object_details *details = object;
2333  struct ast_variable *field;
2334 
2335  for (field = details->object->extended; field; field = field->next) {
2336  if (!strcmp(field->name + 1, name)) {
2337  return field->value;
2338  }
2339  }
2340 
2341  return NULL;
2342 }
struct ast_variable * next
static const char name[]
Definition: format_mp3.c:68
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
struct ast_variable * extended
Extended object fields.
Definition: sorcery.c:138
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_get_id()

const char* ast_sorcery_object_get_id ( const void *  object)

Get the unique identifier of a sorcery object.

Parameters
objectPointer to a sorcery object
Return values
uniqueidentifier

Definition at line 2312 of file sorcery.c.

References ast_sorcery_object::id, and ast_sorcery_object_details::object.

Referenced by __print_debug_details(), aeap_cli_show(), aeap_server_apply(), aeap_tab_complete_name(), allocate_subscription_tree(), allow_and_or_replace_unsolicited(), ami_outbound_registration_task(), ami_show_registration_contact_statuses(), anonymous_identify(), aor_deleted_observer(), apply_acls(), ast_bucket_file_json(), ast_bucket_json(), ast_mwi_mailbox_get_id(), ast_mwi_mailbox_update(), ast_res_pjsip_find_or_create_contact_status(), ast_res_pjsip_initialize_configuration(), ast_sip_create_dialog_uac(), ast_sip_create_subscription(), ast_sip_for_each_contact(), ast_sip_format_contact_ami(), ast_sip_get_contact_status(), ast_sip_get_device_state(), ast_sip_initialize_sorcery_auth(), ast_sip_initialize_sorcery_transport(), ast_sip_location_create_contact(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), ast_sip_session_alloc(), ast_sip_session_create_outgoing(), ast_sip_session_get_name(), ast_sip_set_tpselector_from_transport(), ast_sip_subscription_destroy(), ast_sorcery_is_stale(), ast_sorcery_object_id_hash(), ast_sorcery_object_id_sort(), AST_TEST_DEFINE(), asterisk_publication_devicestate(), asterisk_publication_devicestate_refresh(), asterisk_publication_devicestate_state_change(), asterisk_publication_mailboxstate(), asterisk_publication_mwi_refresh(), asterisk_publication_mwi_state_change(), auth_apply(), auth_observer(), bucket_file_run_curl(), bucket_http_test_wizard_create(), bucket_http_test_wizard_delete(), bucket_http_test_wizard_update(), build_resource_tree(), can_reuse_registration(), cancel_and_unpublish(), chan_pjsip_indicate(), chan_pjsip_new(), change_outgoing_sdp_stream_media_address(), check_state(), cli_aor_get_id(), cli_aor_print_body(), cli_complete_endpoint(), cli_complete_registration(), cli_complete_uri(), cli_contact_print_body(), cli_endpoint_print_body(), cli_iterator(), cli_list_subscriptions_detail(), cli_print_body(), cli_show_subscriptions_detail(), codec_prefs_handler(), common_identify(), connected_line_method_handler(), contact_apply_handler(), contact_function_get_permanent(), create_dialog_uas(), create_out_of_dialog_request(), create_rtp(), create_unsolicited_mwi_subscriptions(), current_state_reusable(), destroy_subscription(), digest_check_auth(), digest_create_request_with_auth(), direct_media_glare_mitigation_handler(), direct_media_method_handler(), domain_alias_apply(), endpt_send_request(), expire_objects_from_cache(), file_extension_from_url_path(), find_internal_state_by_transport(), find_or_create_temporary_state(), find_registrar_aor(), format_ami_aor_handler(), format_ami_auth_handler(), format_ami_endpoint_identify(), format_ami_endpoint_transport(), from_user_handler(), get_account_id(), get_curl_instance(), handle_export_primitives(), handle_incoming_request(), handle_slash(), has_mwi_subscription(), header_identify_match_check(), ident_handler(), internal_state_alloc(), ip_identify_apply(), ip_identify_match_check(), ip_identify_match_handler(), line_identify(), load_module(), log_caps(), mark_object_as_stale_in_cache(), media_cache_handle_show_item(), media_cache_item_del_from_astdb(), media_cache_item_sync_to_astdb(), media_cache_prnt_summary(), memory_cache_stale_update_object(), msg_send(), mwi_contact_changed(), mwi_observe_delete(), mwi_post_event(), mwi_subscription_alloc(), mwi_validate_for_aor(), new_subscribe(), on_load_attestation(), permanent_uri_handler(), permanent_uri_sort_fn(), persistent_endpoint_find_or_create(), pjsip_aor_function_read(), publish_request_initial(), publisher_start(), publisher_stop(), pubsub_on_rx_mwi_notify_request(), pubsub_on_rx_publish_request(), pubsub_on_rx_subscribe_request(), qualify_contact_cb(), read_pjsip(), redirect_handler(), refer_incoming_attended_request(), refer_incoming_blind_request(), refer_incoming_invite_request(), refer_incoming_refer_request(), refer_progress_alloc(), register_aor_core(), registrar_contact_delete(), registrar_on_rx_request(), registration_deleted_observer(), registration_state_cmp(), registration_state_hash(), remove_from_cache(), remove_subscription(), resource_list_apply_handler(), rfc3326_add_reason_header(), rx_data_to_ast_msg(), session_destructor(), session_inv_on_redirected(), session_inv_on_tsx_state_changed(), session_outgoing_nat_hook(), set_outbound_authentication_credentials(), sip_aor_to_ami(), sip_endpoint_apply_handler(), sip_options_aor_alloc(), sip_options_aor_observer_deleted_task(), sip_options_aor_observer_modified_task(), sip_options_apply_aor_configuration(), sip_options_contact_status_notify_task(), sip_options_endpoint_observer_deleted_task(), sip_options_endpoint_observer_modified_task(), sip_options_endpoint_state_compositor_find_or_alloc(), sip_options_endpoint_unlink_aor_feeders(), sip_options_qualify_contact(), sip_options_remove_contact_status(), sip_options_synchronize_aor(), sip_options_synchronize_endpoint(), sip_outbound_publish_apply(), sip_outbound_publish_callback(), sip_outbound_publish_state_alloc(), sip_outbound_publish_synchronize(), sip_outbound_publisher_alloc(), sip_outbound_publisher_init(), sip_outbound_publisher_set_uris(), sip_outbound_registration_apply(), sip_outbound_registration_regc_alloc(), sip_outbound_registration_state_alloc(), sip_sorcery_object_ami_set_type_name(), sip_subscription_send_request(), sip_subscription_to_ami(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_update(), sorcery_config_fields_cmp(), sorcery_memory_cache_complete_object_name(), sorcery_memory_cache_create(), sorcery_memory_cache_delete(), sorcery_memory_cache_fields_cmp(), sorcery_memory_cache_print_object(), sorcery_memory_cache_retrieve_id(), sorcery_memory_cached_object_cmp(), sorcery_memory_cached_object_hash(), sorcery_memory_cmp(), sorcery_memory_create(), sorcery_memory_delete(), sorcery_memory_fields_cmp(), sorcery_memory_hash(), sorcery_memory_update(), sorcery_realtime_create(), sorcery_realtime_delete(), sorcery_realtime_update(), stale_item_update(), stir_shaken_cli_show(), stir_shaken_tab_complete_name(), subscription_established(), subscription_persistence_create(), subscription_persistence_remove(), subscription_tree_destructor(), t38_initialize_session(), tos_handler(), transport_apply(), transport_tls_file_handler(), transport_tos_handler(), update_devstate(), users_apply_handler(), and validate_publish_config().

2313 {
2314  const struct ast_sorcery_object_details *details = object;
2315  return details->object->id;
2316 }
char * id
Unique identifier of this object.
Definition: sorcery.c:129
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_get_type()

const char* ast_sorcery_object_get_type ( const void *  object)

Get the type of a sorcery object.

Parameters
objectPointer to a sorcery object
Return values
typeof object

Definition at line 2324 of file sorcery.c.

References ast_sorcery_object_details::object, and ast_sorcery_object::type.

Referenced by aeap_cli_show(), ast_sorcery_diff(), AST_TEST_DEFINE(), memory_cache_stale_check_object(), memory_cache_stale_update_object(), sip_aor_to_ami(), sip_sorcery_object_ami_set_type_name(), sorcery_astdb_create(), sorcery_astdb_delete(), sorcery_astdb_update(), stale_item_update(), and stir_shaken_cli_show().

2325 {
2326  const struct ast_sorcery_object_details *details = object;
2327  return details->object->type;
2328 }
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_has_dynamic_contents()

unsigned int ast_sorcery_object_has_dynamic_contents ( const void *  object)

Get whether an object contains dynamic contents or not.

Parameters
objectPointer to a sorcery object
Since
19
18.3.0
16.17.0

Definition at line 2372 of file sorcery.c.

References ast_sorcery_object::has_dynamic_contents, and ast_sorcery_object_details::object.

Referenced by sorcery_config_internal_load().

2373 {
2374  const struct ast_sorcery_object_details *details = object;
2375 
2376  return details->object->has_dynamic_contents;
2377 }
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
unsigned int has_dynamic_contents
Whether this object has dynamic contents or not.
Definition: sorcery.c:144
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_id_compare()

int ast_sorcery_object_id_compare ( void *  obj,
void *  arg,
int  flags 
)

ao2 object comparator based on sorcery id.

Definition at line 2459 of file sorcery.c.

References ast_sorcery_object_id_sort(), and CMP_MATCH.

Referenced by ast_media_cache_init(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), handle_registrations(), register_aor_core(), sip_options_aor_alloc(), and sorcery_config_internal_load().

2460 {
2461  int cmp;
2462 
2463  cmp = ast_sorcery_object_id_sort(obj, arg, flags);
2464  if (cmp) {
2465  return 0;
2466  }
2467  return CMP_MATCH;
2468 }
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2435

◆ ast_sorcery_object_id_hash()

int ast_sorcery_object_id_hash ( const void *  obj,
int  flags 
)

ao2 object hasher based on sorcery id.

Definition at line 2470 of file sorcery.c.

References ast_assert, ast_sorcery_object_get_id(), ast_str_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_media_cache_init(), sip_options_aor_alloc(), and sorcery_config_internal_load().

2471 {
2472  const char *key;
2473 
2474  switch (flags & OBJ_SEARCH_MASK) {
2475  case OBJ_SEARCH_KEY:
2476  key = obj;
2477  break;
2478  case OBJ_SEARCH_OBJECT:
2479  key = ast_sorcery_object_get_id(obj);
2480  break;
2481  default:
2482  /* Hash can only work on something with a full key. */
2483  ast_assert(0);
2484  return 0;
2485  }
2486  return ast_str_hash(key);
2487 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
#define ast_assert(a)
Definition: utils.h:710
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ ast_sorcery_object_id_sort()

int ast_sorcery_object_id_sort ( const void *  obj,
const void *  arg,
int  flags 
)

ao2 object sorter based on sorcery id.

Definition at line 2435 of file sorcery.c.

References ast_sorcery_object_get_id(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by ast_sorcery_object_id_compare(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), and sip_options_aor_alloc().

2436 {
2437  const void *object_left = obj;
2438  const void *object_right = arg;
2439  const char *right_key = arg;
2440  int cmp;
2441 
2442  switch (flags & OBJ_SEARCH_MASK) {
2443  case OBJ_SEARCH_OBJECT:
2444  right_key = ast_sorcery_object_get_id(object_right);
2445  /* Fall through */
2446  case OBJ_SEARCH_KEY:
2447  cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
2448  break;
2450  cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
2451  break;
2452  default:
2453  cmp = 0;
2454  break;
2455  }
2456  return cmp;
2457 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1120
The arg parameter is an object of the same type.
Definition: astobj2.h:1091
Search option field mask.
Definition: astobj2.h:1076

◆ ast_sorcery_object_set_congestion_levels()

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.

Since
13.10.0
Parameters
sorceryPointer to a sorcery structure
typeType of object
low_waterNew queue low water mark. (-1 to set as 90% of high_water)
high_waterNew queue high water mark.
Return values
0on success.
-1on error (water marks not changed).

Definition at line 1114 of file sorcery.c.

References ao2_find, ao2_ref, ast_taskprocessor_alert_set_levels(), OBJ_SEARCH_KEY, ast_sorcery_object_type::serializer, and ast_sorcery::types.

Referenced by ast_sip_initialize_sorcery_location().

1115 {
1116  struct ast_sorcery_object_type *object_type;
1117  int res = -1;
1118 
1119  object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1120  if (object_type) {
1122  low_water, high_water);
1123  ao2_ref(object_type, -1);
1124  }
1125  return res;
1126 }
static const char type[]
Definition: chan_ooh323.c:109
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
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.
struct ast_taskprocessor * serializer
Serializer for observers.
Definition: sorcery.c:183
Structure for registered object type.
Definition: sorcery.c:148
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ ast_sorcery_object_set_copy_handler()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object
copyCopy handler

Definition at line 1128 of file sorcery.c.

References ao2_cleanup, ao2_find, copy(), OBJ_KEY, RAII_VAR, and ast_sorcery::types.

Referenced by ast_bucket_init(), and AST_TEST_DEFINE().

1129 {
1130  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1131 
1132  if (!object_type) {
1133  return;
1134  }
1135 
1136  object_type->copy = copy;
1137 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
static int copy(char *infile, char *outfile)
Utility function to copy a file.
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_sorcery_object_set_diff_handler()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object
diffDiff handler

Definition at line 1139 of file sorcery.c.

References ao2_cleanup, ao2_find, ast_sorcery_object_type::diff, OBJ_KEY, RAII_VAR, and ast_sorcery::types.

Referenced by AST_TEST_DEFINE().

1140 {
1141  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1142 
1143  if (!object_type) {
1144  return;
1145  }
1146 
1147  object_type->diff = diff;
1148 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
sorcery_diff_handler diff
Optional object diff callback.
Definition: sorcery.c:162
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_sorcery_object_set_extended()

int ast_sorcery_object_set_extended ( const void *  object,
const char *  name,
const char *  value 
)

Set an extended field value on a sorcery object.

Parameters
objectPointer to a sorcery object
nameName of the extended field
valueValue of the extended field
Return values
0success
-1failure
Note
The field name MUST begin with '@' to indicate it is an extended field.
If the extended field already exists it will be overwritten with the new value.

Definition at line 2344 of file sorcery.c.

References ast_variable_new, ast_variables_destroy(), ast_sorcery_object::extended, ast_variable::next, NULL, ast_sorcery_object_details::object, and RAII_VAR.

Referenced by AST_TEST_DEFINE(), and sorcery_extended_config_handler().

2345 {
2346  RAII_VAR(struct ast_variable *, field, NULL, ast_variables_destroy);
2347  struct ast_variable *extended = ast_variable_new(name, value, ""), *previous = NULL;
2348  const struct ast_sorcery_object_details *details = object;
2349 
2350  if (!extended) {
2351  return -1;
2352  }
2353 
2354  for (field = details->object->extended; field; previous = field, field = field->next) {
2355  if (!strcmp(field->name, name)) {
2356  if (previous) {
2357  previous->next = field->next;
2358  } else {
2359  details->object->extended = field->next;
2360  }
2361  field->next = NULL;
2362  break;
2363  }
2364  }
2365 
2366  extended->next = details->object->extended;
2367  details->object->extended = extended;
2368 
2369  return 0;
2370 }
struct ast_variable * next
static const char name[]
Definition: format_mp3.c:68
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_variable * extended
Extended object fields.
Definition: sorcery.c:138
#define ast_variable_new(name, value, filename)
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_set_has_dynamic_contents()

void ast_sorcery_object_set_has_dynamic_contents ( const void *  object)

Set the dynamic contents flag on a sorcery object.

Parameters
objectPointer to a sorcery object
Since
19
18.3.0
16.17.0

Definition at line 2379 of file sorcery.c.

References ast_sorcery_object::has_dynamic_contents, and ast_sorcery_object_details::object.

Referenced by ip_identify_apply().

2380 {
2381  const struct ast_sorcery_object_details *details = object;
2382 
2383  details->object->has_dynamic_contents = 1;
2384 }
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
unsigned int has_dynamic_contents
Whether this object has dynamic contents or not.
Definition: sorcery.c:144
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_object_unregister()

int ast_sorcery_object_unregister ( struct ast_sorcery sorcery,
const char *  type 
)

Unregister an object type.

Parameters
sorceryPointer to a sorcery structure
typeType of object
Return values
0success
-1failure

Definition at line 1061 of file sorcery.c.

References ACO_ITEM, ao2_cleanup, ao2_find, ao2_unlink_flags, ao2_unlock, ao2_wrlock, OBJ_NOLOCK, OBJ_SEARCH_KEY, ast_sorcery_object_type::type, aco_type::type, and ast_sorcery::types.

Referenced by unload_module().

1062 {
1063  struct ast_sorcery_object_type *object_type;
1064  int res = -1;
1065 
1066  ao2_wrlock(sorcery->types);
1067  object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY | OBJ_NOLOCK);
1068  if (object_type && object_type->type.type == ACO_ITEM) {
1069  ao2_unlink_flags(sorcery->types, object_type, OBJ_NOLOCK);
1070  res = 0;
1071  }
1072  ao2_unlock(sorcery->types);
1073 
1074  /* XXX may need to add an instance unregister observer callback on success. */
1075 
1076  ao2_cleanup(object_type);
1077  return res;
1078 }
static const char type[]
Definition: chan_ooh323.c:109
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ao2_wrlock(a)
Definition: astobj2.h:720
enum aco_type_t type
Structure for registered object type.
Definition: sorcery.c:148
struct aco_type type
Type details.
Definition: sorcery.c:177
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ao2_unlink_flags(container, obj, flags)
Definition: astobj2.h:1622

◆ ast_sorcery_objectset_apply()

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.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
objectsetObject set itself
Return values
0success
-1failure
Note
This operation is not atomic. If this fails it is possible for the object to be left with a partially applied object set.

Definition at line 1632 of file sorcery.c.

References aco_process_var(), ao2_cleanup, ao2_find, ast_variables_destroy(), ast_sorcery_object::id, ast_variable::next, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, ast_sorcery_object::type, and ast_sorcery::types.

Referenced by ast_ari_asterisk_update_object(), ast_sorcery_copy(), AST_TEST_DEFINE(), create_object(), sorcery_astdb_retrieve_fields_common(), sorcery_astdb_retrieve_id(), sorcery_astdb_retrieve_prefix(), sorcery_astdb_retrieve_regex(), sorcery_config_internal_load(), sorcery_realtime_retrieve_fields(), and sorcery_realtime_retrieve_multiple().

1633 {
1634  const struct ast_sorcery_object_details *details = object;
1635  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1636  RAII_VAR(struct ast_variable *, transformed, NULL, ast_variables_destroy);
1637  struct ast_variable *field;
1638  int res = 0;
1639 
1640  if (!object_type) {
1641  return -1;
1642  }
1643 
1644  if (object_type->transform && (transformed = object_type->transform(objectset))) {
1645  field = transformed;
1646  } else {
1647  field = objectset;
1648  }
1649 
1650  for (; field; field = field->next) {
1651  if ((res = aco_process_var(&object_type->type, details->object->id, field, object))) {
1652  break;
1653  }
1654  }
1655 
1656  if (!res && object_type->apply) {
1657  res = object_type->apply(sorcery, object);
1658  }
1659 
1660  return res;
1661 }
struct ast_variable * next
char * id
Unique identifier of this object.
Definition: sorcery.c:129
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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.
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_objectset_create2()

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.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
flagsFlags indicating which handler to use and in what order.
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_variable list must be destroyed using ast_variables_destroy

Definition at line 1511 of file sorcery.c.

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, AST_HANDLER_ONLY_LIST, AST_HANDLER_ONLY_STRING, AST_HANDLER_PREFER_LIST, AST_HANDLER_PREFER_STRING, ast_variable_list_append_hint(), get_multiple_fields_as_var_list(), get_single_field_as_var_list(), NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, tmp(), ast_sorcery_object::type, and ast_sorcery::types.

Referenced by aeap_cli_show(), ast_sip_sorcery_object_to_ami(), sip_aor_to_ami(), and stir_shaken_cli_show().

1513 {
1514  const struct ast_sorcery_object_details *details = object;
1515  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1516  struct ao2_iterator i;
1517  struct ast_sorcery_object_field *object_field;
1518  struct ast_variable *head = NULL;
1519  struct ast_variable *tail = NULL;
1520 
1521  if (!object_type) {
1522  return NULL;
1523  }
1524 
1525  i = ao2_iterator_init(object_type->fields, 0);
1526 
1527  for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1528  struct ast_variable *tmp;
1529 
1530  switch (flags) {
1532  if ((tmp = get_multiple_fields_as_var_list(object, object_field)) ||
1533  (tmp = get_single_field_as_var_list(object, object_field))) {
1534  break;
1535  }
1536  continue;
1538  if ((tmp = get_single_field_as_var_list(object, object_field)) ||
1539  (tmp = get_multiple_fields_as_var_list(object, object_field))) {
1540  break;
1541  }
1542  continue;
1543  case AST_HANDLER_ONLY_LIST:
1544  if ((tmp = get_multiple_fields_as_var_list(object, object_field))) {
1545  break;
1546  }
1547  continue;
1549  if ((tmp = get_single_field_as_var_list(object, object_field))) {
1550  break;
1551  }
1552  continue;
1553  default:
1554  continue;
1555  }
1556 
1557  tail = ast_variable_list_append_hint(&head, tail, tmp);
1558  }
1559 
1561 
1562  return head;
1563 }
Try both handlers, list first.
Definition: sorcery.h:134
#define OBJ_KEY
Definition: astobj2.h:1155
static struct ast_variable * get_single_field_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition: sorcery.c:1478
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
Use list handler only.
Definition: sorcery.h:140
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure for registered object field.
Definition: sorcery.c:205
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Use string handler only.
Definition: sorcery.h:137
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.
Definition: main/config.c:648
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
static struct ast_variable * get_multiple_fields_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
Definition: sorcery.c:1495
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Try both handlers, string first.
Definition: sorcery.h:131
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_objectset_json_create()

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.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
non-NULLsuccess
NULLif error occurred
Note
The returned ast_json object must be unreferenced using ast_json_unref

Definition at line 1565 of file sorcery.c.

References ao2_cleanup, ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_debug, ast_free, ast_json_object_create(), ast_json_object_set(), ast_json_string_create(), ast_json_unref(), ast_variables_destroy(), buf, ast_variable::name, ast_variable::next, NULL, OBJ_KEY, ast_sorcery_object_details::object, RAII_VAR, tmp(), ast_sorcery_object::type, ast_sorcery::types, value, and ast_variable::value.

Referenced by ast_bucket_file_json(), ast_bucket_json(), AST_TEST_DEFINE(), and sorcery_astdb_create().

1566 {
1567  const struct ast_sorcery_object_details *details = object;
1568  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
1569  struct ao2_iterator i;
1570  struct ast_sorcery_object_field *object_field;
1571  struct ast_json *json = ast_json_object_create();
1572  int res = 0;
1573 
1574  if (!object_type || !json) {
1575  ast_json_unref(json);
1576  return NULL;
1577  }
1578 
1579  i = ao2_iterator_init(object_type->fields, 0);
1580 
1581  for (; !res && (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
1582  if (object_field->multiple_handler) {
1583  struct ast_variable *tmp = NULL;
1584  struct ast_variable *field;
1585 
1586  if ((res = object_field->multiple_handler(object, &tmp))) {
1587  ast_variables_destroy(tmp);
1588  ao2_ref(object_field, -1);
1589  break;
1590  }
1591 
1592  for (field = tmp; field; field = field->next) {
1593  struct ast_json *value = ast_json_string_create(field->value);
1594 
1595  if (!value || ast_json_object_set(json, field->name, value)) {
1596  res = -1;
1597  break;
1598  }
1599  }
1600 
1601  ast_variables_destroy(tmp);
1602  } else if (object_field->handler) {
1603  char *buf = NULL;
1604  struct ast_json *value = NULL;
1605 
1606  if (object_field->handler(object, object_field->args, &buf)
1607  || !(value = ast_json_string_create(buf))
1608  || ast_json_object_set(json, object_field->name, value)) {
1609  ast_free(buf);
1610  ast_debug(5, "Skipping field '%s' for object type '%s'\n",
1611  object_field->name, object_type->name);
1612  continue;
1613  }
1614 
1615  ast_free(buf);
1616  } else {
1617  continue;
1618  }
1619  }
1620 
1622 
1623  /* If any error occurs we destroy the JSON object so a partial objectset is not returned */
1624  if (res) {
1625  ast_json_unref(json);
1626  json = NULL;
1627  }
1628 
1629  return json;
1630 }
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define OBJ_KEY
Definition: astobj2.h:1155
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:404
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
Structure for registered object field.
Definition: sorcery.c:205
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ast_free(a)
Definition: astmm.h:182
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition: json.c:389
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_observer_add()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object that should be observed
callbacksImplementation of the observer interface
Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 2386 of file sorcery.c.

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ao2_ref, ast_sorcery_object_type_observer::callbacks, ast_sorcery_internal_wizard::callbacks, NULL, OBJ_KEY, observer, RAII_VAR, and ast_sorcery::types.

Referenced by ast_bucket_file_observer_add(), ast_bucket_observer_add(), ast_res_pjsip_initialize_configuration(), ast_sip_initialize_distributor(), ast_sip_initialize_sorcery_location(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), load_module(), pjsip_outbound_registration_metrics_init(), and sip_options_init_task().

2387 {
2388  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
2390  int res;
2391 
2392  if (!object_type || !callbacks) {
2393  return -1;
2394  }
2395 
2396  if (!(observer = ao2_alloc(sizeof(*observer), NULL))) {
2397  return -1;
2398  }
2399 
2400  observer->callbacks = callbacks;
2401  res = 0;
2402  if (!ao2_link(object_type->observers, observer)) {
2403  res = -1;
2404  }
2405  ao2_ref(observer, -1);
2406 
2407  return res;
2408 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
Structure for registered object type observer.
Definition: sorcery.c:190
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_sorcery_instance_observer observer
const struct ast_sorcery_observer * callbacks
Pointer to the observer implementation.
Definition: sorcery.c:192
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_sorcery_observer_remove()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object that should no longer be observed
callbacksImplementation of the observer interface
Return values
0success
-1failure

Definition at line 2418 of file sorcery.c.

References ao2_callback, ao2_cleanup, ao2_find, NULL, OBJ_KEY, OBJ_NODATA, OBJ_UNLINK, RAII_VAR, sorcery_observer_remove(), and ast_sorcery::types.

Referenced by ast_bucket_file_observer_remove(), ast_bucket_observer_remove(), ast_res_pjsip_cleanup_options_handling(), ast_sip_destroy_distributor(), ast_sip_destroy_sorcery_location(), ast_sip_destroy_transport_management(), load_module(), pjsip_outbound_registration_metrics_init(), pjsip_outbound_registration_metrics_unload_cb(), and unload_module().

2419 {
2420  RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
2421  struct ast_sorcery_observer *cbs = (struct ast_sorcery_observer *) callbacks;/* Remove const for traversal. */
2422 
2423  if (!sorcery) {
2424  return;
2425  }
2426  object_type = ao2_find(sorcery->types, type, OBJ_KEY);
2427  if (!object_type) {
2428  return;
2429  }
2430 
2431  ao2_callback(object_type->observers, OBJ_NODATA | OBJ_UNLINK,
2433 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static int sorcery_observer_remove(void *obj, void *arg, int flags)
Internal callback function for removing an observer.
Definition: sorcery.c:2411
#define NULL
Definition: resample.c:96
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Interface for a sorcery object type observer.
Definition: sorcery.h:332
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_sorcery_ref()

void ast_sorcery_ref ( struct ast_sorcery sorcery)

Increase the reference count of a sorcery structure.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1473 of file sorcery.c.

References ao2_ref.

1474 {
1475  ao2_ref(sorcery, +1);
1476 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ ast_sorcery_reload()

void ast_sorcery_reload ( const struct ast_sorcery sorcery)

Inform any wizards to reload persistent objects.

Parameters
sorceryPointer to a sorcery structure

Definition at line 1408 of file sorcery.c.

References ao2_callback, ast_sorcery::module_name, NOTIFY_INSTANCE_OBSERVERS, OBJ_NODATA, ast_sorcery::observers, sorcery, sorcery_load_details::sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by ast_res_pjsip_reload_configuration(), AST_TEST_DEFINE(), and reload_module().

1409 {
1410  struct sorcery_load_details details = {
1411  .sorcery = sorcery,
1412  .reload = 1,
1413  };
1414 
1415  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loading,
1416  sorcery->module_name, sorcery, 1);
1417 
1418  ao2_callback(sorcery->types, OBJ_NODATA, sorcery_object_load, &details);
1419 
1420  NOTIFY_INSTANCE_OBSERVERS(sorcery->observers, instance_loaded,
1421  sorcery->module_name, sorcery, 1);
1422 
1423 }
char * module_name
Pointer to module_name in the associated sorcery_proxy.
Definition: sorcery.c:238
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
struct ao2_container * observers
Observers.
Definition: sorcery.c:235
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244
Structure for passing load/reload details.
Definition: sorcery.c:242
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
static struct ast_sorcery * sorcery
#define NOTIFY_INSTANCE_OBSERVERS(container, callback,...)
Definition: sorcery.c:79
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336

◆ ast_sorcery_reload_object()

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.

Parameters
sorceryPointer to a sorcery structure
typeName of the object type to reload

Definition at line 1442 of file sorcery.c.

References ao2_cleanup, ao2_find, OBJ_KEY, RAII_VAR, sorcery, sorcery_load_details::sorcery, sorcery_object_load(), and ast_sorcery::types.

Referenced by apply_list_configuration(), ast_sip_initialize_distributor(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), load_module(), load_users(), and reload_module().

1443 {
1444  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1445  struct sorcery_load_details details = {
1446  .sorcery = sorcery,
1447  .reload = 1,
1448  };
1449 
1450  if (!object_type) {
1451  return;
1452  }
1453 
1454  sorcery_object_load(object_type, &details, 0);
1455 }
static const char type[]
Definition: chan_ooh323.c:109
#define OBJ_KEY
Definition: astobj2.h:1155
const struct ast_sorcery * sorcery
Sorcery structure in use.
Definition: sorcery.c:244
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure for passing load/reload details.
Definition: sorcery.c:242
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int sorcery_object_load(void *obj, void *arg, int flags)
Definition: sorcery.c:1336

◆ ast_sorcery_retrieve_by_fields()

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.

Since
13.9.0
Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
flagsFlags to control behavior
fieldsOptional object fields and values to match against
Return values
non-NULLif found
NULLif not found
Note
If the AST_RETRIEVE_FLAG_MULTIPLE flag is specified the returned value will be an ao2_container that must be unreferenced after use.
If the AST_RETRIEVE_FLAG_ALL flag is used you may omit fields to retrieve all objects of the given type.
The fields parameter can contain realtime-style expressions in variable->name. All operators defined for ast_strings_match can be used except for regex as there's no common support for regex in the realtime backends at this time. If multiple variables are in the fields list, all must match for an object to be returned. See ast_strings_match for more information.

Example:

The following code can be significantly faster when a realtime backend is in use because the expression "qualify_frequency > 0" is passed to the database to limit the number of rows returned.

struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", ""); struct ao2_container *aors;

if (!var) { return; }

aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);

Definition at line 1897 of file sorcery.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_find, AST_RETRIEVE_FLAG_MULTIPLE, AST_VECTOR_CALLBACK, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, NULL, OBJ_KEY, RAII_VAR, ast_sorcery_wizard::retrieve_fields, ast_sorcery_wizard::retrieve_multiple, sorcery_cache_create(), ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by acl_on_rx_msg(), aeap_server_get_all(), ami_show_registration_contact_statuses(), ami_show_resource_lists(), ast_mwi_mailbox_get_all(), ast_sip_get_endpoints(), ast_sip_initialize_sorcery_transport(), ast_sip_initialize_system(), ast_sip_location_prune_boot_contacts(), AST_TEST_DEFINE(), asterisk_publication_send_refresh(), auth_observer(), check_expiration_thread(), cli_complete_registration(), cli_contact_get_container(), cli_get_aors(), cli_get_auths(), cli_iterator(), common_identify(), create_mwi_subscriptions(), format_ami_endpoint_identify(), get_all_contacts(), get_publishes_and_update_state(), get_registrations(), get_system_cfg(), global_loaded_observer(), handle_export_primitives(), load_all_endpoints(), load_users(), memory_cache_populate(), process_nat(), sip_options_aor_observer_modified_task(), sip_options_synchronize_task(), sorcery_memory_cache_ami_populate(), stale_cache_update(), stir_shaken_certificate_get_all(), stir_shaken_certificate_get_by_caller_id_number(), stir_shaken_general_get(), stir_shaken_store_get_all(), and subscription_persistence_load().

1898 {
1899  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1900  void *object = NULL;
1901  int i;
1902  unsigned int cached = 0;
1903 
1904  if (!object_type) {
1905  return NULL;
1906  }
1907 
1908  /* If returning multiple objects create a container to store them in */
1909  if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1911  if (!object) {
1912  return NULL;
1913  }
1914  }
1915 
1916  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1917  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1919  AST_VECTOR_GET(&object_type->wizards, i);
1920 
1921  if ((flags & AST_RETRIEVE_FLAG_MULTIPLE)) {
1922  if (wizard->wizard->callbacks.retrieve_multiple) {
1923  wizard->wizard->callbacks.retrieve_multiple(sorcery, wizard->data, object_type->name, object, fields);
1924  }
1925  } else if (fields && wizard->wizard->callbacks.retrieve_fields) {
1926  if (wizard->wizard->callbacks.retrieve_fields) {
1927  object = wizard->wizard->callbacks.retrieve_fields(sorcery, wizard->data, object_type->name, fields);
1928  }
1929  }
1930 
1931  if (((flags & AST_RETRIEVE_FLAG_MULTIPLE) && (!ao2_container_count(object) || !wizard->caching)) || !object) {
1932  continue;
1933  }
1934 
1935  cached = wizard->caching;
1936 
1937  break;
1938  }
1939 
1940  /* If we are returning a single object and it came from a non-cache source create it in any caches */
1941  if (!(flags & AST_RETRIEVE_FLAG_MULTIPLE) && !cached && object) {
1942  AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, object, 0);
1943  }
1944  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1945 
1946  return object;
1947 }
static const char type[]
Definition: chan_ooh323.c:109
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int sorcery_cache_create(void *obj, void *arg, int flags)
Internal function used to create an object in caching wizards.
Definition: sorcery.c:1839
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
Return all matching objects.
Definition: sorcery.h:120
#define NULL
Definition: resample.c:96
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
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.
Definition: sorcery.h:310
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
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.
Definition: sorcery.h:313
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * data
Unique data for the wizard.
Definition: sorcery.c:108
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
Definition: vector.h:768
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_sorcery_retrieve_by_id()

void* ast_sorcery_retrieve_by_id ( const struct ast_sorcery sorcery,
const char *  type,
const char *  id 
)

Retrieve an object using its unique identifier.

Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
idUnique object identifier
Return values
non-NULLif found
NULLif not found

Definition at line 1853 of file sorcery.c.

References ao2_find, ao2_ref, ast_strlen_zero(), AST_VECTOR_CALLBACK, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, ast_sorcery_object_type::name, NULL, OBJ_SEARCH_KEY, ast_sorcery_wizard::retrieve_id, sorcery, sorcery_details::sorcery, sorcery_cache_create(), ast_sorcery::types, ast_sorcery_object_wizard::wizard, and ast_sorcery_object_type::wizards.

Referenced by aeap_server_get(), ami_show_endpoint(), ami_sip_qualify(), anonymous_identify(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), ast_bucket_file_retrieve(), ast_bucket_retrieve(), ast_mwi_mailbox_get(), ast_mwi_mailbox_update(), ast_sip_default_outbound_endpoint(), ast_sip_for_each_auth(), ast_sip_location_retrieve_aor(), ast_sip_location_retrieve_contact(), ast_sip_retrieve_auths(), ast_sip_retrieve_auths_vector(), ast_sip_set_tpselector_from_transport_name(), AST_TEST_DEFINE(), asterisk_publication_devicestate_state_change(), asterisk_publication_mwi_state_change(), asterisk_publication_new(), chan_pjsip_devicestate(), check_state(), cli_aor_retrieve_by_id(), cli_endpoint_retrieve_by_id(), cli_iterate(), cli_qualify(), cli_reload_qualify_aor(), cli_reload_qualify_endpoint(), cli_retrieve_by_id(), cli_show_qualify_endpoint(), common_identify(), contact_observer_updated(), create_rtp(), find_aor(), find_aor_name(), find_endpoint(), format_ami_endpoint_transport(), get_log_mappings(), get_write_timeout(), handle_atsign(), handle_single_token(), handle_slash(), line_identify(), load_endpoint(), mwi_contact_changed(), mwi_contact_deleted(), mwi_subscription_shutdown(), on_rx_process_symmetric_transport(), pjsip_acf_dial_contacts_read(), pjsip_aor_function_read(), pjsip_contact_function_read(), pjsip_endpoint_function_read(), process_nat(), publish_request_initial(), push_notify(), request(), retrieve_resource_list(), send_unsolicited_mwi_notify(), sip_options_contact_add_management_task(), sip_options_qualify_contact(), sorcery_function_read(), sorcery_memory_cache_ami_populate(), sorcery_memory_cache_thrash_retrieve(), stale_item_update(), stir_shaken_certificate_get(), stir_shaken_store_get(), sub_persistence_recreate(), t38_initialize_session(), and transfer().

1854 {
1855  struct ast_sorcery_object_type *object_type;
1856  void *object = NULL;
1857  int i;
1858  unsigned int cached = 0;
1859 
1860  if (ast_strlen_zero(id)) {
1861  return NULL;
1862  }
1863 
1864  object_type = ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
1865  if (!object_type) {
1866  return NULL;
1867  }
1868 
1869  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1870  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1872  AST_VECTOR_GET(&object_type->wizards, i);
1873 
1874  if (wizard->wizard->callbacks.retrieve_id &&
1875  !(object = wizard->wizard->callbacks.retrieve_id(sorcery, wizard->data, object_type->name, id))) {
1876  continue;
1877  }
1878 
1879  cached = wizard->caching;
1880  break;
1881  }
1882 
1883  if (!cached && object) {
1884  struct sorcery_details sdetails = {
1885  .sorcery = sorcery,
1886  .obj = object,
1887  };
1888 
1889  AST_VECTOR_CALLBACK(&object_type->wizards, sorcery_cache_create, NULL, &sdetails, 0);
1890  }
1891  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1892 
1893  ao2_ref(object_type, -1);
1894  return object;
1895 }
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition: sorcery.c:1833
static const char type[]
Definition: chan_ooh323.c:109
Structure used when calling create, update, or delete.
Definition: sorcery.c:1831
static int sorcery_cache_create(void *obj, void *arg, int flags)
Internal function used to create an object in caching wizards.
Definition: sorcery.c:1839
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
Structure for registered object type.
Definition: sorcery.c:148
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition: sorcery.c:165
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * data
Unique data for the wizard.
Definition: sorcery.c:108
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static struct ast_sorcery * sorcery
void *(* retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
Callback for retrieving an object using an id.
Definition: sorcery.h:296
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
Definition: vector.h:768
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
char name[MAX_OBJECT_TYPE]
Unique name of the object type.
Definition: sorcery.c:150

◆ ast_sorcery_retrieve_by_module_name()

struct ast_sorcery* ast_sorcery_retrieve_by_module_name ( const char *  module_name)

Search function for sorcery instances.

Retrieves an existing sorcery instance by module name.

Definition at line 672 of file sorcery.c.

References ao2_weakproxy_find, and OBJ_SEARCH_KEY.

Referenced by ast_ari_asterisk_delete_object(), ast_ari_asterisk_get_object(), ast_ari_asterisk_update_object(), AST_TEST_DEFINE(), and sorcery_function_read().

673 {
674  return ao2_weakproxy_find(instances, module_name, OBJ_SEARCH_KEY, "");
675 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
static struct ao2_container * instances
Registered sorcery instances.
Definition: sorcery.c:284
#define ao2_weakproxy_find(c, arg, flags, tag)
Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object...
Definition: astobj2.h:1768

◆ ast_sorcery_retrieve_by_prefix()

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.

Since
13.19.0
Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
prefixObject id prefix
prefix_lenThe length of prefix in bytes
Return values
non-NULLif error occurs
NULLsuccess
Note
The prefix is matched in a case sensitive manner.

Definition at line 1984 of file sorcery.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_find, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, NULL, OBJ_KEY, RAII_VAR, ast_sorcery_wizard::retrieve_prefix, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by aor_deleted_observer(), ast_sip_location_retrieve_aor_contacts_nolock_filtered(), cli_complete_endpoint(), and sip_options_apply_aor_configuration().

1985 {
1986  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1987  struct ao2_container *objects;
1988  int i;
1989 
1990  if (!object_type) {
1991  return NULL;
1992  }
1993 
1995  if (!objects) {
1996  return NULL;
1997  }
1998 
1999  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2000  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2002  AST_VECTOR_GET(&object_type->wizards, i);
2003 
2004  if (!wizard->wizard->callbacks.retrieve_prefix) {
2005  continue;
2006  }
2007 
2008  wizard->wizard->callbacks.retrieve_prefix(sorcery, wizard->data, object_type->name, objects, prefix, prefix_len);
2009 
2010  if (wizard->caching && ao2_container_count(objects)) {
2011  break;
2012  }
2013  }
2014  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
2015 
2016  return objects;
2017 }
static const char type[]
Definition: chan_ooh323.c:109
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
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.
Definition: sorcery.h:302
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * data
Unique data for the wizard.
Definition: sorcery.c:108
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
Generic container type.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_sorcery_retrieve_by_regex()

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.

Parameters
sorceryPointer to a sorcery structure
typeType of object to retrieve
regexRegular expression
Return values
non-NULLif error occurs
NULLsuccess
Note
The provided regex is treated as extended case sensitive.

Definition at line 1949 of file sorcery.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_count(), ao2_find, AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, ast_sorcery_internal_wizard::callbacks, ast_sorcery_object_wizard::data, NULL, OBJ_KEY, RAII_VAR, ast_sorcery_wizard::retrieve_regex, ast_sorcery::types, and ast_sorcery_object_wizard::wizard.

Referenced by ast_mwi_mailbox_get_by_regex(), AST_TEST_DEFINE(), cli_aor_get_container(), cli_contact_get_container(), cli_endpoint_get_container(), and cli_get_container().

1950 {
1951  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
1952  struct ao2_container *objects;
1953  int i;
1954 
1955  if (!object_type) {
1956  return NULL;
1957  }
1958 
1960  if (!objects) {
1961  return NULL;
1962  }
1963 
1964  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
1965  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
1967  AST_VECTOR_GET(&object_type->wizards, i);
1968 
1969  if (!wizard->wizard->callbacks.retrieve_regex) {
1970  continue;
1971  }
1972 
1973  wizard->wizard->callbacks.retrieve_regex(sorcery, wizard->data, object_type->name, objects, regex);
1974 
1975  if (wizard->caching && ao2_container_count(objects)) {
1976  break;
1977  }
1978  }
1979  AST_VECTOR_RW_UNLOCK(&object_type->wizards);
1980 
1981  return objects;
1982 }
static const char type[]
Definition: chan_ooh323.c:109
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
struct ast_sorcery_wizard callbacks
Wizard interface itself.
Definition: sorcery.c:96
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.
Definition: sorcery.h:299
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_sorcery_internal_wizard * wizard
Wizard interface itself.
Definition: sorcery.c:105
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * data
Unique data for the wizard.
Definition: sorcery.c:108
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
Generic container type.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_sorcery_update()

int ast_sorcery_update ( const struct ast_sorcery sorcery,
void *  object 
)

Update an object.

Parameters
sorceryPointer to a sorcery structure
objectPointer to a sorcery object
Return values
0success
-1failure

Definition at line 2145 of file sorcery.c.

References ao2_cleanup, ao2_container_count(), ao2_find, ast_taskprocessor_push(), AST_VECTOR_GET, AST_VECTOR_RW_RDLOCK, AST_VECTOR_RW_UNLOCK, AST_VECTOR_SIZE, ast_sorcery_object_wizard::caching, CMP_MATCH, NULL, OBJ_KEY, ast_sorcery_object_details::object, sorcery_observer_invocation::object_type, RAII_VAR, ast_sorcery_object_type::serializer, sorcery, sorcery_details::sorcery, sorcery_observer_invocation_alloc(), sorcery_observers_notify_update(), sorcery_wizard_update(), ast_sorcery_object::type, ast_sorcery::types, and ast_sorcery_object_type::wizards.

Referenced by ast_ari_asterisk_update_object(), ast_bucket_file_update(), ast_mwi_mailbox_update(), ast_sip_location_update_contact(), AST_TEST_DEFINE(), sorcery_memory_cache_thrash_update(), and subscription_persistence_update().

2146 {
2147  const struct ast_sorcery_object_details *details = object;
2148  RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
2149  struct ast_sorcery_object_wizard *object_wizard = NULL;
2150  struct ast_sorcery_object_wizard *found_wizard;
2151  int i;
2152  struct sorcery_details sdetails = {
2153  .sorcery = sorcery,
2154  .obj = object,
2155  };
2156 
2157  if (!object_type) {
2158  return -1;
2159  }
2160 
2161  AST_VECTOR_RW_RDLOCK(&object_type->wizards);
2162  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2163  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2164  if (!found_wizard->caching
2165  && sorcery_wizard_update(found_wizard, &sdetails) == CMP_MATCH) {
2166  object_wizard = found_wizard;
2167  }
2168  }
2169 
2170  if (object_wizard) {
2171  for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
2172  found_wizard = AST_VECTOR_GET(&object_type->wizards, i);
2173  if (found_wizard->caching) {
2174  sorcery_wizard_update(found_wizard, &sdetails);
2175  }
2176  }
2177 
2178  if (ao2_container_count(object_type->observers)) {
2179  struct sorcery_observer_invocation *invocation;
2180 
2181  invocation = sorcery_observer_invocation_alloc(object_type, object);
2182  if (invocation
2184  invocation)) {
2185  ao2_cleanup(invocation);
2186  }
2187  }
2188  }
2189 
2191 
2192  return object_wizard ? 0 : -1;
2193 }
const struct ast_sorcery * sorcery
Pointer to the sorcery instance.
Definition: sorcery.c:1833
static struct sorcery_observer_invocation * sorcery_observer_invocation_alloc(struct ast_sorcery_object_type *object_type, void *object)
Allocator function for observer invocation.
Definition: sorcery.c:1292
Structure used when calling create, update, or delete.
Definition: sorcery.c:1831
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:900
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:880
#define NULL
Definition: resample.c:96
Structure used for observer invocations.
Definition: sorcery.c:196
unsigned int caching
Wizard is acting as an object cache.
Definition: sorcery.c:111
struct ast_taskprocessor * serializer
Serializer for observers.
Definition: sorcery.c:183
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.
Definition: sorcery.c:2131
Structure for registered object type.
Definition: sorcery.c:148
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
Structure which contains details about a sorcery object.
Definition: sorcery.h:350
struct ao2_container * types
Container for known object types.
Definition: sorcery.c:232
struct ast_sorcery_object_wizards wizards
Wizard instances.
Definition: sorcery.c:165
static int sorcery_observers_notify_update(void *data)
Internal callback function which notifies observers that an object has been updated.
Definition: sorcery.c:2120
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
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.
static struct ast_sorcery * sorcery
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure for a wizard instance which operates on objects.
Definition: sorcery.c:103
struct ast_sorcery_object_type * object_type
Pointer to the object type.
Definition: sorcery.c:198
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
char type[MAX_OBJECT_TYPE]
Type of object.
Definition: sorcery.c:132
struct ast_sorcery_object * object
Pointer to internal sorcery object information.
Definition: sorcery.h:352

◆ ast_sorcery_wizard_observer_add()

int ast_sorcery_wizard_observer_add ( struct ast_sorcery_wizard wizard,
const struct ast_sorcery_wizard_observer callbacks 
)

Add an observer to a sorcery wizard.

Parameters
sorceryPointer to a previously registered wizard structure
callbacksImplementation of the wizard observer interface

A wizard observer is notified... Before a wizard is loaded or reloaded. After a wizard is loaded or reloaded.

Return values
0success
-1failure
Note
You must be ready to accept observer invocations before this function is called

Definition at line 543 of file sorcery.c.

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ao2_ref, sorcery_wizard_observer::callbacks, ast_sorcery_internal_wizard::callbacks, ast_sorcery_wizard::name, NULL, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by AST_TEST_DEFINE().

545 {
546  RAII_VAR(struct ast_sorcery_internal_wizard *, wizard,
547  interface ? ao2_find(wizards, interface->name, OBJ_SEARCH_KEY) : NULL,
548  ao2_cleanup);
549 
550  if (wizard) {
551  struct sorcery_wizard_observer *cb;
552 
553  cb = ao2_alloc(sizeof(*cb), NULL);
554  if (!cb) {
555  return -1;
556  }
557 
558  cb->callbacks = callbacks;
559  ao2_link(wizard->observers, cb);
560  ao2_ref(cb, -1);
561 
562  return 0;
563  }
564 
565  return -1;
566 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
const struct ast_sorcery_wizard_observer * callbacks
Definition: sorcery.c:277
#define NULL
Definition: resample.c:96
const char * name
Name of the wizard.
Definition: sorcery.h:278
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure for an internal wizard instance.
Definition: sorcery.c:89
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static struct ao2_container * wizards
Registered sorcery wizards.
Definition: sorcery.c:257
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A wizard observer wrapper.
Definition: sorcery.c:276
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_sorcery_wizard_observer_remove()

void ast_sorcery_wizard_observer_remove ( struct ast_sorcery_wizard wizard,
const struct ast_sorcery_wizard_observer callbacks 
)

Remove an observer from a sorcery wizard.

Parameters
sorceryPointer to a sorcery structure
callbacksImplementation of the wizard observer interface

Definition at line 568 of file sorcery.c.

References ao2_callback, ao2_cleanup, ao2_find, ast_sorcery_wizard::name, NULL, OBJ_NODATA, OBJ_SEARCH_KEY, OBJ_UNLINK, RAII_VAR, and sorcery_generic_observer_remove().

Referenced by AST_TEST_DEFINE().

570 {
571  RAII_VAR(struct ast_sor