This is because semaphores can't detect the other side has
failed/exited. So we rely on the socket poll to tell us.
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
lib/ipc_int.h | 2 ++
lib/ipcc.c | 29 ++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
index 67093fc..b4bdebc 100644
--- a/lib/ipc_int.h
+++ b/lib/ipc_int.h
@@ -39,6 +39,8 @@
#include <semaphore.h>
#endif /* HAVE_POSIX_SHARED_SEMAPHORE */
+#define QB_IPC_MAX_WAIT_MS 2000
+
/*
Client Server
SEND CONN REQ ->
diff --git a/lib/ipcc.c b/lib/ipcc.c
index e801538..cc664b4 100644
--- a/lib/ipcc.c
+++ b/lib/ipcc.c
@@ -220,6 +220,8 @@ qb_ipcc_sendv_recv(qb_ipcc_connection_t * c,
void *res_msg, size_t res_len, int32_t ms_timeout)
{
ssize_t res = 0;
+ int32_t timeout_now;
+ int32_t timeout_rem = ms_timeout;
if (c == NULL) {
return -EINVAL;
@@ -243,7 +245,32 @@ qb_ipcc_sendv_recv(qb_ipcc_connection_t * c,
return res;
}
- return qb_ipcc_recv(c, res_msg, res_len, ms_timeout);
+ do {
+ if (timeout_rem > QB_IPC_MAX_WAIT_MS || ms_timeout == -1) {
+ timeout_now = QB_IPC_MAX_WAIT_MS;
+ } else {
+ timeout_now = timeout_rem;
+ }
+
+ res = qb_ipcc_recv(c, res_msg, res_len, timeout_now);
+ if (res == -ETIMEDOUT) {
+ if (ms_timeout < 0) {
+ res = -EAGAIN;
+ } else {
+ timeout_rem -= timeout_now;
+ if (timeout_rem > 0) {
+ res = -EAGAIN;
+ }
+ }
+ } else if (res < 0 && res != -EAGAIN) {
+ errno = -res;
+ qb_util_perror(LOG_DEBUG,
+ "qb_ipcc_recv %d timeout:(%d/%d)",
+ res, timeout_now, timeout_rem);
+ }
+ } while (res == -EAGAIN && c->is_connected);
+
+ return res;
}
int32_t
--
1.7.7.6
Show replies by date
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
lib/ringbuffer.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c
index 2116d88..b840981 100644
--- a/lib/ringbuffer.c
+++ b/lib/ringbuffer.c
@@ -556,6 +556,9 @@ qb_rb_chunk_read(struct qb_ringbuffer_s * rb, void *data_out, size_t
len,
chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
if (len < chunk_size) {
+ qb_util_log(LOG_ERR,
+ "trying to recv chunk of size %d but %d available",
+ len, chunk_size);
return -ENOBUFS;
}
--
1.7.7.6
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
tests/check_ipc.c | 26 ++++++--------------------
1 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/tests/check_ipc.c b/tests/check_ipc.c
index 225d379..d0ad31d 100644
--- a/tests/check_ipc.c
+++ b/tests/check_ipc.c
@@ -113,7 +113,6 @@ s1_msg_process_fn(qb_ipcs_connection_t *c,
qb_perror(LOG_INFO, "qb_ipcs_event_send");
}
} else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) {
- qb_ipcs_destroy(s1);
exit(0);
}
return 0;
@@ -525,6 +524,7 @@ test_ipc_server_fail(void)
{
struct qb_ipc_request_header req_header;
struct qb_ipc_response_header res_header;
+ struct iovec iov[1];
int32_t res;
int32_t try_times = 0;
int32_t j;
@@ -552,26 +552,12 @@ test_ipc_server_fail(void)
req_header.id = IPC_MSG_REQ_SERVER_FAIL;
req_header.size = sizeof(struct qb_ipc_request_header);
- repeat_send:
- res = qb_ipcc_send(conn, &req_header, req_header.size);
- try_times++;
- if (res < 0) {
- if (res == -EAGAIN && try_times < 10) {
- goto repeat_send;
- }
- ck_assert_int_eq(res, 0);
- }
+ iov[0].iov_len = req_header.size;
+ iov[0].iov_base = &req_header;
- /*
- * wait a bit for the server to die.
- */
- sleep(1);
- /*
- * try recv from the exit'ed server
- * assertion: we can call recv without locking up
- */
- res = qb_ipcc_recv(conn, &res_header,
- sizeof(struct qb_ipc_response_header), 100);
+ res = qb_ipcc_sendv_recv(conn, iov, 1,
+ &res_header,
+ sizeof(struct qb_ipc_response_header), -1);
/*
* confirm we get -ENOTCONN
*/
--
1.7.7.6