Hello community,

here is the log from the commit of package libqb for openSUSE:Factory checked 
in at 2013-08-04 20:39:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libqb (Old)
 and      /work/SRC/openSUSE:Factory/.libqb.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libqb"

Changes:
--------
--- /work/SRC/openSUSE:Factory/libqb/libqb.changes      2013-07-08 
07:18:12.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.libqb.new/libqb.changes 2013-08-04 
23:52:27.000000000 +0200
@@ -1,0 +2,27 @@
+Fri Jul 26 01:19:30 UTC 2013 - [email protected]
+
+- Bump version to 0.16.0
+- ipc_socket.c: Detect EOF connection on connection STREAM socket
+- ipc_socket.c: Handle the unlikely event of an EAGAIN or EINTR during dgram 
max size detection
+- Fixes sem leak
+- Fixes less-than-zero comparision of unsigned int
+- Fixes double fd close
+- Fixes fd leak
+- Fixes use ater free in shm disconnect
+- Fixes use after free during ipcs client disconnect
+- ipcc: Add abilty to verify dgram kernel buffer size meets max msg value
+- Upstream version cs: 75f7ed373758b3cb9087e89e4fae17379dd7b483 (v0.16.0)
+
+-------------------------------------------------------------------
+Mon Jul 22 07:38:56 UTC 2013 - [email protected]
+
+- ringbuffer: Make max_size of ringbuffer accurate so shm ipc max msg size 
value is honored
+- ipcs: For shm ipc, always retry outstanding notifications when next event is 
sent
+- ipc_socket: In fbsd send() returns ENOBUFS when dgram queue is full, this 
should be treated similar to EAGAIN
+- kqueue: Properly enable kqueue filter in poll loop
+- ipcs: Attempt to resend outstanding event notifications during event send
+- ipcs: Disconnect shm ipc connection when poll socket returns error on msg 
receive
+- ipcs: Properly disconnect client connection on POLLNVAL or any other error 
causing connection removal from mainloop.
+- Upstream version cs: 39e9ef542dc89893c7c5af4fbd539338266e8031
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libqb.spec ++++++
--- /var/tmp/diff_new_pack.11ZHls/_old  2013-08-04 23:52:28.000000000 +0200
+++ /var/tmp/diff_new_pack.11ZHls/_new  2013-08-04 23:52:28.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package libqb
 #
-# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,12 +17,12 @@
 
 
 Name:           libqb
-Version:        0.14.4
+Version:        0.16.0
 Release:        0
 Summary:        An IPC library for high performance servers
 License:        LGPL-2.1+
 Group:          System/Libraries
-Url:            http://www.libqb.org
+Url:            https://github.com/ClusterLabs/libqb
 Source0:        %{name}.tar.bz2
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -31,8 +31,8 @@
 BuildRequires:  check-devel
 BuildRequires:  doxygen
 BuildRequires:  libtool
-BuildRequires:  procps
 BuildRequires:  pkgconfig
+BuildRequires:  procps
 # Need git so build-aux/git-version-gen can extract the version number and
 # commit hash during autogen run (not used currently)
 #BuildRequires:  git
@@ -44,7 +44,6 @@
 
 %package -n libqb0
 Summary:        An IPC library for high performance servers
-License:        LGPL-2.1+
 Group:          System/Libraries
 Provides:       %{name} = %{version}
 
@@ -55,7 +54,6 @@
 
 %package       devel
 Summary:        Development files for %{name}
-License:        LGPL-2.1+
 Group:          Development/Libraries/C and C++
 Requires:       %{name} = %{version}-%{release}
 Requires:       pkgconfig
@@ -69,7 +67,7 @@
 %setup -q -n %{name}
 
 %build
-#./autogen.sh
+./autogen.sh
 %configure --disable-static
 make %{?_smp_mflags}
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.11ZHls/_old  2013-08-04 23:52:28.000000000 +0200
+++ /var/tmp/diff_new_pack.11ZHls/_new  2013-08-04 23:52:28.000000000 +0200
@@ -7,8 +7,8 @@
     To update to a new release, change "revision" to the desired
     git commit hash and bump "version" if necessary
 -->
-    <param name="version">0.14.4</param>
-    <param name="revision">7c6e109046ec772a97a7fe2cdf61f84fc2155b7e</param>
+    <param name="version">0.16.0</param>
+    <param name="revision">75f7ed373758b3cb9087e89e4fae17379dd7b483</param>
   </service>
 
   <service name="recompress" mode="disabled">

++++++ libqb.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/.tarball-version new/libqb/.tarball-version
--- old/libqb/.tarball-version  2013-07-02 11:28:45.000000000 +0200
+++ new/libqb/.tarball-version  2013-07-26 03:10:21.000000000 +0200
@@ -1 +1 @@
-0.14.4.53-7c6e
+0.16.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/.version new/libqb/.version
--- old/libqb/.version  2012-06-07 11:27:48.000000000 +0200
+++ new/libqb/.version  2013-07-26 03:10:02.000000000 +0200
@@ -1 +1 @@
-0.13.0.51-e70e
+0.16.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/ChangeLog new/libqb/ChangeLog
--- old/libqb/ChangeLog 2013-07-02 11:28:45.000000000 +0200
+++ new/libqb/ChangeLog 2013-07-26 03:10:21.000000000 +0200
@@ -1,7 +1,146 @@
-2013-06-29  David Vossel  <[email protected]>
+2013-07-26  David Vossel  <[email protected]>
 
