libamxb  4.8.2
Bus Agnostic C API
amxb_ba_invoke.c File Reference
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_dm.h>
#include <amxd/amxd_object.h>
#include <amxb/amxb_be_intf.h>
#include <amxb/amxb.h>
#include "amxb_priv.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static int isdot (int c)
 
static int isbrace (int c)
 
static void amxb_trim (char *str, amxc_string_is_char_fn_t fn)
 
static void amxb_complete_async_invoke (UNUSED const amxc_var_t *const data, void *const priv)
 
static void amxb_complete_async_deferred_invoke (const amxc_var_t *const data, void *const priv)
 
static int amxb_invoke_local_impl (amxb_invoke_t *invoke_ctx, amxb_bus_ctx_t *ctx, amxc_var_t *args, amxb_request_t *request, bool async)
 
static int amxb_invoke_be_impl (amxb_invoke_t *invoke_ctx, amxb_bus_ctx_t *ctx, amxc_var_t *args, amxb_request_t *request, int timeout, bool async)
 
static int amxb_invoke_wait_local (amxb_req_t *req, int timeout)
 
int amxb_new_invoke (amxb_invoke_t **invoke_ctx, amxb_bus_ctx_t *const ctx, const char *object, const char *interface, const char *method)
 Prepares a remote function invocation. More...
 
void amxb_free_invoke (amxb_invoke_t **invoke_ctx)
 Deletes a function invoke context, and frees allocated memory. More...
 
int amxb_invoke (amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxc_var_t *ret, amxb_be_cb_fn_t fn, void *priv, int timeout)
 Invokes a remote function, as defined by the function invoke context. More...
 
int amxb_async_invoke (amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxb_be_cb_fn_t fn, amxb_be_done_cb_fn_t done_fn, void *priv, amxb_request_t **request)
 Invokes a remote function, as defined by the function invoke context. More...
 
int amxb_wait_for_request (amxb_request_t *request, int timeout)
 Waits for an asynchronous remote function invoke to finish. More...
 
int amxb_request_new (amxb_request_t **request)
 Allocates an empty amxb_request_t. More...
 
amxb_bus_ctx_tamxb_request_get_ctx (amxb_request_t *request)
 Get the bus context of the request if any. More...
 
int amxb_close_request (amxb_request_t **request)
 Closes a previously create remote function called context. More...
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxb_ba_invoke.c.

Function Documentation

◆ amxb_complete_async_deferred_invoke()

static void amxb_complete_async_deferred_invoke ( const amxc_var_t *const  data,
void *const  priv 
)
static

Definition at line 126 of file amxb_ba_invoke.c.

127  {
128  amxc_var_t* rv = GET_ARG(data, "retval");
129  amxb_req_t* req = (amxb_req_t*) priv;
130  amxb_request_t* request = &req->data;
131 
132  amxc_var_set_type(request->result, AMXC_VAR_ID_LIST);
133  amxc_var_take_it(rv);
134  amxc_var_set_index(request->result, 0, rv, AMXC_VAR_FLAG_DEFAULT);
135  request->bus_retval = GET_UINT32(data, "status");
136 
137  amxb_complete_async_invoke(NULL, priv);
138 
139  return;
140 }
static void amxb_complete_async_invoke(UNUSED const amxc_var_t *const data, void *const priv)
A request structure.
Definition: amxb_types.h:138
amxc_var_t * result
Definition: amxb_types.h:140
Definition: amxb_priv.h:69
amxb_request_t data
Definition: amxb_priv.h:71

◆ amxb_complete_async_invoke()

static void amxb_complete_async_invoke ( UNUSED const amxc_var_t *const  data,
void *const  priv 
)
static

Definition at line 100 of file amxb_ba_invoke.c.

