Also allow the ringbuffer to pass ETIMEDOUT back to the client applications.
Signed-off-by: Angus Salkeld asalkeld@redhat.com --- include/qb/qbipcc.h | 9 ++++----- lib/ipc_shm.c | 15 ++------------- lib/ipc_us.c | 4 ++-- lib/ipcc.c | 47 ++++++++++++++++------------------------------- lib/ipcs.c | 18 ++++++++++++------ tests/bmc.c | 12 ++---------- tests/bmcpt.c | 21 ++++++++------------- tests/check_ipc.c | 21 ++++++++++----------- 8 files changed, 56 insertions(+), 91 deletions(-)
diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h index 1fa892c..b6f94a8 100644 --- a/include/qb/qbipcc.h +++ b/include/qb/qbipcc.h @@ -113,7 +113,7 @@ ssize_t qb_ipcc_sendv(qb_ipcc_connection_t* c, const struct iovec* iov, * @return (size recv'ed, -errno == error) */ ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr, - size_t msg_len); + size_t msg_len, int32_t ms_timeout);
/** * This is a convenience function that simply sends and then recvs. @@ -127,10 +127,9 @@ ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr, * @see qb_ipcc_sendv() qb_ipcc_recv() */ ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c, - const struct iovec *iov, - unsigned int iov_len, - void *msg_ptr, - size_t msg_len); + const struct iovec *iov, uint32_t iov_len, + void *msg_ptr, size_t msg_len, + int32_t ms_timeout);
/** * Receive an event. diff --git a/lib/ipc_shm.c b/lib/ipc_shm.c index 1b8fd6e..55670dc 100644 --- a/lib/ipc_shm.c +++ b/lib/ipc_shm.c @@ -86,34 +86,23 @@ static ssize_t qb_ipc_shm_recv(struct qb_ipc_one_way *one_way, size_t msg_len, int32_t ms_timeout) { - ssize_t res; if (one_way->u.shm.rb == NULL) { return -ENOTCONN; } - res = qb_rb_chunk_read(one_way->u.shm.rb, + return qb_rb_chunk_read(one_way->u.shm.rb, (void *)msg_ptr, msg_len, ms_timeout); - if (res == -ETIMEDOUT) { - return -EAGAIN; - } - return res; }
static ssize_t qb_ipc_shm_peek(struct qb_ipc_one_way *one_way, void **data_out, int32_t ms_timeout) { - ssize_t res; - if (one_way->u.shm.rb == NULL) { return -ENOTCONN; } - res = qb_rb_chunk_peek(one_way->u.shm.rb, + return qb_rb_chunk_peek(one_way->u.shm.rb, data_out, ms_timeout); - if (res == -ETIMEDOUT) { - return -EAGAIN; - } - return res; }
static void qb_ipc_shm_reclaim(struct qb_ipc_one_way *one_way) diff --git a/lib/ipc_us.c b/lib/ipc_us.c index 14da2dd..3fe0ddd 100644 --- a/lib/ipc_us.c +++ b/lib/ipc_us.c @@ -227,7 +227,7 @@ ssize_t qb_ipc_us_recv(struct qb_ipc_one_way *one_way,
retry_recv: result = recv(one_way->u.us.sock, msg, len, MSG_NOSIGNAL | MSG_WAITALL); - if (result == -1 && errno == EAGAIN) { + if (timeout == -1 && result == -1 && errno == EAGAIN) { goto retry_recv; } if (result == -1) { @@ -318,7 +318,7 @@ int32_t qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, return res; }
- res = qb_ipc_us_recv(&c->setup, r, sizeof(struct qb_ipc_connection_response), 0); + res = qb_ipc_us_recv(&c->setup, r, sizeof(struct qb_ipc_connection_response), -1); if (res < 0) { return res; } diff --git a/lib/ipcc.c b/lib/ipcc.c index 5fb8039..8248cdd 100644 --- a/lib/ipcc.c +++ b/lib/ipcc.c @@ -131,55 +131,40 @@ ssize_t qb_ipcc_sendv(struct qb_ipcc_connection* c, const struct iovec* iov, }
ssize_t qb_ipcc_recv(struct qb_ipcc_connection * c, void *msg_ptr, - size_t msg_len) + size_t msg_len, int32_t ms_timeout) { int32_t res = 0; - int32_t retries = 0; - - recv_retry: - retries++; - res = c->funcs.recv(&c->response, msg_ptr, msg_len, 100); - if (res == -EAGAIN && c->needs_sock_for_poll) { - res = qb_ipc_us_recv_ready(&c->setup, 0); - if (res == -EAGAIN && retries < 50) { - goto recv_retry; - } else if (res < 0) { - return res; + int32_t res2 = 0; + + res = c->funcs.recv(&c->response, msg_ptr, msg_len, ms_timeout); + if ((res == -EAGAIN || res == -ETIMEDOUT) && c->needs_sock_for_poll) { + res2 = qb_ipc_us_recv_ready(&c->setup, 0); + if (res2 < 0) { + return res2; } else { - return -EAGAIN; + return res; } } return res; }
-ssize_t qb_ipcc_sendv_recv ( - qb_ipcc_connection_t *c, - const struct iovec *iov, - unsigned int iov_len, - void *res_msg, - size_t res_len) +ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c, + const struct iovec *iov, uint32_t iov_len, + void *res_msg, size_t res_len, + int32_t ms_timeout) { - ssize_t res; + ssize_t res = 0;
if (c->funcs.fc_get && c->funcs.fc_get(&c->request)) { return -EAGAIN; }
-repeat_send: res = qb_ipcc_sendv(c, iov, iov_len); if (res < 0) { - if (res == -EAGAIN) { - goto repeat_send; - } return res; }
-repeat_recv: - res = qb_ipcc_recv(c, res_msg, res_len); - if (res == -EAGAIN) { - goto repeat_recv; - } - return res; + return qb_ipcc_recv(c, res_msg, res_len, ms_timeout); }
int32_t qb_ipcc_fd_get(struct qb_ipcc_connection * c, int32_t * fd) @@ -217,7 +202,7 @@ ssize_t qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt, return size; } if (c->needs_sock_for_poll) { - res = qb_ipc_us_recv(&c->setup, &one_byte, 1, 0); + res = qb_ipc_us_recv(&c->setup, &one_byte, 1, -1); if (res < 0) { return res; } diff --git a/lib/ipcs.c b/lib/ipcs.c index 51a3164..2c615ba 100644 --- a/lib/ipcs.c +++ b/lib/ipcs.c @@ -211,7 +211,7 @@ ssize_t qb_ipcs_response_send(struct qb_ipcs_connection *c, const void *data, res = c->service->funcs.send(&c->response, data, size); if (res == size) { c->stats.responses++; - } else if (res == -EAGAIN) { + } else if (res == -EAGAIN || res == -ETIMEDOUT) { c->stats.send_retries++; } qb_ipcs_connection_unref(c); @@ -227,7 +227,7 @@ ssize_t qb_ipcs_response_sendv(struct qb_ipcs_connection *c, const struct iovec res = c->service->funcs.sendv(&c->response, iov, iov_len); if (res > 0) { c->stats.responses++; - } else if (res == -EAGAIN) { + } else if (res == -EAGAIN || res == -ETIMEDOUT) { c->stats.send_retries++; } qb_ipcs_connection_unref(c); @@ -481,7 +481,7 @@ static int32_t _process_request_(struct qb_ipcs_connection *c, ms_timeout); } if (size < 0) { - if (size != -EAGAIN) { + if (size != -EAGAIN && size != -ETIMEDOUT) { qb_util_log(LOG_ERR, "%s(): %s", __func__, strerror(-res)); } else { c->stats.recv_retries++; @@ -573,6 +573,12 @@ int32_t qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, return 0; } avail = _request_q_len_get(c); + + if (c->service->needs_sock_for_poll && avail == 0) { + (void)qb_ipc_us_recv(&c->setup, bytes, 1, 0); + return 0; + } + res = avail; /* in case error */ do { res = _process_request_(c, IPC_REQUEST_TIMEOUT); @@ -585,15 +591,15 @@ int32_t qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, } while (avail > 0 && res > 0 && !c->fc_enabled);
if (c->service->needs_sock_for_poll && recvd > 0) { - (void)qb_ipc_us_recv(&c->setup, bytes, recvd, 0); + (void)qb_ipc_us_recv(&c->setup, bytes, recvd, -1); }
res = QB_MIN(0, res); - if (res == -EAGAIN || res == -ENOBUFS) { + if (res == -EAGAIN || res == -ETIMEDOUT || res == -ENOBUFS) { res = 0; } if (res != 0) { - qb_util_log(LOG_INFO, "%s returning %d : %s", + qb_util_log(LOG_DEBUG, "%s returning %d : %s", __func__, res, strerror(-res)); qb_ipcs_connection_unref(c); } diff --git a/tests/bmc.c b/tests/bmc.c index 5eafd56..e49d0e6 100644 --- a/tests/bmc.c +++ b/tests/bmc.c @@ -99,13 +99,9 @@ repeat_send: }
if (blocking) { - repeat_recv: res = qb_ipcc_recv(conn, &res_header, - sizeof(struct qb_ipc_response_header)); - if (res == -EAGAIN) { - goto repeat_recv; - } + sizeof(struct qb_ipc_response_header), -1); if (res == -EINTR) { return -1; } @@ -117,13 +113,9 @@ repeat_send: assert(res_header.size == sizeof(struct qb_ipc_response_header)); } if (events) { - repeat_event_recv: res = qb_ipcc_event_recv(conn, &res_header, - sizeof(struct qb_ipc_response_header), 0); - if (res == -EAGAIN) { - goto repeat_event_recv; - } + sizeof(struct qb_ipc_response_header), -1); if (res == -EINTR) { return -1; } diff --git a/tests/bmcpt.c b/tests/bmcpt.c index e0d4fa0..b7b1369 100644 --- a/tests/bmcpt.c +++ b/tests/bmcpt.c @@ -123,19 +123,14 @@ repeat_send: } }
- repeat_recv: - res = qb_ipcc_recv(ctx->conn, - &res_header, - sizeof(struct qb_ipc_response_header)); - if (res == -EAGAIN) { - goto repeat_recv; - } - if (res == -EINTR) { - return -1; - } - if (res < 0) { - perror("qb_ipcc_recv"); - } + res = qb_ipcc_recv(ctx->conn, &res_header, + sizeof(struct qb_ipc_response_header), -1); + if (res == -EINTR) { + return -1; + } + if (res < 0) { + perror("qb_ipcc_recv"); + } assert(res == sizeof(struct qb_ipc_response_header)); assert(res_header.id == 13); assert(res_header.size == sizeof(struct qb_ipc_response_header)); diff --git a/tests/check_ipc.c b/tests/check_ipc.c index 539e7ee..fcdf91a 100644 --- a/tests/check_ipc.c +++ b/tests/check_ipc.c @@ -111,6 +111,7 @@ static int32_t s1_msg_process_fn(qb_ipcs_connection_t *c, perror("qb_ipcs_event_send"); } } else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) { + qb_ipcs_destroy(s1); exit(0); } return 0; @@ -229,13 +230,8 @@ repeat_send: } }
- repeat_recv: - res = qb_ipcc_recv(conn, - &res_header, - sizeof(struct qb_ipc_response_header)); - if (res == -EAGAIN) { - goto repeat_recv; - } + res = qb_ipcc_recv(conn, &res_header, + sizeof(struct qb_ipc_response_header), -1); if (res == -EINTR) { return -1; } @@ -371,7 +367,7 @@ static void test_ipc_dispatch(void) repeat_event_recv: res = qb_ipcc_event_recv(conn, res_header, IPC_BUF_SIZE, 0); if (res < 0) { - if (res == -EAGAIN) { + if (res == -EAGAIN || res == -ETIMEDOUT) { goto repeat_event_recv; } else { errno = -res; @@ -442,11 +438,14 @@ static void test_ipc_server_fail(void) }
/* + * wait a bit for the server to die. + */ + sleep(1); + /* * try recv from the exit'ed server */ - res = qb_ipcc_recv(conn, - &res_header, - sizeof(struct qb_ipc_response_header)); + res = qb_ipcc_recv(conn, &res_header, + sizeof(struct qb_ipc_response_header), 100); /* * confirm we get -ENOTCONN */