From d633b4e2fa8d9cf07e9df93c1a37aa795aa10c8b Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Tue, 14 Feb 2012 16:42:59 +1100 Subject: [PATCH] IPC: split up the recv into chuncks of 2 seconds. 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 --- lib/ipc_int.h | 2 ++ lib/ipcc.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) 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 #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