Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions
optional_api.c File Reference
#include "asterisk.h"
#include "asterisk/optional_api.h"
#include "asterisk/utils.h"
#include "asterisk/vector.h"
Include dependency graph for optional_api.c:

Go to the source code of this file.

Data Structures

struct  optional_api
 An optional API. More...
 
struct  optional_api_user
 A user of an optional API. More...
 

Macros

#define OPTIONAL_API_SYMNAME_CMP(ele, value)   (!strcmp(ele->symname, value))
 
#define USER_OPTIONAL_REF_CMP(ele, value)   (ele->optional_ref == value)
 

Functions

void ast_optional_api_provide (const char *symname, ast_optional_fn impl)
 
void ast_optional_api_unprovide (const char *symname, ast_optional_fn impl)
 
void ast_optional_api_unuse (const char *symname, ast_optional_fn *optional_ref, const char *module)
 
void ast_optional_api_use (const char *symname, ast_optional_fn *optional_ref, ast_optional_fn stub, const char *module)
 
 AST_VECTOR (struct optional_api *)
 Free an optional_api_user. More...
 
static struct optional_apiget_api (const char *symname)
 Gets (or creates) the optional_api for the given function. More...
 
static struct optional_apioptional_api_create (const char *symname)
 Create and link an optional_api. More...
 
static void optional_api_destroy (struct optional_api *api)
 Free an optional_api. More...
 
static void optional_api_set_impl (struct optional_api *api, ast_optional_fn impl)
 Sets the implementation function pointer for an api. More...
 
static struct optional_api_useroptional_api_user_create (ast_optional_fn *optional_ref, ast_optional_fn stub, const char *module)
 Create an optional_api_user. More...
 
static void optional_api_user_relink (struct optional_api_user *user, struct optional_api *api)
 Re-links a given user against its associated api. More...
 

Macro Definition Documentation

◆ OPTIONAL_API_SYMNAME_CMP

#define OPTIONAL_API_SYMNAME_CMP (   ele,
  value 
)    (!strcmp(ele->symname, value))

Referenced by get_api().

◆ USER_OPTIONAL_REF_CMP

#define USER_OPTIONAL_REF_CMP (   ele,
  value 
)    (ele->optional_ref == value)

Referenced by ast_optional_api_unuse().

Function Documentation

◆ ast_optional_api_provide()

void ast_optional_api_provide ( const char *  symname,
ast_optional_fn  impl 
)

Definition at line 212 of file optional_api.c.

References get_api(), and optional_api_set_impl().

Referenced by AST_TEST_DEFINE().

213 {
214  struct optional_api *api;
215 
216  api = get_api(symname);
217  if (api) {
219  }
220 }
An optional API.
Definition: optional_api.c:57
static void optional_api_set_impl(struct optional_api *api, ast_optional_fn impl)
Sets the implementation function pointer for an api.
Definition: optional_api.c:198
ast_optional_fn impl
Definition: optional_api.c:59
static struct optional_api * get_api(const char *symname)
Gets (or creates) the optional_api for the given function.
Definition: optional_api.c:158

◆ ast_optional_api_unprovide()

void ast_optional_api_unprovide ( const char *  symname,
ast_optional_fn  impl 
)

Definition at line 222 of file optional_api.c.

References get_api(), and optional_api_set_impl().

Referenced by AST_TEST_DEFINE().

223 {
224  struct optional_api *api;
225 
226  api = get_api(symname);
227  if (api) {
228  optional_api_set_impl(api, 0);
229  }
230 }
An optional API.
Definition: optional_api.c:57
static void optional_api_set_impl(struct optional_api *api, ast_optional_fn impl)
Sets the implementation function pointer for an api.
Definition: optional_api.c:198
static struct optional_api * get_api(const char *symname)
Gets (or creates) the optional_api for the given function.
Definition: optional_api.c:158

◆ ast_optional_api_unuse()

void ast_optional_api_unuse ( const char *  symname,
ast_optional_fn *  optional_ref,
const char *  module 
)

Definition at line 257 of file optional_api.c.

References AST_VECTOR_REMOVE_CMP_UNORDERED, AST_VECTOR_SIZE, get_api(), optional_api::impl, optional_api_destroy(), and USER_OPTIONAL_REF_CMP.

Referenced by AST_TEST_DEFINE().