101  {
102  amxb_req_t* req = (amxb_req_t*) priv;
103  amxb_request_t* request = &req->data;
104  amxb_bus_ctx_t* ctx = amxb_request_get_ctx(request);
105  req->in_flight = false;
106 
107  if(req->closed) {
108  if(!req->wait) {
109  amxb_close_request(&request);
110  }
111 
112  goto exit;
113  }
114 
115  if((request->cb_fn != NULL) && (request->bus_retval == 0)) {
116  request->cb_fn(ctx, request->result, request->priv);
117  }
118  if(request->done_fn != NULL) {
119  request->done_fn(ctx, request, request->bus_retval, request->priv);
120  }
121 
122 exit:
123  return;
124 }
int amxb_close_request(amxb_request_t **request)
Closes a previously create remote function called context.
amxb_bus_ctx_t * amxb_request_get_ctx(amxb_request_t *request)
Get the bus context of the request if any.
amxb_be_cb_fn_t cb_fn
Definition: amxb_types.h:141
amxb_be_done_cb_fn_t done_fn
Definition: amxb_types.h:142
bool in_flight
Definition: amxb_priv.h:73
bool closed
Definition: amxb_priv.h:74
bool wait
Definition: amxb_priv.h:75

◆ amxb_invoke_be_impl()

static int amxb_invoke_be_impl ( amxb_invoke_t invoke_ctx,
amxb_bus_ctx_t ctx,
amxc_var_t *  args,
amxb_request_t request,
int  timeout,
bool  async 
)
static

Definition at line 205 of file amxb_ba_invoke.c.

210  {
211  amxc_var_t* func_args = args;
212  const amxb_be_funcs_t* fns = NULL;
213  int retval = -1;
214 
215  if((amxc_var_type_of(args) == AMXC_VAR_ID_NULL) ||
216  ( amxc_var_type_of(args) == AMXC_VAR_ID_INVALID)) {
217  func_args = NULL;
218  }
219 
220  fns = ctx->bus_fn;
221  if(async) {
222  if(amxb_is_valid_be_func(fns, invoke, fns->async_invoke)) {
223  retval = fns->async_invoke(ctx->bus_ctx,
224  invoke_ctx,
225  func_args,
226  request);
227  } else {
229  }
230  } else {
231  if(amxb_is_valid_be_func(fns, invoke, fns->invoke)) {
232  retval = fns->invoke(ctx->bus_ctx,
233  invoke_ctx,
234  func_args,
235  request,
236  timeout);
237  } else {
239  }
240  }
241 
242  return retval;
243 }
#define amxb_is_valid_be_func(ft, member, ptr)
Definition: amxb_priv.h:78
#define AMXB_ERROR_NOT_SUPPORTED_OP
Function/operation not supported.
Definition: amxb_error.h:110
The back-end interface structure.
amxb_be_invoke_fn_t invoke
amxb_be_async_invoke_fn_t async_invoke
const amxb_be_funcs_t * bus_fn
Definition: amxb_types.h:121
void * bus_ctx
Definition: amxb_types.h:122

◆ amxb_invoke_local_impl()

static int amxb_invoke_local_impl ( amxb_invoke_t invoke_ctx,
amxb_bus_ctx_t ctx,
amxc_var_t *  args,
amxb_request_t request,
bool  async 
)
static

Definition at line 142 of file amxb_ba_invoke.c.

