libamxb  4.8.2
Bus Agnostic C API
amxb_backend_mngr.c File Reference
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_dm.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_path.h>
#include <amxb/amxb_be_intf.h>
#include <amxb/amxb.h>
#include "amxb_priv.h"
#include "amxb_version.h"

Go to the source code of this file.

Data Structures

struct  _amxb_who_has_cache
 

Macros

#define _GNU_SOURCE
 

Typedefs

typedef struct _amxb_who_has_cache amxb_who_has_cache_t
 

Functions

static int amxb_close_backend (UNUSED amxb_be_funcs_t *fns)
 
static void amxb_be_remove_connections (amxc_llist_it_t *lit)
 
static void amxb_be_remove_backend (UNUSED const char *key, amxc_htable_it_t *it)
 
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)
 
static bool amxb_has_object (amxb_bus_ctx_t *bus_ctx, const char *object, bool full_match)
 
static void amxb_be_object_exists (UNUSED const amxb_bus_ctx_t *bus_ctx, const amxc_var_t *const data, void *priv)
 
static amxb_bus_ctx_tamxb_be_find_connection (amxc_llist_t *connections, const char *object_path, bool full_match)
 
static void amxb_apply_be_config (amxb_be_funcs_t *funcs, amxc_var_t *const config)
 
amxb_bus_ctx_tamxb_be_who_has_impl (const char *object_path, bool full_match)
 
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...
 
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 config)
 Passes configuration options to the backends. More...
 
static CONSTRUCTOR void amxb_cache_init (void)
 
static DESTRUCTOR void amxb_cache_clean (void)
 

Variables

static amxc_htable_t amxb_backends
 
static amxb_be_funcs_tcurrent_be = NULL
 
static const amxc_var_t * amxb_conf = NULL
 
static uint32_t amxb_cache_size = 5
 
static amxc_llist_t amxb_cache_list
 
static amxc_htable_t amxb_cache_table
 
static amxb_version_t lib_version
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxb_backend_mngr.c.

Typedef Documentation

◆ amxb_who_has_cache_t

Function Documentation

◆ amxb_apply_be_config()

static void amxb_apply_be_config ( amxb_be_funcs_t funcs,
amxc_var_t *const  config 
)
static

Definition at line 250 of file amxb_backend_mngr.c.

251  {
252  if(amxb_is_valid_be_func(funcs, set_config, funcs->set_config)) {
253  funcs->set_config(config);
254  }
255 }
config
Definition: test.odl:56
#define amxb_is_valid_be_func(ft, member, ptr)
Definition: amxb_priv.h:78
amxb_be_set_config_t set_config

◆ amxb_be_find_connection()

static amxb_bus_ctx_t* amxb_be_find_connection ( amxc_llist_t *  connections,
const char *  object_path,
bool  full_match 
)
static

Definition at line 189 of file amxb_backend_mngr.c.

191  {
192  amxb_bus_ctx_t* ctx = NULL;
193  amxc_var_t data;
194  bool found = false;
195  amxd_path_t path;
196  char* fixed_path = NULL;
197  uint32_t caps = 0;
198 
199  amxd_path_init(&path, NULL);
200  amxc_var_init(&data);
201  amxd_path_setf(&path, true, "%s", object_path);
202  fixed_path = amxd_path_get_fixed_part(&path, false);
203 
204  // remove the trailing dot if any
205  if((fixed_path != NULL) && (*fixed_path != 0)) {
206  int len = strlen(fixed_path);
207  if(fixed_path[len - 1] == '.') {
208  fixed_path[len - 1] = 0;
209  }
210  }
211 
212  amxc_llist_for_each(it, connections) {
213  ctx = amxc_llist_it_get_data(it, amxb_bus_ctx_t, it);
214  if(ctx->socket_type == AMXB_LISTEN_SOCK) {
215  ctx = NULL;
216  continue;
217  }
218  if(amxb_is_local_object(ctx, fixed_path)) {
219  break;
220  }
222  if(((caps & AMXB_BE_DISCOVER) == AMXB_BE_DISCOVER) &&
223  amxb_has_object(ctx, fixed_path, full_match)) {
224  break;
225  }
227  ( amxb_describe(ctx, fixed_path, AMXB_FLAG_EXISTS, &data, 5) == 0)) {
228  if(amxc_var_is_null(&data)) {
229  ctx = NULL;
230  continue;
231  }
232  break;
233  }
236  amxb_be_object_exists, &found);
237  if(found) {
238  break;
239  }
240  }
241  ctx = NULL;
242  }
243 
244  free(fixed_path);
245  amxd_path_clean(&path);
246  amxc_var_clean(&data);
247  return ctx;
248 }
static bool amxb_has_object(amxb_bus_ctx_t *bus_ctx, const char *object, bool full_match)
static void amxb_be_object_exists(UNUSED const amxb_bus_ctx_t *bus_ctx, const amxc_var_t *const data, void *priv)
#define AMXB_BE_DISCOVER
Definition: amxb_be_intf.h:343
#define AMXB_BE_DISCOVER_DESCRIBE
Definition: amxb_be_intf.h:341
#define AMXB_BE_DISCOVER_LIST
Definition: amxb_be_intf.h:342
#define AMXB_FLAG_EXISTS
#define AMXB_FLAG_FIRST_LVL
bool PRIVATE amxb_is_local_object(amxb_bus_ctx_t *ctx, const char *obj_path)
Definition: amxb_ba_priv.c:94
uint32_t PRIVATE amxb_be_get_capabilities(amxb_bus_ctx_t *bus_ctx)
Definition: amxb_ba_priv.c:157
#define AMXB_LISTEN_SOCK
Definition: amxb_types.h:77
static uint32_t caps
Definition: dummy_be.c:70
int amxb_describe(amxb_bus_ctx_t *const bus_ctx, const char *object, uint32_t flags, amxc_var_t *ret, int timeout)
Describes an object.
int amxb_list(amxb_bus_ctx_t *const bus_ctx, const char *object, uint32_t flags, amxb_be_cb_fn_t fn, void *priv)
List the service elements/nodes of an object.
uint32_t socket_type
Definition: amxb_types.h:126