259 {
260  struct optional_api *api;
261 
262  api = get_api(symname);
263  if (api) {
264  AST_VECTOR_REMOVE_CMP_UNORDERED(&api->users, optional_ref, USER_OPTIONAL_REF_CMP, optional_api_user_destroy);
265  if (!api->impl && !AST_VECTOR_SIZE(&api->users)) {
267  }
268  }
269 }
An optional API.
Definition: optional_api.c:57
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
static void optional_api_destroy(struct optional_api *api)
Free an optional_api.
Definition: optional_api.c:118
ast_optional_fn impl
Definition: optional_api.c:59
#define USER_OPTIONAL_REF_CMP(ele, value)
static struct optional_api * get_api(const char *symname)
Gets (or creates) the optional_api for the given function.
Definition: optional_api.c:158
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_optional_api_use()

void ast_optional_api_use ( const char *  symname,
ast_optional_fn *  optional_ref,
ast_optional_fn  stub,
const char *  module 
)

Definition at line 232 of file optional_api.c.

References ast_do_crash(), AST_VECTOR_APPEND, get_api(), optional_api_user_create(), optional_api_user_relink(), and user.

Referenced by AST_TEST_DEFINE().

234 {
235  struct optional_api_user *user;
236  struct optional_api *api;
237 
238  api = get_api(symname);
239  if (!api) {
240  return;
241  }
242 
243  user = optional_api_user_create(optional_ref, stub, module);
244  if (!user) {
245  return;
246  }
247 
248  /* Add user to the API */
249  if (!AST_VECTOR_APPEND(&api->users, user)) {
250  optional_api_user_relink(user, api);
251  } else {
252  optional_api_user_destroy(user);
253  ast_do_crash();
254  }
255 }
static char user[512]
An optional API.
Definition: optional_api.c:57
static struct optional_api_user * optional_api_user_create(ast_optional_fn *optional_ref, ast_optional_fn stub, const char *module)
Create an optional_api_user.
Definition: optional_api.c:93
A user of an optional API.
Definition: optional_api.c:47
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
Definition: main/utils.c:2552
static void optional_api_user_relink(struct optional_api_user *user, struct optional_api *api)
Re-links a given user against its associated api.
Definition: optional_api.c:181
static struct optional_api * get_api(const char *symname)
Gets (or creates) the optional_api for the given function.
Definition: optional_api.c:158

◆ AST_VECTOR()

AST_VECTOR ( struct optional_api )

Free an optional_api_user.

Vector of optional_api functions

Parameters
userUser struct to free.

Definition at line 67 of file optional_api.c.

References ast_free, optional_api_user::optional_ref, and optional_api_user::stub.

78 {
79  *user->optional_ref = user->stub;
80  ast_free(user);
81 }
#define ast_free(a)
Definition: astmm.h:182
structure to hold users read from users.conf

◆ get_api()

static struct optional_api* get_api ( const char *  symname)
static

Gets (or creates) the optional_api for the given function.

Parameters
sysnameName of the function to look up.
Returns
Corresponding optional_api.
NULL on error.

Definition at line 158 of file optional_api.c.

References AST_VECTOR_GET_CMP, optional_api_create(), and OPTIONAL_API_SYMNAME_CMP.

Referenced by ast_optional_api_provide(), ast_optional_api_unprovide(), ast_optional_api_unuse(), and ast_optional_api_use().

159 {
160  struct optional_api **api;
161 
162  /* Find one, if we already have it */
163  api = AST_VECTOR_GET_CMP(&apis, symname, OPTIONAL_API_SYMNAME_CMP);
164  if (api) {
165  return *api;
166  }
167 
168  /* API not found. Build one */
169  return optional_api_create(symname);
170 }
An optional API.
Definition: optional_api.c:57
static struct optional_api * optional_api_create(const char *symname)
Create and link an optional_api.
Definition: optional_api.c:134
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:733
#define OPTIONAL_API_SYMNAME_CMP(ele, value)

◆ optional_api_create()

static struct optional_api* optional_api_create ( const char *  symname)
static

Create and link an optional_api.

Parameters
symnameName of the optional function.
Returns
New optional_api.
NULL on error.

Definition at line 134 of file optional_api.c.

References ast_calloc, ast_do_crash(), ast_free, AST_VECTOR_APPEND, and NULL.

Referenced by get_api().

