libamxb  4.8.2
Bus Agnostic C API
Bus Backend Management

Functions

int amxb_be_register (amxb_be_funcs_t *const funcs)
 Registers backend interface. More...
 
int amxb_be_unregister (amxb_be_funcs_t *const funcs)
 Unregisters a backend interface. More...
 
amxb_be_funcs_tamxb_be_find (const char *name)
 Gets a backend function table using its name. More...
 
const amxb_be_info_tamxb_be_get_info (const char *name)
 Gets a backend information. More...
 
int amxb_be_load (const char *path_name)
 Loads a shared object that implements a bus specific backend interface. More...
 
int amxb_be_load_multiple (amxc_var_t *const bes)
 Loads multiple shared objects that each implement a bus specific backend interface. More...
 
int amxb_be_remove (const char *backend_name)
 Removes and unloads a backend with a given name. More...
 
void amxb_be_remove_all (void)
 Removes and unloads all backends. More...
 
amxc_array_t * amxb_be_list (void)
 Get the loaded back-end names. More...
 
int amxb_be_for_all_connections (amxb_be_task_fn_t fn, const amxc_var_t *args, void *priv)
 Calls a function on all open connections. More...
 
int amxb_be_for_all_listeners (amxb_be_task_fn_t fn, const amxc_var_t *args, void *priv)
 Calls a function on all listen sockets. More...
 
amxb_bus_ctx_tamxb_be_who_has (const char *object_path)
 Searches a bus context that can provide a certain object. More...
 
void amxb_be_cache_remove_ctx (amxb_bus_ctx_t *ctx)
 Removes a bus context from the lookup cache. More...
 
void amxb_be_cache_remove_path (const char *object_path)
 Removes an object path and its corresponding bus context from the lookup cache. More...
 
void amxb_be_cache_set_size (uint32_t size)
 Changes the size of the lookup cache. More...
 
int amxb_set_config (amxc_var_t *const configuration)
 Passes configuration options to the backends. More...
 
int amxb_check_version (const amxb_version_t *be_version)
 Compares the given version with the library version. More...
 
int amxb_check_be_versions (const amxb_version_t *min, const amxb_version_t *max)
 Checks if the library version is in the given range. More...
 
const amxb_version_tamxb_get_version (void)
 Gets the version of the library. More...
 

Detailed Description

Function Documentation

◆ amxb_be_cache_remove_ctx()

void amxb_be_cache_remove_ctx ( amxb_bus_ctx_t ctx)

Removes a bus context from the lookup cache.

Bus contexts are added to the lookup cache by amxb_be_who_has

Parameters
ctxa bus context

Definition at line 654 of file amxb_backend_mngr.c.

654  {
655  when_null(ctx, exit);
656 
657  amxc_llist_for_each(lit, &amxb_cache_list) {
658  amxb_who_has_cache_t* cache = amxc_container_of(lit, amxb_who_has_cache_t, lit);
659  if(cache->ctx == ctx) {
660  amxc_llist_it_take(&cache->lit);
661  amxc_htable_it_clean(&cache->hit, NULL);
662  free(cache);
663  }
664  }
665 
666 exit:
667  return;
668 }
static amxc_llist_t amxb_cache_list
amxb_bus_ctx_t * ctx
amxc_htable_it_t hit
amxc_llist_it_t lit

◆ amxb_be_cache_remove_path()

void amxb_be_cache_remove_path ( const char *  object_path)

Removes an object path and its corresponding bus context from the lookup cache.

Bus contexts are added to the lookup cache by amxb_be_who_has

Parameters
object_pathObject path that must be removed from the cache

Definition at line 670 of file amxb_backend_mngr.c.

670  {
671  amxc_htable_it_t* cache_hit = NULL;
672  amxb_who_has_cache_t* cache = NULL;
673 
674  when_str_empty(object_path, exit);
675  when_true(strcmp(object_path, ".") == 0, exit);
676 
677  cache_hit = amxc_htable_get(&amxb_cache_table, object_path);
678  when_null(cache_hit, exit);
679 
680  cache = amxc_container_of(cache_hit, amxb_who_has_cache_t, hit);
681  amxc_llist_it_take(&cache->lit);
682  amxc_htable_it_clean(&cache->hit, NULL);
683  free(cache);
684 
685 exit:
686  return;
687 }
static amxc_htable_t amxb_cache_table

