]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make watching/unwatching sockets saner.
authorWitold Kręcicki <wpk@isc.org>
Thu, 4 Oct 2018 14:52:54 +0000 (14:52 +0000)
committerWitold Kręcicki <wpk@isc.org>
Tue, 6 Nov 2018 11:25:09 +0000 (11:25 +0000)
lib/isc/unix/socket.c

index 2fb55d49e6e5d3a06c40f03500ad44d17e2f98db..38a057b708d1bb61eb63c7e55b7f6682f3bfadcb 100644 (file)
@@ -2894,6 +2894,7 @@ internal_accept(isc__socket_t *sock) {
         */
        dev = ISC_LIST_HEAD(sock->accept_list);
        if (dev == NULL) {
+               unwatch_fd(thread, sock->fd, SELECT_POKE_ACCEPT);
                UNLOCK(&sock->lock);
                return;
        }
@@ -3019,9 +3020,9 @@ internal_accept(isc__socket_t *sock) {
        /*
         * Poke watcher if there are more pending accepts.
         */
-       if (!ISC_LIST_EMPTY(sock->accept_list))
-               watch_fd(thread, sock->fd,
-                        SELECT_POKE_ACCEPT);
+       if (ISC_LIST_EMPTY(sock->accept_list))
+               unwatch_fd(thread, sock->fd,
+                          SELECT_POKE_ACCEPT);
 
        UNLOCK(&sock->lock);
 
@@ -3125,7 +3126,7 @@ internal_recv(isc__socket_t *sock) {
        LOCK(&sock->lock);
        dev = ISC_LIST_HEAD(sock->recv_list);
        if (dev == NULL) {
-               UNLOCK(&sock->lock);
+               goto finish;
                return;
        }
 
@@ -3140,7 +3141,7 @@ internal_recv(isc__socket_t *sock) {
        while (dev != NULL) {
                switch (doio_recv(sock, dev)) {
                case DOIO_SOFT:
-                       goto poke;
+                       goto finish;
 
                case DOIO_EOF:
                        /*
@@ -3153,7 +3154,7 @@ internal_recv(isc__socket_t *sock) {
                                send_recvdone_event(sock, &dev);
                                dev = ISC_LIST_HEAD(sock->recv_list);
                        } while (dev != NULL);
-                       goto poke;
+                       goto finish;
 
                case DOIO_SUCCESS:
                case DOIO_HARD:
@@ -3164,11 +3165,10 @@ internal_recv(isc__socket_t *sock) {
                dev = ISC_LIST_HEAD(sock->recv_list);
        }
 
- poke:
-       if (!ISC_LIST_EMPTY(sock->recv_list))
-               watch_fd(&sock->manager->threads[sock->threadid], sock->fd,
-                        SELECT_POKE_READ);
-
+ finish:
+       if (ISC_LIST_EMPTY(sock->recv_list))
+               unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd,
+                          SELECT_POKE_READ);
        UNLOCK(&sock->lock);
 }
 
@@ -3181,8 +3181,7 @@ internal_send(isc__socket_t *sock) {
        LOCK(&sock->lock);
        dev = ISC_LIST_HEAD(sock->send_list);
        if (dev == NULL) {
-               UNLOCK(&sock->lock);
-               return;
+               goto finish;
        }
        socket_log(sock, NULL, EVENT, NULL, 0, 0,
                   "internal_send:  event %p -> task %p",
@@ -3195,7 +3194,7 @@ internal_send(isc__socket_t *sock) {
        while (dev != NULL) {
                switch (doio_send(sock, dev)) {
                case DOIO_SOFT:
-                       goto poke;
+                       goto finish;
 
                case DOIO_HARD:
                case DOIO_SUCCESS:
@@ -3206,10 +3205,10 @@ internal_send(isc__socket_t *sock) {
                dev = ISC_LIST_HEAD(sock->send_list);
        }
 
poke:
-       if (!ISC_LIST_EMPTY(sock->send_list))
-               watch_fd(&sock->manager->threads[sock->threadid], sock->fd, SELECT_POKE_WRITE);
-
finish:
+       if (ISC_LIST_EMPTY(sock->send_list))
+               unwatch_fd(&sock->manager->threads[sock->threadid],
+                          sock->fd, SELECT_POKE_WRITE);
        UNLOCK(&sock->lock);
 }
 
@@ -3222,7 +3221,6 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
           bool writeable)
 {
        isc__socket_t *sock;
-       bool unwatch_read = false, unwatch_write = false;
        int lockid = FDLOCK_ID(fd);
 
        /*
@@ -3239,9 +3237,8 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
 
        sock = thread->fds[fd];
        if (sock == NULL) {
-               unwatch_read = readable;
-               unwatch_write = writeable;
-               goto unlock_fd;
+               UNLOCK(&thread->fdlock[lockid]);
+               return;
        }
        if (SOCK_DEAD(sock)) { /* Sock is being closed, bail */
                goto unlock_fd;
@@ -3254,7 +3251,6 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
                        internal_accept(sock);
                else
                        internal_recv(sock);
-               unwatch_read = true;
        }
 
        if (writeable) {
@@ -3262,15 +3258,10 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
                        internal_connect(sock);
                else
                        internal_send(sock);
-               unwatch_write = true;
        }
 
  unlock_fd:
        UNLOCK(&thread->fdlock[lockid]);
-       if (unwatch_read)
-               (void)unwatch_fd(thread, fd, SELECT_POKE_READ);
-       if (unwatch_write)
-               (void)unwatch_fd(thread, fd, SELECT_POKE_WRITE);
        if (sock != NULL) {
                if (isc_refcount_decrement(&sock->references) == 1) {
                        destroy(&sock);
@@ -4130,10 +4121,12 @@ socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
                 * Enqueue the request.  If the socket was previously not being
                 * watched, poke the watcher to start paying attention to it.
                 */
-               if (ISC_LIST_EMPTY(sock->recv_list))
+               bool do_poke = ISC_LIST_EMPTY(sock->recv_list);
+               ISC_LIST_ENQUEUE(sock->recv_list, dev, ev_link);
+               if (do_poke) {
                        select_poke(sock->manager, sock->threadid, sock->fd,
                                    SELECT_POKE_READ);
-               ISC_LIST_ENQUEUE(sock->recv_list, dev, ev_link);
+               }
 
                socket_log(sock, NULL, EVENT, NULL, 0, 0,
                           "socket_recv: event %p -> task %p",
@@ -4278,12 +4271,13 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
                         * not being watched, poke the watcher to start
                         * paying attention to it.
                         */
-                       if (ISC_LIST_EMPTY(sock->send_list))
+                       bool do_poke = ISC_LIST_EMPTY(sock->send_list);
+                       ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link);
+                       if (do_poke) {
                                select_poke(sock->manager, sock->threadid,
                                            sock->fd,
                                            SELECT_POKE_WRITE);
-                       ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link);
-
+                       }
                        socket_log(sock, NULL, EVENT, NULL, 0, 0,
                                   "socket_send: event %p -> task %p",
                                   dev, ntask);
@@ -4844,15 +4838,12 @@ isc_socket_accept(isc_socket_t *sock0,
         * is no race condition.  We will keep the lock for such a short
         * bit of time waking it up now or later won't matter all that much.
         */
-       if (ISC_LIST_EMPTY(sock->accept_list))
-               do_poke = true;
-
+       do_poke = ISC_LIST_EMPTY(sock->accept_list);
        ISC_LIST_ENQUEUE(sock->accept_list, dev, ev_link);
-
-       if (do_poke)
+       if (do_poke) {
                select_poke(manager, sock->threadid, sock->fd,
                            SELECT_POKE_ACCEPT);
-
+       }
        UNLOCK(&sock->lock);
        return (ISC_R_SUCCESS);
 }
@@ -5005,13 +4996,13 @@ isc_socket_connect(isc_socket_t *sock0, const isc_sockaddr_t *addr,
         * is no race condition.  We will keep the lock for such a short
         * bit of time waking it up now or later won't matter all that much.
         */
-       if (ISC_LIST_EMPTY(sock->connect_list) && !sock->connecting)
+       bool do_poke = ISC_LIST_EMPTY(sock->connect_list);
+       ISC_LIST_ENQUEUE(sock->connect_list, dev, ev_link);
+       if (do_poke && !sock->connecting) {
+               sock->connecting = 1;
                select_poke(manager, sock->threadid, sock->fd,
                            SELECT_POKE_CONNECT);
-
-       sock->connecting = 1;
-
-       ISC_LIST_ENQUEUE(sock->connect_list, dev, ev_link);
+       }
 
        UNLOCK(&sock->lock);
        return (ISC_R_SUCCESS);
@@ -5040,8 +5031,7 @@ internal_connect(isc__socket_t *sock) {
        dev = ISC_LIST_HEAD(sock->connect_list);
        if (dev == NULL) {
                INSIST(!sock->connecting);
-               UNLOCK(&sock->lock);
-               return;
+               goto finish;
        }
 
        INSIST(sock->connecting);
@@ -5064,10 +5054,7 @@ internal_connect(isc__socket_t *sock) {
                 */
                if (SOFT_ERROR(errno) || errno == EINPROGRESS) {
                        sock->connecting = 1;
-                       watch_fd(&sock->manager->threads[sock->threadid], sock->fd,
-                                SELECT_POKE_CONNECT);
                        UNLOCK(&sock->lock);
-
                        return;
                }
 
@@ -5117,6 +5104,10 @@ internal_connect(isc__socket_t *sock) {
                dev = ISC_LIST_HEAD(sock->connect_list);
        } while (dev != NULL);
 
+ finish:
+       unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd,
+                  SELECT_POKE_CONNECT);
+
        UNLOCK(&sock->lock);
 }
 
@@ -5538,7 +5529,7 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) {
                TRY0(xmlTextWriterStartElement(writer,
                                               ISC_XMLCHAR "references"));
                TRY0(xmlTextWriterWriteFormatString(writer, "%d",
-                                   isc_refcount_current(&sock->references)));
+                                   (int)isc_refcount_current(&sock->references)));
                TRY0(xmlTextWriterEndElement(writer));
 
                TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type",
@@ -5640,7 +5631,7 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats) {
                        json_object_object_add(entry, "name", obj);
                }
 
-               obj = json_object_new_int(isc_refcount_current(&sock->references));
+               obj = json_object_new_int((int)isc_refcount_current(&sock->references));
                CHECKMEM(obj);
                json_object_object_add(entry, "references", obj);