-       Merge pull request #73 from davidvossel/ref_count_cleanup
-       cleanup connection and service ref counting without changing behavior
+       Bump version to 0.16.0 ... do not use version 0.15.0
+       The use of version-info conflicted with the naming
+       convention used to represent libqb version numbers. Because
+       of this the shared library file used for release 0.15.0
+       did not properly match the release version.  From now on
+       the version number will be manually set to guarantee consistency
+       between .so file and release version.
+
+       Update release gpg sign key
+
+2013-07-25  David Vossel  <[email protected]>
+
+       Bump the version to 0.15.0
+
+2013-07-24  David Vossel  <[email protected]>
+
+       Merge pull request #83 from davidvossel/master
+       socket ipc fixes
+
+       Low: ipc_socket: Output send event failure as debug instead of error
+
+       Low: ipcserver.c: Fix example server's glib mainloop implementation
+
+       High: ipc_socket.c: Detect EOF connection on connection STREAM socket
+
+2013-07-23  David Vossel  <[email protected]>
+
+       Merge pull request #81 from davidvossel/dgram_max_msg
+       Added ability to estimate kernel's actual max dgram buffer size in a 
portable way.
+
+       Low: tests: Add dgram max size detection test
+
+       Low: ipc_socket.c: Handle the unlikely event of an EAGAIN or EINTR 
during dgram max size detection
+
+       Merge pull request #82 from davidvossel/master
+       coverity fixes
+
+       Fixes detect disconnect on send for tcp example
+
+       Fixes sem leak
+
+       Fixes less-than-zero comparision of unsigned int
+
+       fixes double close
+
+       Fixes double close
+
+       Fixes double fd close
+
+       Fixes fd leak
+
+       Prevent use after free in benchmark util
+
+       Fixes use ater free in shm disconnect
+
+       Fixes use after free during ipcs client disconnect
+
+       Remove dead code
+
+2013-07-20  David Vossel  <[email protected]>
+
+       Low: check_ipc.c: Verify dgram max size during tests
+
+       High: ipcc: Add abilty to verify dgram kernel buffer size meets max msg 
value
+
+       Fixes travis build error
+
+2013-07-19  David Vossel  <[email protected]>
+
+       Merge pull request #80 from davidvossel/master
+       Fixes travis build error
+
+       Low: check_ipc.c: fix debug message to only display once.
+
+       High: ringbuffer: Make max_size of ringbuffer accurate so shm ipc max 
msg size value is honored
+
+       Low: ipcs: For shm ipc, always retry outstanding notifications when 
next event is sent
+
+       Low: tests: Added test to verify sending ipc msg equal to max size 
succeeds
+
+       Merge pull request #79 from davidvossel/master
+       fix shared memory ipc so max msg size is honored correctly
+
+2013-07-13  David Vossel  <[email protected]>
+
+       Merge pull request #78 from davidvossel/master
+       fixes travis compile time issue
+
+       Fix: ipcs: Fixes compile time issue reported by travis
+
+       Merge pull request #77 from davidvossel/stress_tests_fixes
+       Adds new ipc event stress test and fixes issues the new test exposed
+
+       Low: loop_pool_kqueue: remove potentially noisy dbug statement
+
+       Low: tests: rework bulk event msg ipc test
+       Some environments have very small dgram msg queues. In
+       these environments we have to be able to read off the event
+       queue before being able to send the rest of events for the
+       bulk event test.
+
+       Account for fbsd ENOBUFS during stress test
+
+       Low: tests: Adds ipc event stress test to testsuite
+
+       Low: ipc_socket: In fbsd send() returns ENOBUFS when dgram queue is 
full, this should be treated similar to EAGAIN
+
+       High: kqueue: Properly enable kqueue filter in poll loop
+
+       Low: ipcs: Attempt to resend outstanding event notifications during 
event send
+
+2013-07-03  David Vossel  <[email protected]>
+
+       Merge pull request #75 from davidvossel/ref_count_cleanup
+       Low: qbipcs: update ipcs connection iterator documentation
+
+       Low: qbipcs.h: update ipcs connection iterator documentation
+
+       Merge pull request #74 from davidvossel/ref_count_cleanup
+       Properly disconnect clients when ipc dispatch fails.
+
+2013-07-02  David Vossel  <[email protected]>
+
+       Fix: ipcs: Disconnect shm ipc connection when poll socket returns error 
on msg receive
+
+       Fix: ipcs: Properly disconnect client connection on POLLNVAL or any 
other error causing connection removal from mainloop.
+       qb_ipcs_dispatch_connection_request is a callback function registered 
with
+       mainloop, or whatever other looping thread implementation is in use.  
When
+       this callback is registered, a reference of the connection object is 
given
+       to the mainloop thread.  If this callback ever returns something none 
zero
+       the callback (and corresponding fd) is unregistered from the loop 
automatically,
+       so we must decrement the reference in this instance.
+
+       Since unregistering this callback from mainloop guarantees a disconnect
+       simply because requests on the fd are no longer processed, it is best
+       that we completely disconnect the connection (which will handle the 
unref)
+       when this callback returns an error... Otherwise since the fd is 
unregistered
+       from the mainloop thread, it may not be possible to detect a disconnect
+       in the future.
+
+2013-06-29  David Vossel  <[email protected]>
 
        Simplify internal ipcs ref counting, add comments and document api 
behavior
 
@@ -9,6 +148,9 @@
 
        Low remove ref-count error in example ipcserver.
 
+       Merge pull request #73 from davidvossel/ref_count_cleanup
+       cleanup connection and service ref counting without changing behavior
+
        Merge pull request #72 from davidvossel/master
        Fixes ref count leak in example ipcserver.c 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/build-aux/release.mk 
new/libqb/build-aux/release.mk
--- old/libqb/build-aux/release.mk      2012-06-07 10:58:53.000000000 +0200
+++ new/libqb/build-aux/release.mk      2013-07-26 03:08:27.000000000 +0200
@@ -1,7 +1,7 @@
 # to build official release tarballs, handle tagging and publish.
 
 # signing key
-gpgsignkey=956EEFB5
+gpgsignkey=C38157D2
 
 project=libqb
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/configure new/libqb/configure
--- old/libqb/configure 2013-07-02 11:28:31.000000000 +0200
+++ new/libqb/configure 2013-07-26 03:09:25.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libqb 0.14.4.53-7c6e.
+# Generated by GNU Autoconf 2.69 for libqb 0.16.0.
 #
 # Report bugs to <[email protected]>.
 #
@@ -590,8 +590,8 @@
 # Identity of this package.
 PACKAGE_NAME='libqb'
 PACKAGE_TARNAME='libqb'