◆ amxb_be_cache_set_size()

void amxb_be_cache_set_size ( uint32_t  size)

Changes the size of the lookup cache.

Bus contexts are added to the lookup cache by amxb_be_who_has.

When the new size is smaller then the current size, the oldes entries are removed from the cache.

Parameters
sizethe new size

Definition at line 689 of file amxb_backend_mngr.c.

689  {
690  uint32_t items = amxc_htable_size(&amxb_cache_table);
691  if(size < items) {
692  amxc_llist_for_each_reverse(it, &amxb_cache_list) {
693  amxb_who_has_cache_t* cache = amxc_container_of(it, amxb_who_has_cache_t, lit);
694  amxc_llist_it_take(&cache->lit);
695  amxc_htable_it_clean(&cache->hit, NULL);
696  free(cache);
697  items--;
698  if(size >= items) {
699  break;
700  }
701  }
702  }
703 
704  amxb_cache_size = size;
705 }
static uint32_t amxb_cache_size

◆ amxb_be_find()

amxb_be_funcs_t* amxb_be_find ( const char *  name)

Gets a backend function table using its name.

This function is mainly used internally to fetch the function table of a specific backend.

Note
Do not free the returned pointer or store the pointer. The backend function table can be removed at any time. Always use this function to retrieve the function table pointer.
Parameters
namename of the backend
Returns
returns NULL when no backend with the given name is found. Otherwise it returns the function table pointer.

Definition at line 432 of file amxb_backend_mngr.c.

432  {
433  amxb_be_funcs_t* fns = NULL;
434  amxc_htable_it_t* hit = NULL;
435 
436  when_null(name, exit);
437  when_true(*(name) == 0, exit);
438 
439  hit = amxc_htable_get(&amxb_backends, name);
440  when_null(hit, exit);
441 
442  fns = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
443 
444 exit:
445  return fns;
446 }
static amxc_htable_t amxb_backends
The back-end interface structure.

◆ amxb_be_for_all_connections()

int amxb_be_for_all_connections ( amxb_be_task_fn_t  fn,
const amxc_var_t *  args,
void *  priv 
)

Calls a function on all open connections.

Loops over all backends and calls a functions for each open connection for the backend.

Parameters
fnfunction to be called
argsa variant that is passed to the function
privsome private data, is passed as is to the function
Returns
0 when at least one connection could perform the task

Definition at line 610 of file amxb_backend_mngr.c.

612  {
613  int retval = AMXB_ERROR_UNKNOWN;
614  when_null(fn, exit);
615 
616  amxc_htable_for_each(hit, &amxb_backends) {
617  amxb_be_funcs_t* funcs = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
619  fn,
620  args,
622  priv) == AMXB_STATUS_OK) {
623  retval = AMXB_STATUS_OK;
624  }
625  }
626 
627 exit:
628  return retval;
629 }
static int amxb_be_invoke_on_all_connections(amxc_llist_t *connections, amxb_be_task_fn_t fn, const amxc_var_t *args, uint32_t type, void *priv)
#define AMXB_DATA_SOCK
Definition: amxb_types.h:76
#define AMXB_ERROR_UNKNOWN
Unknown error.
Definition: amxb_error.h:80
#define AMXB_STATUS_OK
All ok.
Definition: amxb_error.h:86
amxc_llist_t connections

◆ amxb_be_for_all_listeners()

int amxb_be_for_all_listeners ( amxb_be_task_fn_t  fn,
const amxc_var_t *  args,
void *  priv 
)

Calls a function on all listen sockets.

Loops over all backends and calls a functions for each listen socket for the backend.

Parameters
fnfunction to be called
argsa variant that is passed to the function
privsome private data, is passed as is to the function
Returns
0 when no errors occured

Definition at line 631 of file amxb_backend_mngr.c.

633  {
634  int retval = 0;
635  when_null(fn, exit);
636 
637  amxc_htable_for_each(hit, &amxb_backends) {
638  amxb_be_funcs_t* funcs = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
640  fn,
641  args,
643  priv);
644  }
645 
646 exit:
647  return retval;
648 }
#define AMXB_LISTEN_SOCK
Definition: amxb_types.h:77

◆ amxb_be_get_info()

const amxb_be_info_t* amxb_be_get_info ( const char *  name)

Gets a backend information.

Fetches some meta-information from the backend.