146  {
147  int retval = -1;
148  amxb_req_t* req = amxc_container_of(request, amxb_req_t, data);
149  amxc_var_t empty_args;
150  amxc_var_t* fn_rv = NULL;
151  amxc_var_t* out_args = NULL;
152  amxd_object_t* object = NULL;
153  amxc_var_init(&empty_args);
154  amxc_var_set_type(&empty_args, AMXC_VAR_ID_HTABLE);
155 
156  object = amxb_fetch_local_object(ctx, invoke_ctx->object);
157  when_null_status(object, exit, retval = amxd_status_object_not_found);
158 
159  if(args == NULL) {
160  args = &empty_args;
161  }
162 
163  amxc_var_set_type(request->result, AMXC_VAR_ID_LIST);
164  fn_rv = amxc_var_add_new(request->result);
165 
166  retval = amxd_object_invoke_function(object, invoke_ctx->method, args, fn_rv);
167  if(!amxc_htable_is_empty(amxc_var_constcast(amxc_htable_t, args))) {
168  out_args = amxc_var_add_new(request->result);
169  amxc_var_move(out_args, args);
170  }
171 
172  request->bus_retval = retval;
173 
174  if(async) {
175  if((request->done_fn != NULL) || (request->cb_fn != NULL)) {
176  req->in_flight = true;
177  if(retval == amxd_status_deferred) {
178  uint64_t call_id = amxc_var_constcast(uint64_t, fn_rv);
179  amxd_function_set_deferred_cb(call_id, amxb_complete_async_deferred_invoke, req);
180  retval = 0;
181  } else {
182  amxp_sigmngr_deferred_call(NULL, amxb_complete_async_invoke, NULL, req);
183  retval = 0;
184  }
185  }
186  } else {
187  if(retval == amxd_status_deferred) {
188  uint64_t call_id = 0;
189  req->in_flight = true;
190  call_id = amxc_var_constcast(uint64_t, fn_rv);
191  amxd_function_set_deferred_cb(call_id, amxb_complete_async_deferred_invoke, req);
192  } else {
193  when_failed(retval, exit);
194  if(request->cb_fn != NULL) {
195  request->cb_fn(ctx, request->result, request->priv);
196  }
197  }
198  }
199 
200 exit:
201  amxc_var_clean(&empty_args);
202  return retval;
203 }
static void amxb_complete_async_deferred_invoke(const amxc_var_t *const data, void *const priv)
amxd_object_t * amxb_fetch_local_object(amxb_bus_ctx_t *ctx, const char *object)
Definition: amxb_ba_priv.c:87
char * method
Definition: amxb_types.h:153
char * object
Definition: amxb_types.h:151

◆ amxb_invoke_wait_local()

static int amxb_invoke_wait_local ( amxb_req_t req,
int  timeout 
)
static

Definition at line 245 of file amxb_ba_invoke.c.

245  {
246  int retval = -1;
247  if(req->in_flight) {
248  int fd = amxp_signal_fd();
249  struct timeval t = {
250  .tv_sec = timeout,
251  .tv_usec = 0
252  };
253 
254  fd_set readset;
255  FD_ZERO(&readset);
256  FD_SET(fd, &readset);
257 
258  req->wait = true;
259  while(req->in_flight) {
260  retval = select(fd + 1, &readset, NULL, NULL, &t);
261  if(retval <= 0) {
262  // timeout or error
263  retval = -1;
264  break;
265  }
266  amxp_signal_read();
267  }
268  req->wait = false;
269  }
270  if(!req->in_flight) {
271  retval = req->data.bus_retval;
272  if(req->closed) {
273  amxb_request_t* request = &req->data;
274  amxb_close_request(&request);
275  }
276  }
277 
278  return retval;
279 }

◆ amxb_trim()

static void amxb_trim ( char *  str,
amxc_string_is_char_fn_t  fn 
)
static

Definition at line 91 of file amxb_ba_invoke.c.

91  {
92  amxc_string_t txt;
93  amxc_string_init(&txt, 0);
94  amxc_string_push_buffer(&txt, str, strlen(str) + 1);
95  amxc_string_trimr(&txt, fn);
96  amxc_string_take_buffer(&txt);
97  amxc_string_clean(&txt);
98 }

◆ isbrace()

static int isbrace ( int  c)
static

Definition at line 83 of file amxb_ba_invoke.c.

83  {
84  if((c == '(') || (c == ')')) {
85  return 1;
86  }
87 
88  return 0;
89 }

◆ isdot()

static int isdot ( int  c)
static

Definition at line 75 of file amxb_ba_invoke.c.

75  {
76  if(c == '.') {
77  return 1;
78  }
79 
80  return 0;
81 }