◆ amxb_be_invoke_on_all_connections()

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 
)
static

Definition at line 130 of file amxb_backend_mngr.c.

134  {
135  int retval = 0;
136 
137  amxc_llist_for_each(it, connections) {
138  amxb_bus_ctx_t* ctx = amxc_llist_it_get_data(it, amxb_bus_ctx_t, it);
139  if(ctx->socket_type != type) {
140  continue;
141  }
142  retval = fn(ctx, args, priv);
143  when_failed(retval, exit);
144  }
145 
146 exit:
147  return retval;
148 }

◆ amxb_be_object_exists()

static void amxb_be_object_exists ( UNUSED const amxb_bus_ctx_t bus_ctx,
const amxc_var_t *const  data,
void *  priv 
)
static

Definition at line 179 of file amxb_backend_mngr.c.

181  {
182  bool* found = (bool*) priv;
183 
184  if(data != NULL) {
185  *found = true;
186  }
187 }

◆ amxb_be_remove_backend()

static void amxb_be_remove_backend ( UNUSED const char *  key,
amxc_htable_it_t *  it 
)
static

Definition at line 119 of file amxb_backend_mngr.c.

120  {
121  amxb_be_funcs_t* fns = NULL;
122 
123  fns = amxc_htable_it_get_data(it, amxb_be_funcs_t, it);
124  amxc_llist_clean(&fns->connections, amxb_be_remove_connections);
125  if(fns->handle != NULL) {
126  amxb_close_backend(fns);
127  }
128 }
static void amxb_be_remove_connections(amxc_llist_it_t *lit)
static int amxb_close_backend(UNUSED amxb_be_funcs_t *fns)
The back-end interface structure.
amxc_llist_t connections

◆ amxb_be_remove_connections()

static void amxb_be_remove_connections ( amxc_llist_it_t *  lit)
static

Definition at line 114 of file amxb_backend_mngr.c.

114  {
115  amxb_bus_ctx_t* bus_ctx = amxc_llist_it_get_data(lit, amxb_bus_ctx_t, it);
116  amxb_free(&bus_ctx);
117 }
void amxb_free(amxb_bus_ctx_t **ctx)
Frees allocated memory.
static amxb_bus_ctx_t * bus_ctx
Definition: test_amxb_e2e.c:84

◆ amxb_be_who_has_impl()

amxb_bus_ctx_t* amxb_be_who_has_impl ( const char *  object_path,
bool  full_match 
)

Definition at line 257 of file amxb_backend_mngr.c.