Note
Do not free the returned pointer or store the pointer.
Parameters
namename of the backend
Returns
returns NULL when no backend with the given name is found. Otherwise it returns the function table pointer.

Definition at line 448 of file amxb_backend_mngr.c.

448  {
449  amxb_be_funcs_t* fns = NULL;
450  amxb_be_info_fn_t be_get_info = NULL;
451  amxb_be_info_t* info = NULL;
452  amxc_htable_it_t* hit = NULL;
453 
454  when_null(name, exit);
455  when_true(*(name) == 0, exit);
456 
457  hit = amxc_htable_get(&amxb_backends, name);
458  when_null(hit, exit);
459 
460  fns = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
461 
462  be_get_info = (amxb_be_info_fn_t) dlsym(fns->handle, "amxb_be_info");
463  when_null(be_get_info, exit);
464  info = be_get_info();
465 
466 exit:
467  return info;
468 }
amxb_be_info_t *(* amxb_be_info_fn_t)(void)
Definition: amxb_types.h:113

◆ amxb_be_list()

amxc_array_t* amxb_be_list ( void  )

Get the loaded back-end names.

This function returns an array of pointers to the loaded back-end names. You can iterate over this array using a simple for loop.

Example:

void dump_backend_names(void) {
amxc_array_t* names = amxb_be_list();
size_t size = amxc_array_size(names);
for(size_t i = 0; i < size; i++) {
const char* name = (const char *)amxc_array_get_data_at(names, i);
printf("back-end [%s]\n", name);
}
amxc_array_delete(&names, NULL);
}
amxc_array_t * amxb_be_list(void)
Get the loaded back-end names.

The array must be freed when not needed any more, use amxc_array_delete.

Warning
Do not free the content of the array, in other words do not provide a delete callback to amxc_array_delete.
Returns
returns a pointer to an amxc_array_t.

Definition at line 606 of file amxb_backend_mngr.c.

606  {
607  return amxc_htable_get_sorted_keys(&amxb_backends);
608 }

◆ amxb_be_load()

int amxb_be_load ( const char *  path_name)

Loads a shared object that implements a bus specific backend interface.

Loads a shared object into memory using dlopen. It is assumed that the shared object provides a backend interface implementation.

The symbol "amxb_be_info" is resolved using dlsym. If the shared object does not contain this symbol, the shared object is closed and the loading fails.

The function "amxb_be_info" is called and must return a backend information structure which must contain the minimum and maximum supported version of this library. If the version of this library is not within the range, the shared object is closed and loading fails.

Parameters
path_nameabsolute or relative path to a shared object that implements a backend interface
Returns
returns 0 when the shared object is loaded successfully and it provides a valid backend interface.

Definition at line 470 of file amxb_backend_mngr.c.

470  {
471  int retval = -1;
472  void* handle = NULL;
473  amxb_be_info_fn_t be_get_info = NULL;
474  amxb_be_info_t* be_info = NULL;
475  when_str_empty(path_name, exit);
476 
477  // Set current backend functions to NULL.
478  // If the loaded shared object has a construct that calls amxb_be_register
479  // the current_be will be set correctly.
480  // This happends during the dlopen
481  current_be = NULL;
482  handle = dlopen(path_name, RTLD_LAZY);
483  if(handle == NULL) {
484  const char* errstr = dlerror();
485  printf("DLOPEN - %s\n", errstr != NULL? errstr:"no error");
486  goto exit;
487  }
488 
489  be_get_info = (amxb_be_info_fn_t) dlsym(handle, "amxb_be_info");
490  when_null(be_get_info, exit);
491 
492  be_info = be_get_info();
493  when_null(be_info, exit);
494  when_null(be_info->min_supported, exit);
495  when_null(be_info->max_supported, exit);
496 
498  be_info->max_supported), exit);
499 
500  when_true(amxb_check_version(be_info->min_supported) < 0, exit);
501  when_true(amxb_check_version(be_info->max_supported) > 0, exit);
502 
503  // The loaded back-end could call amxb_be_register using a constructor
504  // function. This method is not always reliable, depending on the platform
505  // the constructor is not invoked.
506  // Or the back-end did not call amxb_be_register function
507 
508  // Prefered solution is that the backend gives the function table using
509  // the back-end information structure. The following lines are here for
510  // backwards compatibility.
511  if(current_be == NULL) {
512  when_null(be_info->funcs, exit);
513  if(be_info->funcs->handle == handle) {
514  dlclose(handle);
515  } else if(be_info->funcs->handle != NULL) {
516  goto exit;
517  } else {
518  when_failed(amxb_be_register(be_info->funcs), exit);
519  }
520  } else {
522  }
523 
524  be_info->funcs->handle = handle;
525 
526  retval = 0;
527 
528 exit:
529  if((retval != 0) && (handle != NULL)) {
530  dlclose(handle);
531  }
532  current_be = NULL;
533  return retval;
534 }
static amxb_be_funcs_t * current_be
int amxb_be_register(amxb_be_funcs_t *const funcs)
Registers backend interface.
int amxb_check_be_versions(const amxb_version_t *min, const amxb_version_t *max)
Checks if the library version is in the given range.
int amxb_check_version(const amxb_version_t *be_version)
Compares the given version with the library version.
const amxb_version_t * min_supported
Definition: amxb_types.h:105
amxb_be_funcs_t * funcs
Definition: amxb_types.h:110
const amxb_version_t * max_supported
Definition: amxb_types.h:106
static amxb_be_info_t be_info

◆ amxb_be_load_multiple()

int amxb_be_load_multiple ( amxc_var_t *const  bes)

Loads multiple shared objects that each implement a bus specific backend interface.

The variant may contain a string or a linked list.

When the variant contains a string it will be split using ':' as a separator. Each individual part is assumed to be an absolute or relative path to a shared object file.

If it is a variant containing a list of variants, each variant in the list must contain an absolute or relative path to a shared object file.

When one or more shared objects can not be loaded, the function will load all other shared objects.

Parameters
beslist of backends
Returns
returns the number of backends that failed to load

Definition at line 536 of file amxb_backend_mngr.c.

536  {
537  int retval = -1;
538  const amxc_llist_t* list = NULL;
539  amxc_llist_t list_bes;
540 
541  amxc_llist_init(&list_bes);
542 
543  when_null(bes, exit);
544  when_true(amxc_var_type_of(bes) != AMXC_VAR_ID_LIST &&
545  amxc_var_type_of(bes) != AMXC_VAR_ID_CSTRING, exit);
546 
547 
548  if(amxc_var_type_of(bes) == AMXC_VAR_ID_CSTRING) {
549  amxc_string_t* str_bes = amxc_var_take(amxc_string_t, bes);
550  when_null(str_bes, exit);
551  amxc_string_split_to_llist(str_bes, &list_bes, ':');
552  amxc_var_clean(bes);
553  amxc_var_set_type(bes, AMXC_VAR_ID_LIST);
554  amxc_llist_for_each(it, (&list_bes)) {
555  amxc_string_t* str = amxc_string_from_llist_it(it);
556  amxc_var_add(cstring_t, bes, amxc_string_get(str, 0));
557  }
558  amxc_string_delete(&str_bes);
559  }
560  list = amxc_var_constcast(amxc_llist_t, bes);
561 
562  when_true(amxc_llist_is_empty(list), exit);
563  retval = 0;
564  amxc_llist_for_each(it, list) {
565  amxc_var_t* be = amxc_var_from_llist_it(it);
566  if(amxb_be_load(amxc_var_constcast(cstring_t, be)) == 0) {
567  amxc_var_delete(&be);
568  } else {
569  retval++;
570  }
571  }
572 
573 exit:
574  amxc_llist_clean(&list_bes, amxc_string_list_it_free);
575  return retval;
576 }
int amxb_be_load(const char *path_name)
Loads a shared object that implements a bus specific backend interface.

◆ amxb_be_register()

int amxb_be_register ( amxb_be_funcs_t *const  funcs)

Registers backend interface.

Backend can call this function to register the function table (backend interface) in a constructor function.

The preferred solution however is backend provides the function table using "amxb_be_info" which returns the backend information, this information may contain the function table.

The function table must contain at least:

  • A valid and unique backend name
  • The size filled in the stucture must be smaller or equal to the sizeof(amxb_be_funcs_t)
  • And the following function pointers must be set:
    • connect
    • disconnect
    • get_fd
    • read

When the backend provides the function "set_config" it will be called if backend specific configuration options are available.

Parameters
funcsThe back-end function table
Returns
returns 0 when the function table is accepted.

Definition at line 372 of file amxb_backend_mngr.c.

