Skip to content

Commit

Permalink
ubus: add explicit support for deferring incoming requests
Browse files Browse the repository at this point in the history
This is needed when asynchronously processing requests via uloop, e.g.
using uclient.

Example script:

  let libubus = require("ubus");
  let uloop = require("uloop");

  uloop.init();
  let ubus = libubus.connect();
  ubus.publish("test", {
      test: {
          call: function(req) {
              req.defer();
              uloop.timer(1000, () => {
                  req.reply({ msg: "Hello, world!" }, 0);
              });
          },
          args: {}
      },
  });
  uloop.run();
  uloop.done();

Signed-off-by: Felix Fietkau <[email protected]>
  • Loading branch information
nbd168 committed Apr 7, 2024
1 parent 55ee75b commit 4ade84e
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion lib/ubus.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ typedef struct {
struct uloop_timeout timeout;
struct ubus_context *ctx;
size_t registry_index;
bool deferred;
bool replied;
uc_vm_t *vm;
} uc_ubus_request_t;
Expand Down Expand Up @@ -845,6 +846,18 @@ uc_ubus_request_reply(uc_vm_t *vm, size_t nargs)
ok_return(ucv_boolean_new(true));
}

static uc_value_t *
uc_ubus_request_defer(uc_vm_t *vm, size_t nargs)
{
uc_ubus_request_t *callctx = uc_fn_thisval("ubus.request");

if (!callctx)
return NULL;

callctx->deferred = true;
return ucv_boolean_new(true);
}

static uc_value_t *
uc_ubus_request_error(uc_vm_t *vm, size_t nargs)
{
Expand Down Expand Up @@ -1256,7 +1269,7 @@ uc_ubus_handle_reply_common(struct ubus_context *ctx,
/* If neither a deferred ubus request, nor a plain object were
* returned and if reqobj.reply() hasn't been called, immediately
* finish deferred request with UBUS_STATUS_NO_DATA. */
else if (!callctx->replied) {
else if (!callctx->replied && !callctx->deferred) {
rv = UBUS_STATUS_NO_DATA;

if (ucv_type(res) == UC_INTEGER) {
Expand Down Expand Up @@ -2003,6 +2016,7 @@ static const uc_function_list_t object_fns[] = {
static const uc_function_list_t request_fns[] = {
{ "reply", uc_ubus_request_reply },
{ "error", uc_ubus_request_error },
{ "defer", uc_ubus_request_defer },
};

static const uc_function_list_t notify_fns[] = {
Expand Down Expand Up @@ -2058,6 +2072,7 @@ static void free_object(void *ud) {
static void free_request(void *ud) {
uc_ubus_request_t *callctx = ud;

uc_ubus_request_finish(callctx, UBUS_STATUS_TIMEOUT, NULL);
uloop_timeout_cancel(&callctx->timeout);
free(callctx);
}
Expand Down

0 comments on commit 4ade84e

Please sign in to comment.