See patch description.
Regards,
Honza
commit 7d02858b7f565e991ed31d0539c4474d44b84df5
Author: Jan Friesse <[email protected]>
Date: Wed May 26 15:58:35 2010 +0200
coroipcc - don't loop forever on EINTR
This patch unify behaviour of SYS V semaphores and POSIX semaphores.
POSIX semaphores never return CS_ERR_TRY_AGAIN on EINTR and keeps
waiting. This was fixed for SYS V semaphores in rev. 2303.
Another change is to remove very small probability of hung forever in
coroipcc_dispatch_put.
Last change is removal of duplicate code by adding ipc_sem_wait function.
diff --git a/trunk/lib/coroipcc.c b/trunk/lib/coroipcc.c
index 7d0a6fb..0d2d13b 100644
--- a/trunk/lib/coroipcc.c
+++ b/trunk/lib/coroipcc.c
@@ -469,34 +469,48 @@ retry_semop:
return (CS_OK);
}
-static cs_error_t
-reply_receive (
+inline static cs_error_t
+ipc_sem_wait (
struct ipc_instance *ipc_instance,
- void *res_msg,
- size_t res_len)
+ int sem_num)
{
#if _POSIX_THREAD_PROCESS_SHARED < 1
struct sembuf sop;
#else
struct timespec timeout;
struct pollfd pfd;
+ sem_t *sem;
#endif
- coroipc_response_header_t *response_header;
int res;
#if _POSIX_THREAD_PROCESS_SHARED > 0
+ switch (sem_num) {
+ case 0:
+ sem = &ipc_instance->control_buffer->sem0;
+ break;
+ case 1:
+ sem = &ipc_instance->control_buffer->sem1;
+ break;
+ case 2:
+ sem = &ipc_instance->control_buffer->sem2;
+ break;
+ }
+
retry_semwait:
timeout.tv_sec = time(NULL) + IPC_SEMWAIT_TIMEOUT;
timeout.tv_nsec = 0;
- res = sem_timedwait (&ipc_instance->control_buffer->sem1, &timeout);
+ res = sem_timedwait (sem, &timeout);
if (res == -1 && errno == ETIMEDOUT) {
pfd.fd = ipc_instance->fd;
pfd.events = 0;
res = poll (&pfd, 1, 0);
- if (res == -1 && errno != EINTR) {
+ if (res == -1 && errno == EINTR) {
+ return (CS_ERR_TRY_AGAIN);
+ } else
+ if (res == -1) {
return (CS_ERR_LIBRARY);
}
@@ -507,17 +521,19 @@ retry_semwait:
}
goto retry_semwait;
- }
-
+ } else
if (res == -1 && errno == EINTR) {
- goto retry_semwait;
+ return (CS_ERR_TRY_AGAIN);
+ } else
+ if (res == -1) {
+ return (CS_ERR_LIBRARY);
}
#else
/*
- * Wait for semaphore #1 indicating a new message from server
- * to client in the response queue
+ * Wait for semaphore indicating a new message from server
+ * to client in queue
*/
- sop.sem_num = 1;
+ sop.sem_num = sem_num;
sop.sem_op = -1;
sop.sem_flg = 0;
@@ -534,6 +550,21 @@ retry_semop:
return (CS_ERR_LIBRARY);
}
#endif
+ return (CS_OK);
+}
+
+static cs_error_t
+reply_receive (
+ struct ipc_instance *ipc_instance,
+ void *res_msg,
+ size_t res_len)
+{
+ coroipc_response_header_t *response_header;
+ cs_error_t err;
+
+ if ((err = ipc_sem_wait (ipc_instance, 1)) != CS_OK) {
+ return (err);
+ }
response_header = (coroipc_response_header_t
*)ipc_instance->response_buffer;
if (response_header->error == CS_ERR_TRY_AGAIN) {
@@ -549,62 +580,12 @@ reply_receive_in_buf (
struct ipc_instance *ipc_instance,
void **res_msg)
{
-#if _POSIX_THREAD_PROCESS_SHARED < 1
- struct sembuf sop;
-#else
- struct timespec timeout;
- struct pollfd pfd;
-#endif
- int res;
-
-#if _POSIX_THREAD_PROCESS_SHARED > 0
-retry_semwait:
- timeout.tv_sec = time(NULL) + IPC_SEMWAIT_TIMEOUT;
- timeout.tv_nsec = 0;
+ cs_error_t err;
- res = sem_timedwait (&ipc_instance->control_buffer->sem1, &timeout);
- if (res == -1 && errno == ETIMEDOUT) {
- pfd.fd = ipc_instance->fd;
- pfd.events = 0;
-
- res = poll (&pfd, 1, 0);
-
- if (res == -1 && errno != EINTR) {
- return (CS_ERR_LIBRARY);
- }
- if (pfd.revents == POLLERR || pfd.revents == POLLHUP) {
- return (CS_ERR_LIBRARY);
- }
-
- goto retry_semwait;
+ if ((err = ipc_sem_wait (ipc_instance, 1)) != CS_OK) {
+ return (err);
}
- if (res == -1 && errno == EINTR) {
- goto retry_semwait;
- }
-#else
- /*
- * Wait for semaphore #1 indicating a new message from server
- * to client in the response queue
- */
- sop.sem_num = 1;
- sop.sem_op = -1;
- sop.sem_flg = 0;
-
-retry_semop:
- res = semop (ipc_instance->semid, &sop, 1);
- if (res == -1 && errno == EINTR) {
- return (CS_ERR_TRY_AGAIN);
- } else
- if (res == -1 && errno == EACCES) {
- priv_change_send (ipc_instance);
- goto retry_semop;
- } else
- if (res == -1) {
- return (CS_ERR_LIBRARY);
- }
-#endif
-
*res_msg = (char *)ipc_instance->response_buffer;
return (CS_OK);
}
@@ -987,12 +968,9 @@ error_put:
cs_error_t
coroipcc_dispatch_put (hdb_handle_t handle)
{
-#if _POSIX_THREAD_PROCESS_SHARED < 1
- struct sembuf sop;
-#endif
coroipc_response_header_t *header;
struct ipc_instance *ipc_instance;
- int res;
+ cs_error_t res;
char *addr;
unsigned int read_idx;
@@ -1000,31 +978,10 @@ coroipcc_dispatch_put (hdb_handle_t handle)
if (res != CS_OK) {
return (res);
}
-#if _POSIX_THREAD_PROCESS_SHARED > 0
-retry_semwait:
- res = sem_wait (&ipc_instance->control_buffer->sem2);
- if (res == -1 && errno == EINTR) {
- goto retry_semwait;
- }
-#else
- sop.sem_num = 2;
- sop.sem_op = -1;
- sop.sem_flg = 0;
-retry_semop:
- res = semop (ipc_instance->semid, &sop, 1);
- if (res == -1 && errno == EINTR) {
- res = CS_ERR_TRY_AGAIN;
- goto error_exit;
- } else
- if (res == -1 && errno == EACCES) {
- priv_change_send (ipc_instance);
- goto retry_semop;
- } else
- if (res == -1) {
- res = CS_ERR_LIBRARY;
+
+ if ((res = ipc_sem_wait (ipc_instance, 2)) != CS_OK) {
goto error_exit;
}
-#endif
addr = ipc_instance->dispatch_buffer;
@@ -1037,9 +994,7 @@ retry_semop:
*/
res = CS_OK;
-#if _POSIX_THREAD_PROCESS_SHARED < 1
error_exit:
-#endif
hdb_handle_put (&ipc_hdb, handle);
hdb_handle_put (&ipc_hdb, handle);
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais