Attached is patch solving $SUBJ bug intended for Z-stream. I will work on real solution based on Posix semaphores for 5.6.
Regards, Honza
commit 58c2676fcedda5df61df07735434c13fb5975cc8 Author: Jan Friesse <jfrie...@redhat.com> Date: Mon May 24 15:33:59 2010 +0200 Support for semtimedop on Linux This patch solves problem with hung semop in OpenAIS if aisexec is killed. Solves rhbz#579081 diff --git a/branches/whitetank/lib/util.c b/branches/whitetank/lib/util.c index 5dc9292..a66d320 100644 --- a/branches/whitetank/lib/util.c +++ b/branches/whitetank/lib/util.c @@ -35,6 +35,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +#if defined(OPENAIS_LINUX) +#define _GNU_SOURCE +#endif + #include <stdlib.h> #include <stdio.h> #include <unistd.h> @@ -59,6 +63,13 @@ #include "../include/ipc_gen.h" #include "util.h" +#if defined(OPENAIS_LINUX) +/* + * Define sem_wait timeout (real timeout will be (n-1;n) ) + */ +#define IPC_SEMWAIT_TIMEOUT 2 +#endif + enum SA_HANDLE_STATE { SA_HANDLE_STATE_EMPTY, SA_HANDLE_STATE_PENDINGREMOVAL, @@ -611,6 +622,10 @@ openais_reply_receive ( void *res_msg, int res_len) { struct sembuf sop; +#if defined(OPENAIS_LINUX) + struct timespec timeout; + struct pollfd pfd; +#endif struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context; unsigned int res; @@ -623,6 +638,40 @@ openais_reply_receive ( sop.sem_flg = 0; retry_semop: +#if defined(OPENAIS_LINUX) + timeout.tv_sec = IPC_SEMWAIT_TIMEOUT; + timeout.tv_nsec = 0; + + res = semtimedop (ipc_segment->semid, &sop, 1, &timeout); + if (res == -1 && errno == EINTR) { + goto retry_semop; + } else + if (res == -1 && errno == EACCES) { + priv_change_send (ipc_segment); + goto retry_semop; + } else + if (res == -1 && errno == EAGAIN) { + pfd.fd = ipc_segment->fd; + pfd.events = 0; + + res = poll (&pfd, 1, 0); + + if (res == -1 && errno != EINTR) { + return (SA_AIS_ERR_LIBRARY); + } + + if (res == 1) { + if (pfd.revents == POLLERR || pfd.revents == POLLHUP || pfd.revents == POLLNVAL) { + return (SA_AIS_ERR_LIBRARY); + } + } + + goto retry_semop; + } else + if (res == -1) { + return (SA_AIS_ERR_LIBRARY); + } +#else res = semop (ipc_segment->semid, &sop, 1); if (res == -1 && errno == EINTR) { goto retry_semop; @@ -634,7 +683,7 @@ retry_semop: if (res == -1) { return (SA_AIS_ERR_LIBRARY); } - +#endif memcpy (res_msg, ipc_segment->shared_memory->res_buffer, res_len); return (SA_AIS_OK); } @@ -645,6 +694,10 @@ openais_reply_receive_in_buf ( void **res_msg) { struct sembuf sop; +#if defined(OPENAIS_LINUX) + struct timespec timeout; + struct pollfd pfd; +#endif struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context; int res; @@ -657,6 +710,40 @@ openais_reply_receive_in_buf ( sop.sem_flg = 0; retry_semop: +#if defined(OPENAIS_LINUX) + timeout.tv_sec = IPC_SEMWAIT_TIMEOUT; + timeout.tv_nsec = 0; + + res = semtimedop (ipc_segment->semid, &sop, 1, &timeout); + if (res == -1 && errno == EINTR) { + goto retry_semop; + } else + if (res == -1 && errno == EACCES) { + priv_change_send (ipc_segment); + goto retry_semop; + } else + if (res == -1 && errno == EAGAIN) { + pfd.fd = ipc_segment->fd; + pfd.events = 0; + + res = poll (&pfd, 1, 0); + + if (res == -1 && errno != EINTR) { + return (SA_AIS_ERR_LIBRARY); + } + + if (res == 1) { + if (pfd.revents == POLLERR || pfd.revents == POLLHUP || pfd.revents == POLLNVAL) { + return (SA_AIS_ERR_LIBRARY); + } + } + + goto retry_semop; + } else + if (res == -1) { + return (SA_AIS_ERR_LIBRARY); + } +#else res = semop (ipc_segment->semid, &sop, 1); if (res == -1 && errno == EINTR) { goto retry_semop; @@ -668,7 +755,7 @@ retry_semop: if (res == -1) { return (SA_AIS_ERR_LIBRARY); } - +#endif *res_msg = (char *)ipc_segment->shared_memory->res_buffer; return (SA_AIS_OK); }
_______________________________________________ Openais mailing list Openais@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/openais