372  {
373  int retval = -1;
374  amxc_htable_it_t* hit = NULL;
375 
376  when_null(funcs, exit);
377  when_null(funcs->name, exit);
378  when_true(*(funcs->name) == 0, exit);
379  when_true(funcs->size > sizeof(amxb_be_funcs_t), exit);
380 
381  if(amxc_htable_is_empty(&amxb_backends)) {
382  when_failed(amxc_htable_init(&amxb_backends, 10), exit);
383  } else {
384  hit = amxc_htable_get(&amxb_backends, funcs->name);
385  when_not_null(hit, exit);
386  }
387 
388  current_be = funcs;
389  funcs->handle = NULL;
390 
391  amxc_htable_it_init(&funcs->it);
392  amxc_llist_init(&funcs->connections);
393  when_failed(amxc_htable_insert(&amxb_backends, funcs->name, &funcs->it), exit);
394 
395  if(amxb_conf != NULL) {
396  amxc_var_t* cfg = amxc_var_get_key(amxb_conf, funcs->name, AMXC_VAR_FLAG_DEFAULT);
397  amxb_apply_be_config(funcs, cfg);
398  }
399 
400  retval = 0;
401 
402 exit:
403  return retval;
404 }
static const amxc_var_t * amxb_conf
static void amxb_apply_be_config(amxb_be_funcs_t *funcs, amxc_var_t *const config)
const char * name
amxc_htable_it_t it

◆ amxb_be_remove()

int amxb_be_remove ( const char *  backend_name)

Removes and unloads a backend with a given name.

Before the backend is unloaded all connections that are opened using that backend are closed.

All bus contexts related to that backend will be invalid after this function call.

Parameters
backend_namename of the backend
Returns
returns 0 when the backend is unloaded.

Definition at line 578 of file amxb_backend_mngr.c.

578  {
579  amxb_be_funcs_t* fns = NULL;
580  amxc_htable_it_t* hit = NULL;
581  int retval = -1;
582 
583  when_str_empty(backend_name, exit);
584 
585  hit = amxc_htable_get(&amxb_backends, backend_name);
586  when_null(hit, exit);
587 
588  fns = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
589  when_null(fns->handle, exit);
590  amxc_llist_clean(&fns->connections, amxb_be_remove_connections);
591  amxc_htable_it_clean(hit, NULL);
592 
593  retval = amxb_close_backend(fns);
594 
595 exit:
596  if(amxc_htable_is_empty(&amxb_backends)) {
597  amxc_htable_clean(&amxb_backends, NULL);
598  }
599  return retval;
600 }
static void amxb_be_remove_connections(amxc_llist_it_t *lit)
static int amxb_close_backend(UNUSED amxb_be_funcs_t *fns)

◆ amxb_be_remove_all()

void amxb_be_remove_all ( void  )

Removes and unloads all backends.

Before the backends are unloaded all connections are closed

Typically this function is used just before the application exits.

Definition at line 602 of file amxb_backend_mngr.c.

602  {
603  amxc_htable_clean(&amxb_backends, amxb_be_remove_backend);
604 }
static void amxb_be_remove_backend(UNUSED const char *key, amxc_htable_it_t *it)

◆ amxb_be_unregister()

int amxb_be_unregister ( amxb_be_funcs_t *const  funcs)

Unregisters a backend interface.

A backend can call this function to remove the function table (backend interface) in a destructor function.

However this is not recommended. The backend will be unloaded from memory when it is not required anymore using the function amxb_be_remove or amxb_be_remove_all.

When a backend's function table is unregistered all open connections for that backend will be closed before the function table is removed.

Parameters
funcsThe back-end function table
Returns
returns 0 when the function table is removed.

Definition at line 406 of file amxb_backend_mngr.c.

406  {
407  int retval = -1;
408  amxc_htable_it_t* hit = NULL;
409 
410  when_null(funcs, exit);
411  when_null(funcs->name, exit);
412  when_true(*(funcs->name) == 0, exit);
413 
414  hit = amxc_htable_get(&amxb_backends, funcs->name);
415 
416  when_null(hit, exit);
417  when_true(hit != &funcs->it, exit);
418 
419  amxc_htable_it_clean(hit, amxb_be_remove_backend);
420 
421  funcs->handle = NULL;
422 
423  retval = 0;
424 
425 exit:
426  if(amxc_htable_is_empty(&amxb_backends)) {
427  amxc_htable_clean(&amxb_backends, NULL);
428  }
429  return retval;
430 }