-PACKAGE_VERSION='0.14.4.53-7c6e'
-PACKAGE_STRING='libqb 0.14.4.53-7c6e'
+PACKAGE_VERSION='0.16.0'
+PACKAGE_STRING='libqb 0.16.0'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 
@@ -1374,7 +1374,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libqb 0.14.4.53-7c6e to adapt to many kinds of systems.
+\`configure' configures libqb 0.16.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1444,7 +1444,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libqb 0.14.4.53-7c6e:";;
+     short | recursive ) echo "Configuration of libqb 0.16.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1568,7 +1568,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libqb configure 0.14.4.53-7c6e
+libqb configure 0.16.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2345,7 +2345,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libqb $as_me 0.14.4.53-7c6e, which was
+It was created by libqb $as_me 0.16.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4487,7 +4487,7 @@
 
 # Define the identity of the package.
  PACKAGE='libqb'
- VERSION='0.14.4.53-7c6e'
+ VERSION='0.16.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -19387,7 +19387,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libqb $as_me 0.14.4.53-7c6e, which was
+This file was extended by libqb $as_me 0.16.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19453,7 +19453,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libqb config.status 0.14.4.53-7c6e
+libqb config.status 0.16.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/docs/Makefile.in new/libqb/docs/Makefile.in
--- old/libqb/docs/Makefile.in  2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/docs/Makefile.in  2013-07-25 10:58:37.000000000 +0200
@@ -290,9 +290,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign docs/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign docs/Makefile
+         $(AUTOMAKE) --gnu docs/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/docs/html.dox new/libqb/docs/html.dox
--- old/libqb/docs/html.dox     2013-07-02 11:28:43.000000000 +0200
+++ new/libqb/docs/html.dox     2013-07-26 03:09:56.000000000 +0200
@@ -1,6 +1,6 @@
 DOXYFILE_ENCODING      = UTF-8
 PROJECT_NAME           = libqb
-PROJECT_NUMBER         = 0.14.4.53-7c6e
+PROJECT_NUMBER         = 0.16.0
 OUTPUT_DIRECTORY       = .
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/docs/man.dox new/libqb/docs/man.dox
--- old/libqb/docs/man.dox      2013-07-02 11:28:43.000000000 +0200
+++ new/libqb/docs/man.dox      2013-07-26 03:09:56.000000000 +0200
@@ -1,6 +1,6 @@
 DOXYFILE_ENCODING      = UTF-8
 PROJECT_NAME           = libqb
-PROJECT_NUMBER         = 0.14.4.53-7c6e
+PROJECT_NUMBER         = 0.16.0
 OUTPUT_DIRECTORY       = .
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/examples/Makefile.in 
new/libqb/examples/Makefile.in
--- old/libqb/examples/Makefile.in      2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/examples/Makefile.in      2013-07-25 10:58:37.000000000 +0200
@@ -325,9 +325,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign examples/Makefile
+         $(AUTOMAKE) --gnu examples/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/examples/ipcclient.c 
new/libqb/examples/ipcclient.c
--- old/libqb/examples/ipcclient.c      2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/examples/ipcclient.c      2013-07-25 08:36:33.000000000 +0200
@@ -53,7 +53,7 @@
 _benchmark(qb_ipcc_connection_t *conn, int write_size)
 {
        struct iovec iov[2];
-       unsigned int res;
+       ssize_t res;
        struct qb_ipc_request_header hdr;
        int write_count = 0;
        float secs;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/examples/ipcserver.c 
new/libqb/examples/ipcserver.c
--- old/libqb/examples/ipcserver.c      2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/examples/ipcserver.c      2013-07-25 08:36:33.000000000 +0200
@@ -181,8 +181,9 @@
 #ifdef HAVE_GLIB
 struct gio_to_qb_poll {
        gboolean is_used;
-       GIOChannel *channel;
        int32_t events;
+       int32_t source;
+       int32_t fd;
        void *data;
        qb_ipcs_dispatch_fn_t fn;
        enum qb_loop_priority p;
@@ -197,6 +198,16 @@
        return (adaptor->fn(fd, condition, adaptor->data) == 0);
 }
 
+static void
+gio_poll_destroy(gpointer data)
+{
+       struct gio_to_qb_poll *adaptor = (struct gio_to_qb_poll *)data;
+
+       qb_log(LOG_DEBUG, "fd %d adaptor destroyed\n", adaptor->fd);
+       adaptor->is_used = QB_FALSE;
+       adaptor->fd = 0;
+}
+
 static int32_t
 my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
                  void *data, qb_ipcs_dispatch_fn_t fn)
@@ -218,14 +229,19 @@
                return -ENOMEM;
        }
 
-       adaptor->channel = channel;
        adaptor->fn = fn;
        adaptor->events = evts;
        adaptor->data = data;
        adaptor->p = p;
        adaptor->is_used = TRUE;
+       adaptor->fd = fd;
+
+       adaptor->source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, 
evts, gio_read_socket, adaptor, gio_poll_destroy);
+
+       /* we are handing the channel off to be managed by mainloop now.
+        * remove our reference. */
+       g_io_channel_unref(channel);
 
-       g_io_add_watch(channel, evts, gio_read_socket, adaptor);
        return 0;
 }
 
@@ -241,7 +257,7 @@
 {
        struct gio_to_qb_poll *adaptor;
        if (qb_array_index(gio_map, fd, (void **)&adaptor) == 0) {
-               g_io_channel_unref(adaptor->channel);
+               g_source_remove(adaptor->source);
                adaptor->is_used = FALSE;
        }
        return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/examples/tcpserver.c 
new/libqb/examples/tcpserver.c
--- old/libqb/examples/tcpserver.c      2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/examples/tcpserver.c      2013-07-25 08:36:33.000000000 +0200
@@ -66,7 +66,10 @@
        } else {
                printf("Recieved: %s\n", recv_data);
                snprintf(send_data, 1024, "ACK %d bytes", bytes_recieved);
-               send(fd, send_data, strlen(send_data), 0);
+               if (send(fd, send_data, strlen(send_data), 0) < 0) {
+                       close(fd);
+                       return QB_FALSE;
+               }
        }
        return QB_TRUE;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/include/Makefile.in 
new/libqb/include/Makefile.in
--- old/libqb/include/Makefile.in       2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/include/Makefile.in       2013-07-25 10:58:37.000000000 +0200
@@ -289,9 +289,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign include/Makefile
+         $(AUTOMAKE) --gnu include/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/include/qb/Makefile.in 
new/libqb/include/qb/Makefile.in
--- old/libqb/include/qb/Makefile.in    2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/include/qb/Makefile.in    2013-07-25 10:58:37.000000000 +0200
@@ -282,9 +282,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qb/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/qb/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign include/qb/Makefile
+         $(AUTOMAKE) --gnu include/qb/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/include/qb/qbipcc.h 
new/libqb/include/qb/qbipcc.h
--- old/libqb/include/qb/qbipcc.h       2012-06-07 10:58:53.000000000 +0200
+++ new/libqb/include/qb/qbipcc.h       2013-07-25 08:36:33.000000000 +0200
@@ -70,11 +70,34 @@
  * @param name name of the service.
  * @param max_msg_size biggest msg size.
  * @return NULL (error: see errno) or a connection object.
+ *
+ * @note It is recommended to do a one time check on the
+ * max_msg_size value using qb_ipcc_verify_dgram_max_msg_size
+ * _BEFORE_ calling the connect function when IPC_SOCKET is in use.
+ * Some distributions while allow large message buffers to be
+ * set on the socket, but not actually honor them because of
+ * kernel state values.  The qb_ipcc_verify_dgram_max_msg_size
+ * function both sets the socket buffer size and verifies it by
+ * doing a send/recv.
  */
 qb_ipcc_connection_t*
 qb_ipcc_connect(const char *name, size_t max_msg_size);
 
 /**
+ * Test kernel dgram socket buffers to verify the largest size up
+ * to the max_msg_size value a single msg can be. Rounds down to the
+ * nearest 1k.
+ *
+ * @param max_msg_size biggest msg size.
+ * @return -1 if max size can not be detected, positive value
+ *         representing the largest single msg up to max_msg_size
+ *         that can successfully be sent over a unix dgram socket.
+ */
+int32_t
+qb_ipcc_verify_dgram_max_msg_size(size_t max_msg_size);
+
+
+/**
  * Disconnect an IPC connection.
  *
  * @param c connection instance
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/include/qb/qbipcs.h 
new/libqb/include/qb/qbipcs.h
--- old/libqb/include/qb/qbipcs.h       2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/include/qb/qbipcs.h       2013-07-22 08:51:47.000000000 +0200
@@ -388,7 +388,7 @@
 /**
  * Get the first connection.
  *
- * @note call qb_ipcs_connection_ref_dec() after using the connection.
+ * @note call qb_ipcs_connection_unref() after using the connection.
  *
  * @param pt service instance
  * @return first connection
@@ -398,7 +398,7 @@
 /**
  * Get the next connection.
  *
- * @note call qb_ipcs_connection_ref_dec() after using the connection.
+ * @note call qb_ipcs_connection_unref() after using the connection.
  *
  * @param pt service instance
  * @param current current connection
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/Makefile.am new/libqb/lib/Makefile.am
--- old/libqb/lib/Makefile.am   2013-06-08 07:44:23.000000000 +0200
+++ new/libqb/lib/Makefile.am   2013-07-26 03:08:27.000000000 +0200
@@ -29,38 +29,7 @@
 
 lib_LTLIBRARIES                = libqb.la
 
-# From: http://sourceware.org/autobook/autobook/autobook_91.html
-# (for my own sanity).
-#
-# 1) If you have changed any of the sources for this library, the revision
-#    number must be incremented. This is a new revision of the current
-#    interface.
-#
-# 2) If the interface has changed, then current must be incremented, and
-#    revision reset to `0'. This is the first revision of a new interface.
-#
-# 3) If the new interface is a superset of the previous interface
-#    (that is, if the previous interface has not been broken by the changes
-#    in this new release), then age must be incremented. This release is
-#    backwards compatible with the previous release.
-#
-# 4) If the new interface has removed elements with respect to the previous
-#    interface, then you have broken backward compatibility and age must be
-#    reset to `0'. This release has a new, but backwards incompatible
-#    interface. For example, if the next release of the library included
-#    some new commands for an existing socket protocol, you would use
-#    -version-info 1:0:1. This is the first revision of a new interface.
-#    This release is backwards compatible with the previous release.
-#    Later, you implement a faster way of handling part of the algorithm
-#    at the core of the library, and release it with -version-info 1:1:1.
-#    This is a new revision of the current interface.
-#    Unfortunately the speed of your new implementation can only be fully
-#    exploited by changing the API to access the structures at a lower level,
-#    which breaks compatibility with the previous interface, so you release
-#    it as -version-info 2:0:0. This release has a new, but backwards
-#    incompatible interface.
-#
-libqb_la_LDFLAGS       = -version-info 14:4:14
+libqb_la_LDFLAGS       = -version-number 0:16:0
 
 source_to_lint         = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
                          array.c loop.c loop_poll.c loop_job.c \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/Makefile.in new/libqb/lib/Makefile.in
