jsonrpc: always allocate response for request
We already have send buffer allocated. This will greatly improving code as we guarantee by design that there is always JSON write context object. Change-Id: Id487c01448e1a65d9d4ef76d40a2a9f178b2f570 Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com> Signed-off-by: Pawel Kaminski <pawelx.kaminski@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/459341 Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
6ad6a1131b
commit
a15dcb0bf0
@ -186,8 +186,7 @@ int spdk_jsonrpc_conn_del_close_cb(struct spdk_jsonrpc_server_conn *conn,
|
||||
*
|
||||
* \param request JSON-RPC request to respond to.
|
||||
|
||||
* \return JSON write context to write the response object to, or NULL if no
|
||||
* response is necessary.
|
||||
* \return Non-NULL pointer to JSON write context to write the response object to.
|
||||
*/
|
||||
struct spdk_json_write_ctx *spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request);
|
||||
|
||||
|
@ -67,6 +67,8 @@ struct spdk_jsonrpc_request {
|
||||
|
||||
uint8_t *send_buf;
|
||||
|
||||
struct spdk_json_write_ctx *response;
|
||||
|
||||
STAILQ_ENTRY(spdk_jsonrpc_request) link;
|
||||
};
|
||||
|
||||
|
@ -195,6 +195,13 @@ spdk_jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, const void *js
|
||||
return -1;
|
||||
}
|
||||
|
||||
request->response = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, request, 0);
|
||||
if (request->response == NULL) {
|
||||
SPDK_ERRLOG("Failed to allocate response JSON write context.\n");
|
||||
spdk_jsonrpc_free_request(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc <= 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n");
|
||||
spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
|
||||
@ -236,15 +243,11 @@ spdk_jsonrpc_get_conn(struct spdk_jsonrpc_request *request)
|
||||
return request->conn;
|
||||
}
|
||||
|
||||
/* Never return NULL */
|
||||
static struct spdk_json_write_ctx *
|
||||
begin_response(struct spdk_jsonrpc_request *request)
|
||||
{
|
||||
struct spdk_json_write_ctx *w;
|
||||
|
||||
w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, request, 0);
|
||||
if (w == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
struct spdk_json_write_ctx *w = request->response;
|
||||
|
||||
spdk_json_write_object_begin(w);
|
||||
spdk_json_write_named_string(w, "jsonrpc", "2.0");
|
||||
@ -263,14 +266,18 @@ static void
|
||||
skip_response(struct spdk_jsonrpc_request *request)
|
||||
{
|
||||
request->send_len = 0;
|
||||
spdk_json_write_end(request->response);
|
||||
request->response = NULL;
|
||||
spdk_jsonrpc_server_send_response(request);
|
||||
}
|
||||
|
||||
static void
|
||||
end_response(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
|
||||
end_response(struct spdk_jsonrpc_request *request)
|
||||
{
|
||||
spdk_json_write_object_end(w);
|
||||
spdk_json_write_end(w);
|
||||
spdk_json_write_object_end(request->response);
|
||||
spdk_json_write_end(request->response);
|
||||
request->response = NULL;
|
||||
|
||||
spdk_jsonrpc_server_write_cb(request, "\n", 1);
|
||||
spdk_jsonrpc_server_send_response(request);
|
||||
}
|
||||
@ -282,6 +289,9 @@ spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request)
|
||||
return;
|
||||
}
|
||||
|
||||
/* We must send or skip response explicitly */
|
||||
assert(request->response == NULL);
|
||||
|
||||
request->conn->outstanding_requests--;
|
||||
free(request->recv_buffer);
|
||||
free(request->values);
|
||||
@ -292,22 +302,9 @@ spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request)
|
||||
struct spdk_json_write_ctx *
|
||||
spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
|
||||
{
|
||||
struct spdk_json_write_ctx *w;
|
||||
|
||||
if (request->id == NULL || request->id->type == SPDK_JSON_VAL_NULL) {
|
||||
/* Notification - no response required */
|
||||
skip_response(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w = begin_response(request);
|
||||
if (w == NULL) {
|
||||
skip_response(request);
|
||||
return NULL;
|
||||
}
|
||||
struct spdk_json_write_ctx *w = begin_response(request);
|
||||
|
||||
spdk_json_write_name(w, "result");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@ -315,43 +312,37 @@ void
|
||||
spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
|
||||
{
|
||||
assert(w != NULL);
|
||||
assert(w == request->response);
|
||||
|
||||
end_response(request, w);
|
||||
/* If there was no ID in request we skip response. */
|
||||
if (request->id && request->id->type != SPDK_JSON_VAL_NULL) {
|
||||
end_response(request);
|
||||
} else {
|
||||
skip_response(request);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
|
||||
int error_code, const char *msg)
|
||||
{
|
||||
struct spdk_json_write_ctx *w;
|
||||
|
||||
w = begin_response(request);
|
||||
if (w == NULL) {
|
||||
skip_response(request);
|
||||
return;
|
||||
}
|
||||
struct spdk_json_write_ctx *w = begin_response(request);
|
||||
|
||||
spdk_json_write_named_object_begin(w, "error");
|
||||
spdk_json_write_named_int32(w, "code", error_code);
|
||||
spdk_json_write_named_string(w, "message", msg);
|
||||
spdk_json_write_object_end(w);
|
||||
|
||||
end_response(request, w);
|
||||
end_response(request);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
|
||||
int error_code, const char *fmt, ...)
|
||||
{
|
||||
struct spdk_json_write_ctx *w;
|
||||
struct spdk_json_write_ctx *w = begin_response(request);
|
||||
va_list args;
|
||||
|
||||
w = begin_response(request);
|
||||
if (w == NULL) {
|
||||
skip_response(request);
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_json_write_named_object_begin(w, "error");
|
||||
spdk_json_write_named_int32(w, "code", error_code);
|
||||
va_start(args, fmt);
|
||||
@ -359,7 +350,7 @@ spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
|
||||
va_end(args);
|
||||
spdk_json_write_object_end(w);
|
||||
|
||||
end_response(request, w);
|
||||
end_response(request);
|
||||
}
|
||||
|
||||
SPDK_LOG_REGISTER_COMPONENT("rpc", SPDK_LOG_RPC)
|
||||
|
@ -133,13 +133,33 @@ const struct spdk_json_val *g_cur_param;
|
||||
g_cur_param++
|
||||
|
||||
#define FREE_REQUEST() \
|
||||
spdk_jsonrpc_free_request(g_request); \
|
||||
ut_jsonrpc_free_request(g_request, g_parse_error); \
|
||||
g_request = NULL; \
|
||||
g_cur_param = NULL; \
|
||||
g_parse_error = 0; \
|
||||
g_method = NULL; \
|
||||
g_cur_param = g_params = NULL
|
||||
|
||||
static void
|
||||
ut_jsonrpc_free_request(struct spdk_jsonrpc_request *request, int err)
|
||||
{
|
||||
struct spdk_json_write_ctx *w;
|
||||
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to emulate response to get the response write contex free */
|
||||
if (err == 0) {
|
||||
w = spdk_jsonrpc_begin_result(request);
|
||||
spdk_json_write_string(w, "UT PASS response");
|
||||
spdk_jsonrpc_end_result(request, w);
|
||||
} else {
|
||||
spdk_jsonrpc_send_error_response_fmt(request, err, "UT error response");
|
||||
}
|
||||
|
||||
spdk_jsonrpc_free_request(request);
|
||||
}
|
||||
|
||||
static void
|
||||
ut_handle(struct spdk_jsonrpc_request *request, int error, const struct spdk_json_val *method,
|
||||
@ -168,7 +188,6 @@ spdk_jsonrpc_server_handle_request(struct spdk_jsonrpc_request *request,
|
||||
void
|
||||
spdk_jsonrpc_server_send_response(struct spdk_jsonrpc_request *request)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user