◆ amxb_be_who_has()

amxb_bus_ctx_t* amxb_be_who_has ( const char *  object_path)

Searches a bus context that can provide a certain object.

Invoke a describe on all open connections (bus contexts), the first bus context that can provide the object is returned.

If a bus context is found, it is stored in a lookup cache. When this method is called again with same object path, the bus context is retrieved from the cache.

The lookup cache is limited in size (default 5 entries), but can be changed by calling amxb_be_cache_set_size.

Parameters
object_pathan object path
Returns
NULL when no bus context can provide the object. A bus context otherwise.

Definition at line 650 of file amxb_backend_mngr.c.

650  {
651  return amxb_be_who_has_impl(object_path, false);
652 }
amxb_bus_ctx_t * amxb_be_who_has_impl(const char *object_path, bool full_match)

◆ amxb_check_be_versions()

int amxb_check_be_versions ( const amxb_version_t min,
const amxb_version_t max 
)

Checks if the library version is in the given range.

Parameters
minthe minimum version
maxthe maximum version
Returns
  • 0 when lib version is in the range
  • 1 when lib version is not in the range

Definition at line 339 of file amxb_backend_mngr.c.

340  {
341  if((min->major == -1) || (max->major == -1)) {
342  return -1;
343  }
344 
345  if(min->major > max->major) {
346  return -1;
347  }
348  if(min->major == max->major) {
349  if((min->minor > max->minor) && (max->minor != -1)) {
350  return -1;
351  }
352  if(min->minor == max->minor) {
353  if((min->build > max->build) && (max->build != -1)) {
354  return -1;
355  }
356  }
357  }
358 
359  return 0;
360 }
int32_t major
Definition: amxb_types.h:99
int32_t minor
Definition: amxb_types.h:100
int32_t build
Definition: amxb_types.h:101

◆ amxb_check_version()

int amxb_check_version ( const amxb_version_t be_version)

Compares the given version with the library version.

Parameters
be_versionthe version that must be compared with the library version
Returns
  • 0 when lib version and the given version are equal
  • 1 when lib version is > than be version
  • -1 when lib version is < than be version

Definition at line 311 of file amxb_backend_mngr.c.

311  {
313  return 1;
314  }
316  return -1;
317  }
318  if(be_version->minor == -1) {
319  return 0;
320  }
322  return 1;
323  }
325  return -1;
326  }
327  if(be_version->build == -1) {
328  return 0;
329  }
331  return 1;
332  }
334  return -1;
335  }
336  return 0;
337 }
static amxb_version_t lib_version
static amxb_version_t be_version

◆ amxb_get_version()

const amxb_version_t* amxb_get_version ( void  )

Gets the version of the library.

Returns
Returns a amxb_version_t struct containing the version of this library.

Definition at line 362 of file amxb_backend_mngr.c.

362  {
363  static amxb_version_t libv;
364 
365  libv.major = lib_version.major;
366  libv.minor = lib_version.minor;
367  libv.build = lib_version.build;
368 
369  return &libv;
370 }

◆ amxb_set_config()

int amxb_set_config ( amxc_var_t *const  configuration)

Passes configuration options to the backends.

The configuration must be a variant containing a hash table. If in the hash table a key is found with the name of a loaded backend, the value of that key is passed to the backend. The value itself can also be a hash table.

When passing a NULL pointer the configuration is reset for all backends

Parameters
configurationa hash table variant with configuration options
Returns
returns 0 when the configuration was set.

Definition at line 707 of file amxb_backend_mngr.c.

707  {
708  amxb_conf = config;
709  if(config == NULL) {
710  amxc_htable_for_each(hit, &amxb_backends) {
711  amxb_be_funcs_t* funcs = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
712  amxb_apply_be_config(funcs, NULL);
713  }
714  } else {
715  amxc_htable_for_each(hit, &amxb_backends) {
716  amxb_be_funcs_t* funcs = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
717  amxc_var_t* be_config = GET_ARG(config, amxc_htable_it_get_key(hit));
718  if(be_config == NULL) {
719  be_config = amxc_var_add_key(amxc_htable_t, config, amxc_htable_it_get_key(hit), NULL);
720  }
721  amxb_apply_be_config(funcs, be_config);
722  }
723  }
724 
725  return 0;
726 }
config
Definition: test.odl:56