]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2766. [bug] isc_socket_fdwatchpoke() should only update the
authorEvan Hunt <each@isc.org>
Fri, 13 Nov 2009 00:41:58 +0000 (00:41 +0000)
committerEvan Hunt <each@isc.org>
Fri, 13 Nov 2009 00:41:58 +0000 (00:41 +0000)
socketmgr state if the socket is not pending on a
read or write.  [RT #20603]

CHANGES
lib/isc/unix/socket.c

diff --git a/CHANGES b/CHANGES
index 7b4aa81e0a6d63bddc68b906c8563cfb7bb23201..f07291c85baedb0ea4e45510fc1f00516a31b39c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+2766.  [bug]           isc_socket_fdwatchpoke() should only update the
+                       socketmgr state if the socket is not pending on a
+                       read or write.  [RT #20603]
+
 2765.  [bug]           Skip masters for which the TSIG key cannot be found.
                        [RT #20595]
 
index 663a03ab101d3a4b64d37ed4f7c87f05d76f008b..c3e5430ff15fb14657e396f0007da7e9457ef275 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.325 2009/10/01 01:30:01 sar Exp $ */
+/* $Id: socket.c,v 1.326 2009/11/13 00:41:58 each Exp $ */
 
 /*! \file */
 
@@ -2628,10 +2628,12 @@ isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags,
        return (ISC_R_SUCCESS);
 }
 
-/* Indicate to the manager that it should watch the socket again.
+/*
+ * Indicate to the manager that it should watch the socket again.
  * This can be used to restart watching if the previous event handler
  * didn't indicate there was more data to be processed.  Primarily
- * it is for writing but could be used for reading if desired */
+ * it is for writing but could be used for reading if desired
+ */
 
 ISC_SOCKETFUNC_SCOPE isc_result_t
 isc__socket_fdwatchpoke(isc_socket_t *sock0, int flags)
@@ -2640,10 +2642,23 @@ isc__socket_fdwatchpoke(isc_socket_t *sock0, int flags)
 
        REQUIRE(VALID_SOCKET(sock));
 
-       if (flags & ISC_SOCKFDWATCH_READ)
-               select_poke(sock->manager, sock->fd, SELECT_POKE_READ);
-       if (flags & ISC_SOCKFDWATCH_WRITE)
-               select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE);
+       /*
+        * We check both flags first to allow us to get the lock
+        * once but only if we need it.
+        */
+
+       if ((flags & (ISC_SOCKFDWATCH_READ | ISC_SOCKFDWATCH_WRITE)) != 0) {
+               LOCK(&sock->lock);
+               if (((flags & ISC_SOCKFDWATCH_READ) != 0) &&
+                   !sock->pending_recv)
+                       select_poke(sock->manager, sock->fd,
+                                   SELECT_POKE_READ);
+               if (((flags & ISC_SOCKFDWATCH_WRITE) != 0) &&
+                   !sock->pending_send)
+                       select_poke(sock->manager, sock->fd,
+                                   SELECT_POKE_WRITE);
+               UNLOCK(&sock->lock);
+       }
 
        socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET,
                   ISC_MSG_POKED, "fdwatch-poked flags: %d", flags);