--- old/libqb/lib/Makefile.in   2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/lib/Makefile.in   2013-07-26 03:09:26.000000000 +0200
@@ -333,39 +333,7 @@
 
 AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
 lib_LTLIBRARIES = libqb.la
-
-# From: http://sourceware.org/autobook/autobook/autobook_91.html
-# (for my own sanity).
-#
-# 1) If you have changed any of the sources for this library, the revision
-#    number must be incremented. This is a new revision of the current
-#    interface.
-#
-# 2) If the interface has changed, then current must be incremented, and
-#    revision reset to `0'. This is the first revision of a new interface.
-#
-# 3) If the new interface is a superset of the previous interface
-#    (that is, if the previous interface has not been broken by the changes
-#    in this new release), then age must be incremented. This release is
-#    backwards compatible with the previous release.
-#
-# 4) If the new interface has removed elements with respect to the previous
-#    interface, then you have broken backward compatibility and age must be
-#    reset to `0'. This release has a new, but backwards incompatible
-#    interface. For example, if the next release of the library included
-#    some new commands for an existing socket protocol, you would use
-#    -version-info 1:0:1. This is the first revision of a new interface.
-#    This release is backwards compatible with the previous release.
-#    Later, you implement a faster way of handling part of the algorithm
-#    at the core of the library, and release it with -version-info 1:1:1.
-#    This is a new revision of the current interface.
-#    Unfortunately the speed of your new implementation can only be fully
-#    exploited by changing the API to access the structures at a lower level,
-#    which breaks compatibility with the previous interface, so you release
-#    it as -version-info 2:0:0. This release has a new, but backwards
-#    incompatible interface.
-#
-libqb_la_LDFLAGS = -version-info 14:4:14
+libqb_la_LDFLAGS = -version-number 0:16:0
 source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
                          array.c loop.c loop_poll.c loop_job.c \
                          loop_timerlist.c ipcc.c ipcs.c ipc_shm.c \
@@ -401,9 +369,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign lib/Makefile
+         $(AUTOMAKE) --gnu lib/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ipc_int.h new/libqb/lib/ipc_int.h
--- old/libqb/lib/ipc_int.h     2013-06-08 07:44:23.000000000 +0200
+++ new/libqb/lib/ipc_int.h     2013-07-25 08:36:33.000000000 +0200
@@ -196,7 +196,6 @@
 int32_t qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt);
 
 int32_t qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void 
*data);
-int32_t qb_ipcs_dispatch_service_request(int32_t fd, int32_t revents, void 
*data);
 struct qb_ipcs_connection* qb_ipcs_connection_alloc(struct qb_ipcs_service *s);
 
 int32_t qb_ipcs_process_request(struct qb_ipcs_service *s,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ipc_setup.c new/libqb/lib/ipc_setup.c
--- old/libqb/lib/ipc_setup.c   2013-03-27 09:16:31.000000000 +0100
+++ new/libqb/lib/ipc_setup.c   2013-07-22 08:51:47.000000000 +0200
@@ -122,7 +122,9 @@
 int32_t
 qb_ipc_us_sock_error_is_disconnected(int err)
 {
-       if (err == -EAGAIN ||
+       if (err >= 0) {
+               return QB_FALSE;
+       } else if (err == -EAGAIN ||
            err == -ETIMEDOUT ||
            err == -EINTR ||
 #ifdef EWOULDBLOCK
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ipc_shm.c new/libqb/lib/ipc_shm.c
--- old/libqb/lib/ipc_shm.c     2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/lib/ipc_shm.c     2013-07-25 08:36:33.000000000 +0200
@@ -229,8 +229,8 @@
                if (c->setup.u.us.sock > 0) {
                        qb_ipcc_us_sock_close(c->setup.u.us.sock);
                        
(void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock);
-                       qb_ipcs_connection_unref(c);
                        c->setup.u.us.sock = -1;
+                       qb_ipcs_connection_unref(c);
                }
        }
        if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN ||
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ipc_socket.c new/libqb/lib/ipc_socket.c
--- old/libqb/lib/ipc_socket.c  2013-03-27 09:16:31.000000000 +0100
+++ new/libqb/lib/ipc_socket.c  2013-07-25 08:36:33.000000000 +0200
@@ -104,10 +104,16 @@
 
        rc = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen);
 
-       qb_util_log(LOG_DEBUG, "%d: getsockopt(%d, needed:%d) actual:%d",
-                   rc, sockfd, max_msg_size, optval);
+       qb_util_log(LOG_TRACE, "%d: getsockopt(%d, needed:%d) actual:%d",
+               rc, sockfd, max_msg_size, optval);
 
-       if (rc == 0 && optval < max_msg_size) {
+       /* The optvat <= max_msg_size check is weird...
+        * during testing it was discovered in some instances if the
+        * default optval is exactly equal to our max_msg_size, we couldn't
+        * actually send a message that large unless we explicilty set
+        * it using setsockopt... there is no good explaination for this. Most
+        * likely this is hitting some sort of "off by one" error in the 
kernel. */
+       if (rc == 0 && optval <= max_msg_size) {
                optval = max_msg_size;
                optlen = sizeof(optval);
                rc = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &optval, optlen);
@@ -115,6 +121,86 @@
        return rc;
 }
 
+static int32_t
+dgram_verify_msg_size(size_t max_msg_size)
+{
+       int32_t rc = -1;
+       int32_t sockets[2];
+       int32_t tries = 0;
+       int32_t write_passed = 0;
+       int32_t read_passed = 0;
+       char buf[max_msg_size];
+
+       if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) {
+               goto cleanup_socks;
+       }
+
+       if (set_sock_size(sockets[0], max_msg_size) != 0) {
+               goto cleanup_socks;
+       }
+       if (set_sock_size(sockets[1], max_msg_size) != 0) {
+               goto cleanup_socks;
+       }
+
+       for (tries = 0; tries < 3; tries++) {
+
+               if (write_passed == 0) {
+                       rc = write(sockets[1], buf, max_msg_size);
+
+                       if (rc < 0 && (errno == EAGAIN || errno == EINTR)) {
+                               continue;
+                       } else if (rc == max_msg_size) {
+                               write_passed = 1;
+                       } else {
+                               break;
+                       }
+               }
+
+               if (read_passed == 0) {
+                       rc = read(sockets[0], buf, max_msg_size);
+
+                       if (rc < 0 && (errno == EAGAIN || errno == EINTR)) {
+                               continue;
+                       } else if (rc == max_msg_size) {
+                               read_passed = 1;
+                       } else {
+                               break;
+                       }
+               }
+
+               if (read_passed && write_passed) {
+                       rc = 0;
+                       break;
+               }
+       }
+
+
+cleanup_socks:
+       close(sockets[0]);
+       close(sockets[1]);
+       return rc;
+}
+
+int32_t
+qb_ipcc_verify_dgram_max_msg_size(size_t max_msg_size)
+{
+       int32_t i;
+       int32_t last = -1;
+
+       if (dgram_verify_msg_size(max_msg_size) == 0) {
+               return max_msg_size;
+       }
+
+       for (i = 1024; i < max_msg_size; i+=1024) {
+               if (dgram_verify_msg_size(i) != 0) {
+                       break;
+               }
+               last = i;
+       }
+
+       return last;
+}
+
 /*
  * bind to "base_name-local_name"
  * connect to "base_name-remote_name"
@@ -219,8 +305,8 @@
        rc = send(one_way->u.us.sock, msg_ptr, msg_len, MSG_NOSIGNAL);
        if (rc == -1) {
                rc = -errno;
-               if (errno != EAGAIN) {
-                       qb_util_perror(LOG_ERR, "socket_send:send");
+               if (errno != EAGAIN && errno != ENOBUFS) {
+                       qb_util_perror(LOG_DEBUG, "socket_send:send");
                }
        }
        qb_sigpipe_ctl(QB_SIGPIPE_DEFAULT);
@@ -254,8 +340,8 @@
 
        if (rc == -1) {
                rc = -errno;
-               if (errno != EAGAIN) {
-                       qb_util_perror(LOG_ERR, "socket_sendv:writev %d",
+               if (errno != EAGAIN && errno != ENOBUFS) {
+                       qb_util_perror(LOG_DEBUG, "socket_sendv:writev %d",
                                       one_way->u.us.sock);
                }
        }
@@ -401,6 +487,7 @@
        c->event.u.us.shared_data =  shm_ptr + (2 * sizeof(struct 
ipc_us_control));
 
        close(fd_hdr);
+       fd_hdr = -1;
 
        res = qb_ipc_dgram_sock_connect(r->response, "response", "request",
                                        r->max_msg_size, &c->request.u.us.sock);
@@ -418,7 +505,9 @@
        return 0;
 
 cleanup_hdr:
-       close(fd_hdr);
+       if (fd_hdr >= 0) {
+               close(fd_hdr);
+       }
        close(c->event.u.us.sock);
        close(c->request.u.us.sock);
        unlink(r->request);
@@ -439,6 +528,7 @@
                    fd, revents, c->description);
        if (revents & POLLNVAL) {
                qb_util_log(LOG_DEBUG, "NVAL conn (%s)", c->description);
+               qb_ipcs_disconnect(c);
                return -EINVAL;
        }
        if (revents & POLLHUP) {
@@ -446,6 +536,28 @@
                qb_ipcs_disconnect(c);
                return -ESHUTDOWN;
        }
+
+       /* If we actually get POLLIN for some reason here, it most
+        * certainly means EOF. Do a recv on the fd to detect eof and
+        * then disconnect */
+       if (revents & POLLIN) {
+               char buf[10];
+               int res;
+
+               res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
+               if (res < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
+                       res = -errno;
+               } else if (res == 0) {
+                       qb_util_log(LOG_DEBUG, "EOF conn (%s)", c->description);
+                       res = -ESHUTDOWN;
+               }
+
+               if (res < 0) {
+                       qb_ipcs_disconnect(c);
+                       return res;
+               }
+       }
+
        return 0;
 }
 