257  {
258  amxb_bus_ctx_t* ctx = NULL;
259  amxc_htable_it_t* cache_hit = NULL;
260  amxb_who_has_cache_t* cache = NULL;
261 
262  when_str_empty(object_path, exit);
263  when_true(strcmp(object_path, ".") == 0, exit);
264 
265  cache_hit = amxc_htable_get(&amxb_cache_table, object_path);
266  if(cache_hit != NULL) {
267  cache = amxc_container_of(cache_hit, amxb_who_has_cache_t, hit);
268  ctx = cache->ctx;
269  amxc_llist_prepend(&amxb_cache_list, &cache->lit);
270  goto exit;
271  }
272 
273  amxc_htable_for_each(hit, &amxb_backends) {
274  amxb_be_funcs_t* funcs = amxc_htable_it_get_data(hit, amxb_be_funcs_t, it);
275  ctx = amxb_be_find_connection(&funcs->connections, object_path, full_match);
276  if(ctx == NULL) {
277  continue;
278  }
279  if(amxb_cache_size == 0) {
280  break;
281  }
282  if(amxc_htable_size(&amxb_cache_table) >= amxb_cache_size) {
283  amxc_llist_it_t* it = amxc_llist_take_last(&amxb_cache_list);
284  if(it != NULL) {
285  cache = amxc_container_of(it, amxb_who_has_cache_t, lit);
286  amxc_htable_it_clean(&cache->hit, NULL);
287  free(cache);
288  }
289  }
290 
291  cache = (amxb_who_has_cache_t*) calloc(1, sizeof(amxb_who_has_cache_t));
292  when_null(cache, exit);
293  cache->ctx = ctx;
294  amxc_htable_insert(&amxb_cache_table, object_path, &cache->hit);
295  amxc_llist_prepend(&amxb_cache_list, &cache->lit);
296  break;
297  }
298 
299 exit:
300  return ctx;
301 }
static amxc_htable_t amxb_backends
static uint32_t amxb_cache_size
static amxb_bus_ctx_t * amxb_be_find_connection(amxc_llist_t *connections, const char *object_path, bool full_match)
static amxc_llist_t amxb_cache_list
static amxc_htable_t amxb_cache_table
amxb_bus_ctx_t * ctx
amxc_htable_it_t hit
amxc_llist_it_t lit

◆ amxb_cache_clean()

static DESTRUCTOR void amxb_cache_clean ( void  )
static

Definition at line 732 of file amxb_backend_mngr.c.

732  {
733  amxc_htable_clean(&amxb_cache_table, NULL);
734 }

◆ amxb_cache_init()

static CONSTRUCTOR void amxb_cache_init ( void  )
static

Definition at line 728 of file amxb_backend_mngr.c.

728  {
729  amxc_htable_init(&amxb_cache_table, amxb_cache_size * 2);
730 }

◆ amxb_close_backend()

static int amxb_close_backend ( UNUSED amxb_be_funcs_t fns)
static

Definition at line 97 of file amxb_backend_mngr.c.

97  {
98  void* handle = fns->handle;
99  char* no_dlclose = getenv("AMXB_NO_DLCLOSE");
100  int retval = 0;
101 
102  fns->handle = NULL;
103  if(no_dlclose == NULL) {
104  retval = dlclose(handle);
105  if(retval != 0) {
106  const char* errstr = dlerror();
107  printf("dlclose failed - %s", errstr != NULL? errstr:"no error");
108  }
109  }
110 
111  return retval;
112 }

◆ amxb_has_object()

static bool amxb_has_object ( amxb_bus_ctx_t bus_ctx,
const char *  object,
bool  full_match 
)
static

Definition at line 150 of file amxb_backend_mngr.c.

150  {
151  bool retval = false;
152  const amxb_be_funcs_t* fns = NULL;
153 
154  fns = bus_ctx->bus_fn;
155  if(amxb_is_valid_be_func(fns, has, fns->has)) {
156  if(full_match) {
157  retval = fns->has(bus_ctx->bus_ctx, object);
158  } else {
159  amxd_path_t path;
160  char* part = NULL;
161 
162  amxd_path_init(&path, NULL);
163  amxd_path_setf(&path, true, "%s", object);
164 
165  do {
166  free(part);
167  object = amxd_path_get(&path, 0);
168  retval = fns->has(bus_ctx->bus_ctx, object);
169  part = amxd_path_get_last(&path, true);
170  } while(part != NULL && !retval);
171  free(part);
172  amxd_path_clean(&path);
173  }
174  }
175 
176  return retval;
177 }
amxb_be_has_fn_t has
const amxb_be_funcs_t * bus_fn
Definition: amxb_types.h:121
void * bus_ctx
Definition: amxb_types.h:122

Variable Documentation

◆ amxb_backends

amxc_htable_t amxb_backends
static

Definition at line 83 of file amxb_backend_mngr.c.

◆ amxb_cache_list

amxc_llist_t amxb_cache_list
static

Definition at line 88 of file amxb_backend_mngr.c.

◆ amxb_cache_size

uint32_t amxb_cache_size = 5
static

Definition at line 87 of file amxb_backend_mngr.c.

◆ amxb_cache_table

amxc_htable_t amxb_cache_table
static

Definition at line 89 of file amxb_backend_mngr.c.

◆ amxb_conf

const amxc_var_t* amxb_conf = NULL
static

Definition at line 85 of file amxb_backend_mngr.c.

◆ current_be

amxb_be_funcs_t* current_be = NULL
static

Definition at line 84 of file amxb_backend_mngr.c.

◆ lib_version

amxb_version_t lib_version
static
Initial value:
= {
.major = AMXB_VERSION_MAJOR,
.minor = AMXB_VERSION_MINOR,
.build = AMXB_VERSION_BUILD
}

Definition at line 91 of file amxb_backend_mngr.c.