First attached is patch solving $SUBJ bug intended for Z-stream.
Real solution based on Posix semaphores for 5.6 is in progress.

Second patch should solve second problem with dispatch.

Regards,
  Honza

commit e3e5d8112cbcfe3307e31f330337135a392360b6
Author: Jan Friesse <[email protected]>
Date:   Wed May 26 14:52:19 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..f285eb5 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,
@@ -455,11 +466,77 @@ static void memcpy_swrap (
 }
 int original_flow = -1;
 
+inline static SaAisErrorT
+ipc_sem_wait (
+       struct ipc_segment *ipc_segment,
+       int sem_num)
+{
+       struct sembuf sop;
+#if defined(OPENAIS_LINUX)
+       struct timespec timeout;
+       struct pollfd pfd;
+#endif
+       int res;
+
+       sop.sem_num = sem_num;
+       sop.sem_op = -1;
+       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;
+       } else
+       if (res == -1 && errno == EACCES) {
+               priv_change_send (ipc_segment);
+               goto retry_semop;
+       } else
+       if (res == -1) {
+               return (SA_AIS_ERR_LIBRARY);
+       }
+#endif
+
+       return (SA_AIS_OK);
+}
+
 int
 openais_dispatch_recv (void *ipc_ctx, void *data, int timeout)
 {
        struct pollfd ufds;
-       struct sembuf sop;
        int poll_events;
        mar_res_header_t *header;
        char buf;
@@ -467,6 +544,7 @@ openais_dispatch_recv (void *ipc_ctx, void *data, int 
timeout)
        int res;
        unsigned int my_read;
        char buf_two = 1;
+       SaAisErrorT err;
 
        ufds.fd = ipc_segment->fd;
        ufds.events = POLLIN;
@@ -520,20 +598,7 @@ retry_recv:
                return (0);
        }
 
-       sop.sem_num = 2;
-       sop.sem_op = -1;
-       sop.sem_flg = 0;
-
-retry_semop:
-       res = semop (ipc_segment->semid, &sop, 1);
-       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) {
+       if ((err = ipc_sem_wait (ipc_segment, 2)) != SA_AIS_OK) {
                return (-1);
        }
        
@@ -610,29 +675,11 @@ openais_reply_receive (
        void *ipc_context,
        void *res_msg, int res_len)
 {
-       struct sembuf sop;
        struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context;
-       unsigned int res;
+       SaAisErrorT err;
 
-       /*
-        * 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_segment->semid, &sop, 1);
-       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) {
-               return (SA_AIS_ERR_LIBRARY);
+       if ((err = ipc_sem_wait (ipc_segment, 1)) != SA_AIS_OK) {
+               return (err);
        }
 
        memcpy (res_msg, ipc_segment->shared_memory->res_buffer, res_len);
@@ -644,29 +691,11 @@ openais_reply_receive_in_buf (
        void *ipc_context,
        void **res_msg)
 {
-       struct sembuf sop;
        struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context;
-       int res;
-
-       /*
-        * 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;
+       SaAisErrorT err;
 
-retry_semop:
-       res = semop (ipc_segment->semid, &sop, 1);
-       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) {
-               return (SA_AIS_ERR_LIBRARY);
+       if ((err = ipc_sem_wait (ipc_segment, 1)) != SA_AIS_OK) {
+               return (err);
        }
 
        *res_msg = (char *)ipc_segment->shared_memory->res_buffer;
>From dd39d40c072e4da1d37f33ddcc0f26670c2e0a0b Mon Sep 17 00:00:00 2001
From: Jan Friesse <[email protected]>
Date: Wed, 26 May 2010 15:17:52 +0200
Subject: [PATCH 2/2] Fix saEvtDispatch for error dispatch

Fixes the second problem found in 579081
---
 branches/whitetank/lib/amf.c |    5 +++++
 branches/whitetank/lib/cfg.c |    5 +++++
 branches/whitetank/lib/evt.c |    5 +++++
 branches/whitetank/lib/lck.c |    5 +++++
 branches/whitetank/lib/msg.c |    5 +++++
 5 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/branches/whitetank/lib/amf.c b/branches/whitetank/lib/amf.c
index 79e7e6f..0956bbe 100644
--- a/branches/whitetank/lib/amf.c
+++ b/branches/whitetank/lib/amf.c
@@ -228,6 +228,11 @@ saAmfDispatch (
                        continue; /* next poll */
                }
 
+               if (dispatch_avail == -1) {
+                       error = SA_AIS_ERR_LIBRARY;
+                       goto error_nounlock;
+               }
+
                /*
                 * Make copy of callbacks, message data, unlock instance, and 
call callback
                 * A risk of this dispatch method is that the callback routines 
may
diff --git a/branches/whitetank/lib/cfg.c b/branches/whitetank/lib/cfg.c
index a542e1f..fcc95a6 100644
--- a/branches/whitetank/lib/cfg.c
+++ b/branches/whitetank/lib/cfg.c
@@ -207,6 +207,11 @@ openais_cfg_dispatch (
                        continue; /* next poll */
                }
 
+               if (dispatch_avail == -1) {
+                       error = SA_AIS_ERR_LIBRARY;
+                       goto error_nounlock;
+               }
+
                /*
                 * Make copy of callbacks, message data, unlock instance, and 
call callback
                 * A risk of this dispatch method is that the callback routines 
may
diff --git a/branches/whitetank/lib/evt.c b/branches/whitetank/lib/evt.c
index be40f49..704dfff 100644
--- a/branches/whitetank/lib/evt.c
+++ b/branches/whitetank/lib/evt.c
@@ -637,6 +637,11 @@ saEvtDispatch(
                        continue; /* next poll */
                }
 
+               if (dispatch_avail == -1) {
+                       error = SA_AIS_ERR_LIBRARY;
+                       goto dispatch_unlock;
+               }
+
                /*
                 * Make copy of callbacks, message data, unlock instance, 
                 * and call callback. A risk of this dispatch method is that 
diff --git a/branches/whitetank/lib/lck.c b/branches/whitetank/lib/lck.c
index fa896f6..d991251 100644
--- a/branches/whitetank/lib/lck.c
+++ b/branches/whitetank/lib/lck.c
@@ -382,6 +382,11 @@ saLckDispatch (
                        continue;
                }
                
+               if (dispatch_avail == -1) {
+                       error = SA_AIS_ERR_LIBRARY;
+                       goto error_unlock;
+               }
+
                /*
                * Make copy of callbacks, message data, unlock instance,
                * and call callback. A risk of this dispatch method is that
diff --git a/branches/whitetank/lib/msg.c b/branches/whitetank/lib/msg.c
index 37f9ae9..6ea131a 100644
--- a/branches/whitetank/lib/msg.c
+++ b/branches/whitetank/lib/msg.c
@@ -328,6 +328,11 @@ saMsgDispatch (
                        continue;
                }
                
+               if (dispatch_avail == -1) {
+                       error = SA_AIS_ERR_LIBRARY;
+                       goto error_unlock;
+               }
+
                memset(&dispatch_data, 0, sizeof(struct message_overlay));
 
                /*
-- 
1.5.5.6

_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to