@@ -582,6 +694,7 @@
        ctl->flow_control = 0;
 
        close(fd_hdr);
+       fd_hdr = -1;
 
        /* request channel */
        res = qb_ipc_dgram_sock_setup(r->response, "request",
@@ -617,7 +730,9 @@
        free(c->response.u.us.sock_name);
        free(c->event.u.us.sock_name);
 
-       close(fd_hdr);
+       if (fd_hdr >= 0) {
+               close(fd_hdr);
+       }
        unlink(r->request);
        munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE);
        return res;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ipcc.c new/libqb/lib/ipcc.c
--- old/libqb/lib/ipcc.c        2013-03-27 09:16:31.000000000 +0100
+++ new/libqb/lib/ipcc.c        2013-07-22 08:51:47.000000000 +0200
@@ -110,7 +110,7 @@
                        poll_ms = 0;
                }
                res2 = qb_ipc_us_ready(one_way, &c->setup, poll_ms, events);
-               if (res2 < 0 && qb_ipc_us_sock_error_is_disconnected(res2)) {
+               if (qb_ipc_us_sock_error_is_disconnected(res2)) {
                        errno = -res2;
                        qb_util_perror(LOG_DEBUG,
                                       "%s %d %s",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ipcs.c new/libqb/lib/ipcs.c
--- old/libqb/lib/ipcs.c        2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/lib/ipcs.c        2013-07-25 08:36:33.000000000 +0200
@@ -342,6 +342,10 @@
 {
        ssize_t res = 0;
 
+       if (!c->service->needs_sock_for_poll) {
+               return res;
+       }
+
        if (c->outstanding_notifiers > 0) {
                res = qb_ipc_us_send(&c->setup, c->receive_buf,
                                     c->outstanding_notifiers);
@@ -349,6 +353,7 @@
        if (res > 0) {
                c->outstanding_notifiers -= res;
        }
+
        assert(c->outstanding_notifiers >= 0);
        if (c->outstanding_notifiers == 0) {
                c->poll_events = POLLIN | POLLPRI | POLLNVAL;
@@ -369,6 +374,7 @@
        assert(c->outstanding_notifiers >= 0);
        if (c->outstanding_notifiers > 0) {
                c->outstanding_notifiers++;
+               res = resend_event_notifications(c);
        } else {
                res = qb_ipc_us_send(&c->setup, &c->outstanding_notifiers, 1);
                if (res == -EAGAIN) {
@@ -400,7 +406,7 @@
        if (res == size) {
                c->stats.events++;
                resn = new_event_notification(c);
-               if (resn < 0 && resn != -EAGAIN) {
+               if (resn < 0 && resn != -EAGAIN && resn != -ENOBUFS) {
                        errno = -resn;
                        qb_util_perror(LOG_WARNING,
                                       "new_event_notification (%s)",
@@ -409,6 +415,10 @@
                }
        } else if (res == -EAGAIN || res == -ETIMEDOUT) {
                struct qb_ipc_one_way *ow = _event_sock_one_way_get(c);
+
+               if (c->outstanding_notifiers > 0) {
+                       resn = resend_event_notifications(c);
+               }
                if (ow) {
                        resn = qb_ipc_us_ready(ow, &c->setup, 0, POLLOUT);
                        if (resn < 0) {
@@ -447,6 +457,10 @@
                }
        } else if (res == -EAGAIN || res == -ETIMEDOUT) {
                struct qb_ipc_one_way *ow = _event_sock_one_way_get(c);
+
+               if (c->outstanding_notifiers > 0) {
+                       resn = resend_event_notifications(c);
+               }
                if (ow) {
                        resn = qb_ipc_us_ready(ow, &c->setup, 0, POLLOUT);
                        if (resn < 0) {
@@ -677,9 +691,8 @@
        } else if (size == 0 || hdr->id == QB_IPC_MSG_DISCONNECT) {
                qb_util_log(LOG_DEBUG, "client requesting a disconnect (%s)",
                            c->description);
-               qb_ipcs_disconnect(c);
-               c = NULL;
                res = -ESHUTDOWN;
+               goto cleanup;
        } else {
                c->stats.requests++;
                res = c->service->serv_fns.msg_process(c, hdr, hdr->size);
@@ -703,17 +716,6 @@
 #define IPC_REQUEST_TIMEOUT 10
 #define MAX_RECV_MSGS 50
 
-int32_t
-qb_ipcs_dispatch_service_request(int32_t fd, int32_t revents, void *data)
-{
-       int32_t res = _process_request_((struct qb_ipcs_connection *)data,
-                                       IPC_REQUEST_TIMEOUT);
-       if (res > 0) {
-               return 0;
-       }
-       return res;
-}
-
 static ssize_t
 _request_q_len_get(struct qb_ipcs_connection *c)
 {
@@ -741,22 +743,24 @@
 {
        struct qb_ipcs_connection *c = (struct qb_ipcs_connection *)data;
        char bytes[MAX_RECV_MSGS];
-       int32_t res;
+       int32_t res = 0;
        int32_t res2;
        int32_t recvd = 0;
        ssize_t avail;
 
        if (revents & POLLNVAL) {
                qb_util_log(LOG_DEBUG, "NVAL conn (%s)", c->description);
-               return -EINVAL;
+               res = -EINVAL;
+               goto dispatch_cleanup;
        }
        if (revents & POLLHUP) {
                qb_util_log(LOG_DEBUG, "HUP conn (%s)", c->description);
-               qb_ipcs_disconnect(c);
-               return -ESHUTDOWN;
+               res = -ESHUTDOWN;
+               goto dispatch_cleanup;
        }
 
        if (revents & POLLOUT) {
+               /* try resend events now that fd can write */
                res = resend_event_notifications(c);
                if (res < 0 && res != -EAGAIN) {
                        errno = -res;
@@ -764,12 +768,15 @@
                                       "resend_event_notifications (%s)",
                                       c->description);
                }
+               /* nothing to read */
                if ((revents & POLLIN) == 0) {
-                       return 0;
+                       res = 0;
+                       goto dispatch_cleanup;
                }
        }
        if (c->fc_enabled) {
-               return 0;
+               res = 0;
+               goto dispatch_cleanup;
        }
        avail = _request_q_len_get(c);
 
@@ -779,18 +786,24 @@
                        errno = -res2;
                        qb_util_perror(LOG_WARNING, "conn (%s) disconnected",
                                       c->description);
-                       qb_ipcs_disconnect(c);
-                       return -ESHUTDOWN;
+                       res = -ESHUTDOWN;
+                       goto dispatch_cleanup;
                } else {
                        qb_util_log(LOG_WARNING,
                                    "conn (%s) Nothing in q but got POLLIN on 
fd:%d (res2:%d)",
                                    c->description, fd, res2);
-                       return 0;
+                       res = 0;
+                       goto dispatch_cleanup;
                }
        }
 
        do {
                res = _process_request_(c, IPC_REQUEST_TIMEOUT);
+
+               if (res == -ESHUTDOWN) {
+                       goto dispatch_cleanup;
+               }
+
                if (res > 0 || res == -ENOBUFS || res == -EINVAL) {
                        recvd++;
                }
@@ -801,11 +814,12 @@
 
        if (c->service->needs_sock_for_poll && recvd > 0) {
                res2 = qb_ipc_us_recv(&c->setup, bytes, recvd, -1);
-               if (res2 < 0) {
+               if (qb_ipc_us_sock_error_is_disconnected(res2)) {
                        errno = -res2;
-                       qb_util_perror(LOG_ERR,
-                                      "error receiving from setup sock (%s)",
-                                      c->description);
+                       qb_util_perror(LOG_ERR, "error receiving from setup 
sock (%s)", c->description);
+
+                       res = -ESHUTDOWN;
+                       goto dispatch_cleanup;
                }
        }
 
@@ -822,9 +836,12 @@
                        qb_util_perror(LOG_ERR, "request returned error (%s)",
                                       c->description);
                }
-               qb_ipcs_connection_unref(c);
        }
 
+dispatch_cleanup:
+       if (res != 0) {
+               qb_ipcs_disconnect(c);
+       }
        return res;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/log_thread.c new/libqb/lib/log_thread.c
--- old/libqb/lib/log_thread.c  2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/lib/log_thread.c  2013-07-25 08:36:33.000000000 +0200
@@ -249,7 +249,7 @@
                for (;;) {
                        res = sem_getvalue(&logt_print_finished, &value);
                        if (res != 0 || value == 0) {
-                               return;
+                               break;
                        }
                        sem_wait(&logt_print_finished);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/loop_poll_kqueue.c 
new/libqb/lib/loop_poll_kqueue.c
--- old/libqb/lib/loop_poll_kqueue.c    2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/lib/loop_poll_kqueue.c    2013-07-22 08:51:47.000000000 +0200
@@ -55,7 +55,7 @@
        struct kevent ke;
        short filters = _poll_to_filter_(events);
 
-       EV_SET(&ke, fd, filters, EV_ADD, 0, 0, (intptr_t)pe);
+       EV_SET(&ke, fd, filters, EV_ADD | EV_ENABLE, 0, 0, (intptr_t)pe);
 
        res = kevent(s->epollfd, &ke, 1, NULL, 0, NULL);
        if (res == -1) {
@@ -75,7 +75,7 @@
        short old_filters = _poll_to_filter_(pe->ufd.events);
 
        EV_SET(&ke[0], fd, old_filters, EV_DELETE, 0, 0, (intptr_t)pe);
-       EV_SET(&ke[1], fd, new_filters, EV_ADD, 0, 0, (intptr_t)pe);
+       EV_SET(&ke[1], fd, new_filters, EV_ADD | EV_ENABLE, 0, 0, (intptr_t)pe);
 
        res = kevent(s->epollfd, ke, 2, NULL, 0, NULL);
        if (res == -1) {
@@ -140,11 +140,13 @@
        for (i = 0; i < event_count; i++) {
                revents = 0;
                pe = (struct qb_poll_entry *)events[i].udata;
+#if 0
                if (events[i].flags) {
                        qb_util_log(LOG_TRACE,
                                    "got flags %d on fd %d.", events[i].flags,
                                    pe->ufd.fd);
                }
+#endif
                if (events[i].flags & EV_ERROR) {
                        qb_util_log(LOG_WARNING,
                                    "got EV_ERROR on fd %d.", pe->ufd.fd);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/ringbuffer.c new/libqb/lib/ringbuffer.c
--- old/libqb/lib/ringbuffer.c  2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/lib/ringbuffer.c  2013-07-25 08:36:33.000000000 +0200
@@ -141,7 +141,14 @@
 #ifdef QB_FORCE_SHM_ALIGN
        page_size = QB_MAX(page_size, 16 * 1024);
 #endif /* QB_FORCE_SHM_ALIGN */
+       /* The user of this api expects the 'size' parameter passed into this 
function
+        * to be reflective of the max size single write we can do to the 
+        * ringbuffer.  This means we have to add both the 'margin' space used
+        * to calculate if there is enough space for a new chunk as well as the 
'+1' that
+        * prevents overlap of the read/write pointers */
+       size += QB_RB_CHUNK_MARGIN + 1;
        real_size = QB_ROUNDUP(size, page_size);
+
        shared_size =
            sizeof(struct qb_ringbuffer_shared_s) + shared_user_data_size;
 
@@ -228,6 +235,7 @@
                    "shm size:%zd; real_size:%zd; rb->word_size:%d", size,
                    real_size, rb->shared_hdr->word_size);
 
+       /* this function closes fd_data */
        error = qb_sys_circular_mmap(fd_data, &shm_addr, real_size);
        rb->shared_data = shm_addr;
        if (error != 0) {
@@ -245,11 +253,9 @@
        }
 
        close(fd_hdr);
-       close(fd_data);
        return rb;
 
 cleanup_data:
-       close(fd_data);
        if (flags & QB_RB_FLAG_CREATE) {
                unlink(rb->shared_hdr->data_path);
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/lib/unix.c new/libqb/lib/unix.c
--- old/libqb/lib/unix.c        2013-06-08 07:44:23.000000000 +0200
+++ new/libqb/lib/unix.c        2013-07-25 08:36:33.000000000 +0200
@@ -141,7 +141,7 @@
 
 unlink_exit:
        unlink(path);
-       if (fd > 0) {
+       if (fd >= 0) {
                close(fd);
        }
        return res;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/tests/Makefile.in new/libqb/tests/Makefile.in
--- old/libqb/tests/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/tests/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -543,9 +543,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign tests/Makefile
+         $(AUTOMAKE) --gnu tests/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/tests/bms.c new/libqb/tests/bms.c
--- old/libqb/tests/bms.c       2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/tests/bms.c       2013-07-25 08:36:33.000000000 +0200
@@ -116,6 +116,7 @@
                                sizeof(response));
                if (res < 0) {
                        qb_perror(LOG_ERR, "qb_ipcs_response_send");
+                       return res;
                }
        }
        if (events) {
@@ -123,6 +124,7 @@
                                sizeof(response));
                if (res < 0) {
                        qb_perror(LOG_ERR, "qb_ipcs_event_send");
+                       return res;
                }
        }
        return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/tests/check_ipc.c new/libqb/tests/check_ipc.c
--- old/libqb/tests/check_ipc.c 2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/tests/check_ipc.c 2013-07-25 08:36:33.000000000 +0200
@@ -33,7 +33,21 @@
 #include <qb/qbloop.h>
 
 static const char *ipc_name = "ipc_test";
-#define MAX_MSG_SIZE (8192*16)
+
+#define DEFAULT_MAX_MSG_SIZE (8192*16)
+static int CALCULATED_DGRAM_MAX_MSG_SIZE = 0;
+
+#define DGRAM_MAX_MSG_SIZE \
+       (CALCULATED_DGRAM_MAX_MSG_SIZE == 0 ? \
+       CALCULATED_DGRAM_MAX_MSG_SIZE = 
qb_ipcc_verify_dgram_max_msg_size(DEFAULT_MAX_MSG_SIZE) : \
+       CALCULATED_DGRAM_MAX_MSG_SIZE)
+
+#define MAX_MSG_SIZE (ipc_type == QB_IPC_SOCKET ? DGRAM_MAX_MSG_SIZE : 
DEFAULT_MAX_MSG_SIZE)
+
+/* The size the giant msg's data field needs to be to make
+ * this the largests msg we can successfully send. */
+#define GIANT_MSG_DATA_SIZE MAX_MSG_SIZE - sizeof(struct 
qb_ipc_response_header) - 8
+
 static qb_ipcc_connection_t *conn;
 static enum qb_ipc_type ipc_type;
 
@@ -44,6 +58,8 @@
        IPC_MSG_RES_DISPATCH,
        IPC_MSG_REQ_BULK_EVENTS,
        IPC_MSG_RES_BULK_EVENTS,
+       IPC_MSG_REQ_STRESS_EVENT,
+       IPC_MSG_RES_STRESS_EVENT,
        IPC_MSG_REQ_SERVER_FAIL,
        IPC_MSG_RES_SERVER_FAIL,
        IPC_MSG_REQ_SERVER_DISCONNECT,
@@ -75,6 +91,7 @@
 static int32_t send_event_on_created = QB_FALSE;
 static int32_t disconnect_after_created = QB_FALSE;
 static int32_t num_bulk_events = 10;
+static int32_t num_stress_events = 30000;
 static int32_t reference_count_test = QB_FALSE;
 
 
@@ -91,7 +108,7 @@
                void *data, size_t size)
 {
        struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header 
*)data;
-       struct qb_ipc_response_header response;
+       struct qb_ipc_response_header response = { 0, };
        ssize_t res;
 
        if (req_pt->id == IPC_MSG_REQ_TX_RX) {
@@ -134,9 +151,26 @@
                                         MAX_MSG_SIZE*10);
                ck_assert_int_eq(res, -EMSGSIZE);
 
-               for (m = 0; m < num_bulk_events; m++) {
-                       res = qb_ipcs_event_send(c, &response,
-                                                sizeof(response));
+               /* send one event before responding */
+               res = qb_ipcs_event_send(c, &response, sizeof(response));
+               ck_assert_int_eq(res, sizeof(response));
+               response.id++;
+
+               /* send response */
+               response.id = IPC_MSG_RES_BULK_EVENTS;
+               res = qb_ipcs_response_send(c, &response, response.size);
+               ck_assert_int_eq(res, sizeof(response));
+
+               /* send the rest of the events after the response */
+               for (m = 1; m < num_bulk_events; m++) {
+                       res = qb_ipcs_event_send(c, &response, 
sizeof(response));
+
+                       if (res == -EAGAIN || res == -ENOBUFS) {
+                               /* retry */
+                               usleep(1000);
+                               m--;
+                               continue;
+                       }
                        ck_assert_int_eq(res, sizeof(response));
                        response.id++;
                }
@@ -144,10 +178,49 @@
                ck_assert_int_eq(stats->event_q_length - num, num_bulk_events);
                free(stats);
 
-               response.id = IPC_MSG_RES_BULK_EVENTS;
+       } else if (req_pt->id == IPC_MSG_REQ_STRESS_EVENT) {
+               struct {
+                       struct qb_ipc_response_header hdr __attribute__ 
((aligned(8)));
+                       char data[GIANT_MSG_DATA_SIZE] __attribute__ 
((aligned(8)));
+                       uint32_t sent_msgs __attribute__ ((aligned(8)));
+               } __attribute__ ((aligned(8))) giant_event_send;
+               int32_t m;
+
+               response.size = sizeof(struct qb_ipc_response_header);
+               response.error = 0;
+
+               response.id = IPC_MSG_RES_STRESS_EVENT;
                res = qb_ipcs_response_send(c, &response, response.size);
                ck_assert_int_eq(res, sizeof(response));
 
+               giant_event_send.hdr.error = 0;
+               giant_event_send.hdr.id = IPC_MSG_RES_STRESS_EVENT;
+               for (m = 0; m < num_stress_events; m++) {
+                       size_t sent_len = sizeof(struct qb_ipc_response_header);
+
+                       if (((m+1) % 1000) == 0) {
+                               sent_len = sizeof(giant_event_send);
+                               giant_event_send.sent_msgs = m + 1;
+                       }
+                       giant_event_send.hdr.size = sent_len;
+
+                       res = qb_ipcs_event_send(c, &giant_event_send, 
sent_len);
+                       if (res < 0) {
+                               if (res == -EAGAIN || res == -ENOBUFS) {
+                                       /* yield to the receive process */
+                                       usleep(1000);
+                                       m--;
+                                       continue;
+                               } else {
+                                       qb_perror(LOG_DEBUG, "sending stress 
events");
+                                       ck_assert_int_eq(res, sent_len);
+                               }
+                       } else if (((m+1) % 1000) == 0) {
+                               qb_log(LOG_DEBUG, "SENT: %d stress events 
sent", m+1);
+                       }
+                       giant_event_send.hdr.id++;
+               }
+
        } else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) {
                exit(0);
        } else if (req_pt->id == IPC_MSG_REQ_SERVER_DISCONNECT) {
@@ -635,6 +708,45 @@
 
 static int32_t events_received;
 
+static int32_t
+count_stress_events(int32_t fd, int32_t revents, void *data)
+{
+       struct {
+               struct qb_ipc_response_header hdr __attribute__ ((aligned(8)));
+               char data[GIANT_MSG_DATA_SIZE] __attribute__ ((aligned(8)));
+               uint32_t sent_msgs __attribute__ ((aligned(8)));
+       } __attribute__ ((aligned(8))) giant_event_recv;
+       qb_loop_t *cl = (qb_loop_t*)data;
+       int32_t res;
+
+       res = qb_ipcc_event_recv(conn, &giant_event_recv,
+                                sizeof(giant_event_recv),
+                                -1);
+       if (res > 0) {
+               events_received++;
+
+               if ((events_received % 1000) == 0) {
+                       qb_log(LOG_DEBUG, "RECV: %d stress events processed", 
events_received);
+                       if (res != sizeof(giant_event_recv)) {
+                               qb_log(LOG_DEBUG, "Unexpected recv size, 
expected %d got %d",
+                                       res, sizeof(giant_event_recv));
+                       } else if (giant_event_recv.sent_msgs != 
events_received) {
+                               qb_log(LOG_DEBUG, "Server event mismatch. 
Server thinks we got %d msgs, but we only received %d",
+                                       giant_event_recv.sent_msgs, 
events_received);
+                       }
+               }
+       } else if (res != -EAGAIN) {
+               qb_perror(LOG_DEBUG, "count_stress_events");
+               qb_loop_stop(cl);
+               return -1;
+       }
+
+       if (events_received >= num_stress_events) {
+               qb_loop_stop(cl);
+               return -1;
+       }
+       return 0;
+}
 
 static int32_t
 count_bulk_events(int32_t fd, int32_t revents, void *data)
@@ -719,6 +831,78 @@
        stop_process(pid);
 }
 
+static void
+test_ipc_stress_test(void)
+{
+       struct qb_ipc_request_header req_header;
+       struct qb_ipc_response_header res_header;
+       struct iovec iov[1];
+       int32_t c = 0;
+       int32_t j = 0;
+       pid_t pid;
+       int32_t res;
+       qb_loop_t *cl;
+       int32_t fd;
+
+       pid = run_function_in_new_process(run_ipc_server);
+       fail_if(pid == -1);
+       sleep(1);
+
+       do {
+               conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE);
+               if (conn == NULL) {
+                       j = waitpid(pid, NULL, WNOHANG);
+                       ck_assert_int_eq(j, 0);
+                       sleep(1);
+                       c++;
+               }
+       } while (conn == NULL && c < 5);
+       fail_if(conn == NULL);
+
+       qb_log(LOG_DEBUG, "Testing %d iterations of EVENT msg passing.", 
num_stress_events);
+
+       events_received = 0;
+       cl = qb_loop_create();
+       res = qb_ipcc_fd_get(conn, &fd);
+       ck_assert_int_eq(res, 0);
+       res = qb_loop_poll_add(cl, QB_LOOP_MED,
+                        fd, POLLIN,
+                        cl, count_stress_events);
+       ck_assert_int_eq(res, 0);
+
+       res = send_and_check(IPC_MSG_REQ_STRESS_EVENT, 0, recv_timeout, 
QB_TRUE);
+
+       qb_loop_run(cl);
+       ck_assert_int_eq(events_received, num_stress_events);
+
+       req_header.id = IPC_MSG_REQ_SERVER_FAIL;
+       req_header.size = sizeof(struct qb_ipc_request_header);
+
+       iov[0].iov_len = req_header.size;
+       iov[0].iov_base = &req_header;
+       res = qb_ipcc_sendv_recv(conn, iov, 1,
+                                &res_header,
+                                sizeof(struct qb_ipc_response_header), -1);
+       if (res != -ECONNRESET && res != -ENOTCONN) {
+               qb_log(LOG_ERR, "id:%d size:%d", res_header.id, 
res_header.size);
+               ck_assert_int_eq(res, -ENOTCONN);
+       }
+
+       qb_ipcc_disconnect(conn);
+       stop_process(pid);
+}
+
+START_TEST(test_ipc_stress_test_us)
+{
+       qb_enter();
+       send_event_on_created = QB_FALSE;
+       ipc_type = QB_IPC_SOCKET;
+       ipc_name = __func__;
+       test_ipc_stress_test();
+       qb_leave();
+}
+END_TEST
+
 START_TEST(test_ipc_bulk_events_us)
 {
        qb_enter();
@@ -918,6 +1102,17 @@
 }
 END_TEST
 
+START_TEST(test_ipc_stress_test_shm)
+{
+       qb_enter();
+       send_event_on_created = QB_FALSE;
+       ipc_type = QB_IPC_SHM;
+       ipc_name = __func__;
+       test_ipc_stress_test();
+       qb_leave();
+}
+END_TEST
+
 START_TEST(test_ipc_bulk_events_shm)
 {
        qb_enter();
@@ -1000,6 +1195,37 @@
 }
 END_TEST
 
+static void test_max_dgram_size(void)
+{
+       /* most implementations will not let you set a dgram buffer 
+        * of 1 million bytes. This test verifies that the we can detect
+        * the max dgram buffersize regardless, and that the value we detect
+        * is consistent. */
+       int32_t init;
+       int32_t i;
+
+       qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
+                         QB_LOG_FILTER_FILE, "*", LOG_TRACE);
+
+       init = qb_ipcc_verify_dgram_max_msg_size(1000000);
+       fail_if(init <= 0);
+       for (i = 0; i < 100; i++) {
+               int try = qb_ipcc_verify_dgram_max_msg_size(1000000);
+               ck_assert_int_eq(init, try);
+       }
+
+       qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+                         QB_LOG_FILTER_FILE, "*", LOG_TRACE);
+}
+
+START_TEST(test_ipc_max_dgram_size)
+{
+       qb_enter();
+       test_max_dgram_size();
+       qb_leave();
+}
+END_TEST
+
 static Suite *
 make_shm_suite(void)
 {
@@ -1031,6 +1257,11 @@
        tcase_set_timeout(tc, 16);
        suite_add_tcase(s, tc);
 
+       tc = tcase_create("ipc_stress_test_shm");
+       tcase_add_test(tc, test_ipc_stress_test_shm);
+       tcase_set_timeout(tc, 16);
+       suite_add_tcase(s, tc);
+
        tc = tcase_create("ipc_bulk_events_shm");
        tcase_add_test(tc, test_ipc_bulk_events_shm);
        tcase_set_timeout(tc, 16);
@@ -1059,6 +1290,11 @@
        Suite *s = suite_create("socket");
        TCase *tc;
 
+       tc = tcase_create("ipc_max_dgram_size");
+       tcase_add_test(tc, test_ipc_max_dgram_size);
+       tcase_set_timeout(tc, 30);
+       suite_add_tcase(s, tc);
+
        tc = tcase_create("ipc_server_fail_soc");
        tcase_add_test(tc, test_ipc_server_fail_soc);
        tcase_set_timeout(tc, 6);
@@ -1089,6 +1325,11 @@
        tcase_set_timeout(tc, 16);
        suite_add_tcase(s, tc);
 
+       tc = tcase_create("ipc_stress_test_us");
+       tcase_add_test(tc, test_ipc_stress_test_us);
+       tcase_set_timeout(tc, 60);
+       suite_add_tcase(s, tc);
+
        tc = tcase_create("ipc_bulk_events_us");
        tcase_add_test(tc, test_ipc_bulk_events_us);
        tcase_set_timeout(tc, 16);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqb/tools/Makefile.in new/libqb/tools/Makefile.in
--- old/libqb/tools/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/tools/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -282,9 +282,9 @@
              exit 1;; \
          esac; \
        done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
        $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --foreign tools/Makefile
+         $(AUTOMAKE) --gnu tools/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
        @case '$?' in \

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to