135 {
136  struct optional_api *api;
137 
138  api = ast_calloc(1, sizeof(*api) + strlen(symname) + 1);
139  if (!api || AST_VECTOR_APPEND(&apis, api)) {
140  ast_free(api);
141  ast_do_crash();
142 
143  return NULL;
144  }
145 
146  strcpy(api->symname, symname); /* SAFE */
147 
148  return api;
149 }
An optional API.
Definition: optional_api.c:57
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define NULL
Definition: resample.c:96
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
Definition: main/utils.c:2552
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ optional_api_destroy()

static void optional_api_destroy ( struct optional_api api)
static

Free an optional_api.

Parameters
apiAPI struct to free.

Definition at line 118 of file optional_api.c.

References ast_free, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_FREE, and AST_VECTOR_REMOVE_CMP_UNORDERED.

Referenced by ast_optional_api_unuse(), and optional_api_set_impl().

119 {
122  AST_VECTOR_CALLBACK_VOID(&api->users, optional_api_user_destroy);
123  AST_VECTOR_FREE(&api->users);
124  ast_free(api);
125 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
#define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value)
Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED()
Definition: vector.h:564
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865

◆ optional_api_set_impl()

static void optional_api_set_impl ( struct optional_api api,
ast_optional_fn  impl 
)
static

Sets the implementation function pointer for an api.

Parameters
apiAPI to implement/stub out.
implPointer to implementation function. Can be 0 to remove implementation.

Definition at line 198 of file optional_api.c.

References AST_VECTOR_CALLBACK_VOID, AST_VECTOR_SIZE, optional_api::impl, optional_api_destroy(), and optional_api_user_relink().

Referenced by ast_optional_api_provide(), and ast_optional_api_unprovide().

200 {
201  api->impl = impl;
202 
203  /* re-link all users */
204  if (AST_VECTOR_SIZE(&api->users)) {
206  } else if (!impl) {
207  /* No users or impl means we should delete this api. */
209  }
210 }
static void optional_api_destroy(struct optional_api *api)
Free an optional_api.
Definition: optional_api.c:118
ast_optional_fn impl
Definition: optional_api.c:59
static void optional_api_user_relink(struct optional_api_user *user, struct optional_api *api)
Re-links a given user against its associated api.
Definition: optional_api.c:181
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865

◆ optional_api_user_create()

static struct optional_api_user* optional_api_user_create ( ast_optional_fn *  optional_ref,
ast_optional_fn  stub,
const char *  module 
)
static

Create an optional_api_user.

Parameters
optional_refPointer-to-function-pointer to link to impl/stub.
stubStub function to link to when impl is not available.
moduleName of the module requesting the API.
Returns
New optional_api_user.
NULL on error.

Definition at line 93 of file optional_api.c.

References ast_calloc, ast_do_crash(), optional_api_user::module, NULL, optional_api_user::optional_ref, optional_api_user::stub, and user.

Referenced by ast_optional_api_use().

95 {
96  struct optional_api_user *user;
97  size_t size = sizeof(*user) + strlen(module) + 1;
98 
99  user = ast_calloc(1, size);
100  if (!user) {
101  ast_do_crash();
102 
103  return NULL;
104  }
105 
106  user->optional_ref = optional_ref;
107  user->stub = stub;
108  strcpy(user->module, module); /* SAFE */
109 
110  return user;
111 }
static char user[512]
A user of an optional API.
Definition: optional_api.c:47
#define NULL
Definition: resample.c:96
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
Definition: main/utils.c:2552
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
ast_optional_fn * optional_ref
Definition: optional_api.c:49
ast_optional_fn stub
Definition: optional_api.c:51

◆ optional_api_user_relink()

static void optional_api_user_relink ( struct optional_api_user user,
struct optional_api api 
)
static

Re-links a given user against its associated api.

If the api has an implementation, the user is linked to that implementation. Otherwise, the user is linked to its stub.

Parameters
useroptional_api_user to link.
apioptional_api to link.

Definition at line 181 of file optional_api.c.

References optional_api::impl, optional_api_user::optional_ref, and optional_api_user::stub.

Referenced by ast_optional_api_use(), and optional_api_set_impl().

183 {
184  if (api->impl && *user->optional_ref != api->impl) {
185  *user->optional_ref = api->impl;
186  } else if (!api->impl && *user->optional_ref != user->stub) {
187  *user->optional_ref = user->stub;
188  }
189 }
ast_optional_fn impl
Definition: optional_api.c:59
ast_optional_fn * optional_ref
Definition: optional_api.c:49
ast_optional_fn stub
Definition: optional_api.c:51