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

Reply via email to