]> 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>
Thu, 15 Nov 2018 08:21:17 +0000 (08:21 +0000)
lib/isc/unix/socket.c

index 0cc8c3a8c231f9cb6fc3d7d52692a2bd0adc5c26..8fc085b516d294ba4bbf3ed3b584ee18f8c9c6f9 100644 (file)
@@ -2898,6 +2898,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;
        }
@@ -3023,9 +3024,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);
 
@@ -3129,7 +3130,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;
        }
 
@@ -3144,7 +3145,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:
                        /*
@@ -3157,7 +3158,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:
@@ -3168,11 +3169,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);
 }
 
@@ -3185,8 +3185,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",
@@ -3199,7 +3198,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:
@@ -3210,10 +3209,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);
 }
 
@@ -3226,7 +3225,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);
 
        /*
@@ -3243,9 +3241,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;
@@ -3258,7 +3255,6 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
                        internal_accept(sock);
                else
                        internal_recv(sock);
-               unwatch_read = true;
        }
 
        if (writeable) {
@@ -3266,15 +3262,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);
@@ -4134,10 +4125,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",
@@ -4282,12 +4275,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);
@@ -4848,15 +4842,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);
 }
@@ -5009,13 +5000,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);
@@ -5044,8 +5035,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);
@@ -5068,10 +5058,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;
                }
 
@@ -5121,6 +5108,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);
 }
 
@@ -5542,7 +5533,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",
@@ -5644,7 +5635,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);