[PATCH] ipcc: don't use received event as response
by Jan Friesse
If SHM IPC is used and IPC client calls qb_ipcc_sendv_recv and IPC
server calls event_send (instead of response_send), value returned
by ipcc_sendv_recv is 0 (because ipcc_recv is 0).
Main problem is hidden in _check_connection_state_with function which
has two main functions. One is to check if connection is alive (then res
parameter is set to -EAGAIN) and second is to sanitize shm/us recv
result. This variant is used only by ipcc_recv and it's subject of this
patch.
If SHM IPC is used, there is only ONE socket for both events and
responses. So when qb_ipc_us_ready is called and server sent event
instead of response, original result (EAGAIN) is thrown away and
replaced by 0.
Solution is to add parameter into _check_connection_state_with function
to find out, which functionality is needed.
Signed-off-by: Jan Friesse <jfriesse(a)redhat.com>
---
lib/ipcc.c | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/lib/ipcc.c b/lib/ipcc.c
index 061cb1c..0dc53ca 100644
--- a/lib/ipcc.c
+++ b/lib/ipcc.c
@@ -91,7 +91,8 @@ disconnect_and_cleanup:
static int32_t
_check_connection_state_with(struct qb_ipcc_connection * c, int32_t res,
struct qb_ipc_one_way * one_way,
- int32_t ms_timeout, int32_t events)
+ int32_t ms_timeout, int32_t events,
+ int32_t use_ipc_us_ready_res)
{
if (res >= 0) return res;
@@ -119,7 +120,9 @@ _check_connection_state_with(struct qb_ipcc_connection * c, int32_t res,
"(from socket) as a disconnect");
c->is_connected = QB_FALSE;
}
- res = res2;
+ if (use_ipc_us_ready_res || res2 < 0) {
+ res = res2;
+ }
}
return res;
}
@@ -268,7 +271,7 @@ qb_ipcc_recv(struct qb_ipcc_connection * c, void *msg_ptr,
res = c->funcs.recv(&c->response, msg_ptr, msg_len, ms_timeout);
return _check_connection_state_with(c, res,
_response_sock_one_way_get(c),
- ms_timeout, POLLIN);
+ ms_timeout, POLLIN, QB_FALSE);
}
ssize_t
@@ -356,7 +359,7 @@ qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt,
return -EINVAL;
}
res = _check_connection_state_with(c, -EAGAIN, _event_sock_one_way_get(c),
- ms_timeout, POLLIN);
+ ms_timeout, POLLIN, QB_TRUE);
if (res < 0) {
return res;
}
@@ -382,7 +385,7 @@ qb_ipcc_disconnect(struct qb_ipcc_connection *c)
}
ow = _event_sock_one_way_get(c);
- (void)_check_connection_state_with(c, -EAGAIN, ow, 0, POLLIN);
+ (void)_check_connection_state_with(c, -EAGAIN, ow, 0, POLLIN, QB_TRUE);
if (c->funcs.disconnect) {
c->funcs.disconnect(c);
@@ -418,7 +421,7 @@ qb_ipcc_is_connected(qb_ipcc_connection_t *c)
}
ow = _response_sock_one_way_get(c);
- (void)_check_connection_state_with(c, -EAGAIN, ow, 0, POLLIN);
+ (void)_check_connection_state_with(c, -EAGAIN, ow, 0, POLLIN, QB_TRUE);
return c->is_connected;
}
--
1.7.1
10 years