add support for deferring a reply to a method invoke call
This commit is contained in:
parent
0f793d3a45
commit
7864896a1b
2 changed files with 25 additions and 8 deletions
21
libubus.c
21
libubus.c
|
@ -342,11 +342,18 @@ static struct ubus_request *ubus_find_request(struct ubus_context *ctx, uint32_t
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ubus_complete_deferred_request(struct ubus_context *ctx, struct ubus_request_data *req, int ret)
|
||||||
|
{
|
||||||
|
blob_buf_init(&b, 0);
|
||||||
|
blob_put_int32(&b, UBUS_ATTR_STATUS, ret);
|
||||||
|
blob_put_int32(&b, UBUS_ATTR_OBJID, req->object);
|
||||||
|
ubus_send_msg(ctx, req->seq, b.head, UBUS_MSG_STATUS, req->peer);
|
||||||
|
}
|
||||||
|
|
||||||
static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr)
|
static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr)
|
||||||
{
|
{
|
||||||
struct ubus_request_data req;
|
struct ubus_request_data req;
|
||||||
struct ubus_object *obj;
|
struct ubus_object *obj;
|
||||||
uint32_t objid = 0;
|
|
||||||
int method;
|
int method;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -357,14 +364,14 @@ static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hd
|
||||||
if (!attrbuf[UBUS_ATTR_OBJID])
|
if (!attrbuf[UBUS_ATTR_OBJID])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
objid = blob_get_u32(attrbuf[UBUS_ATTR_OBJID]);
|
req.object = blob_get_u32(attrbuf[UBUS_ATTR_OBJID]);
|
||||||
|
|
||||||
if (!attrbuf[UBUS_ATTR_METHOD]) {
|
if (!attrbuf[UBUS_ATTR_METHOD]) {
|
||||||
ret = UBUS_STATUS_INVALID_ARGUMENT;
|
ret = UBUS_STATUS_INVALID_ARGUMENT;
|
||||||
goto send;
|
goto send;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = avl_find_element(&ctx->objects, &objid, obj, avl);
|
obj = avl_find_element(&ctx->objects, &req.object, obj, avl);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
ret = UBUS_STATUS_NOT_FOUND;
|
ret = UBUS_STATUS_NOT_FOUND;
|
||||||
goto send;
|
goto send;
|
||||||
|
@ -381,16 +388,14 @@ static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hd
|
||||||
goto send;
|
goto send;
|
||||||
|
|
||||||
found:
|
found:
|
||||||
req.object = objid;
|
|
||||||
ret = obj->methods[method].handler(ctx, obj, &req,
|
ret = obj->methods[method].handler(ctx, obj, &req,
|
||||||
blob_data(attrbuf[UBUS_ATTR_METHOD]),
|
blob_data(attrbuf[UBUS_ATTR_METHOD]),
|
||||||
attrbuf[UBUS_ATTR_DATA]);
|
attrbuf[UBUS_ATTR_DATA]);
|
||||||
|
if (req.deferred)
|
||||||
|
return;
|
||||||
|
|
||||||
send:
|
send:
|
||||||
blob_buf_init(&b, 0);
|
ubus_complete_deferred_request(ctx, &req, ret);
|
||||||
blob_put_int32(&b, UBUS_ATTR_STATUS, ret);
|
|
||||||
blob_put_int32(&b, UBUS_ATTR_OBJID, objid);
|
|
||||||
ubus_send_msg(ctx, req.seq, b.head, UBUS_MSG_STATUS, req.peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr)
|
static void ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr)
|
||||||
|
|
12
libubus.h
12
libubus.h
|
@ -132,6 +132,7 @@ struct ubus_request_data {
|
||||||
uint32_t object;
|
uint32_t object;
|
||||||
uint32_t peer;
|
uint32_t peer;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
|
bool deferred;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ubus_request {
|
struct ubus_request {
|
||||||
|
@ -220,6 +221,17 @@ int ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char *method
|
||||||
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
|
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
|
||||||
struct blob_attr *msg);
|
struct blob_attr *msg);
|
||||||
|
|
||||||
|
static inline void ubus_defer_request(struct ubus_context *ctx,
|
||||||
|
struct ubus_request_data *req,
|
||||||
|
struct ubus_request_data *new_req)
|
||||||
|
{
|
||||||
|
memcpy(new_req, req, sizeof(*req));
|
||||||
|
req->deferred = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ubus_complete_deferred_request(struct ubus_context *ctx,
|
||||||
|
struct ubus_request_data *req, int ret);
|
||||||
|
|
||||||
/* ----------- events ----------- */
|
/* ----------- events ----------- */
|
||||||
|
|
||||||
int ubus_send_event(struct ubus_context *ctx, const char *id,
|
int ubus_send_event(struct ubus_context *ctx, const char *id,
|
||||||
|
|
Loading…
Reference in a new issue