tsocket: use the correct 'ret' variable for tdgram_disconnect_send/recv()
[ira/wip.git] / lib / tsocket / tsocket_bsd.c
index 6c60ef2ebd13928b114479d2961ea0b40a1b2880..6d27ccae22082eef5ce2aa431e863876aa516ab9 100644 (file)
@@ -615,9 +615,6 @@ static int tsocket_address_bsd_create_socket(const struct tsocket_address *addr,
                }
                bsd_type = SOCK_STREAM;
                break;
-       case TSOCKET_TYPE_DGRAM:
-               bsd_type = SOCK_DGRAM;
-               break;
        default:
                errno = EPROTONOSUPPORT;
                return -1;
@@ -944,73 +941,6 @@ static int tsocket_context_bsd_writev_data(struct tsocket_context *sock,
        return ret;
 }
 
-static ssize_t tsocket_context_bsd_recvfrom_data(struct tsocket_context *sock,
-                                                 uint8_t *data, size_t len,
-                                                 TALLOC_CTX *addr_ctx,
-                                                 struct tsocket_address **remote)
-{
-       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
-                                          struct tsocket_context_bsd);
-       struct tsocket_address *addr = NULL;
-       struct tsocket_address_bsd *bsda;
-       ssize_t ret;
-       struct sockaddr *sa = NULL;
-       socklen_t sa_len = 0;
-
-       if (remote) {
-               addr = tsocket_address_create(addr_ctx,
-                                             &tsocket_address_bsd_ops,
-                                             &bsda,
-                                             struct tsocket_address_bsd,
-                                             __location__ "recvfrom");
-               if (!addr) {
-                       return -1;
-               }
-
-               ZERO_STRUCTP(bsda);
-
-               sa = &bsda->u.sa;
-               sa_len = sizeof(bsda->u.ss);
-       }
-
-       ret = recvfrom(bsds->fd, data, len, 0, sa, &sa_len);
-       if (ret < 0) {
-               int saved_errno = errno;
-               talloc_free(addr);
-               errno = saved_errno;
-               return ret;
-       }
-
-       if (remote) {
-               *remote = addr;
-       }
-       return ret;
-}
-
-static ssize_t tsocket_context_bsd_sendto_data(struct tsocket_context *sock,
-                                               const uint8_t *data, size_t len,
-                                               const struct tsocket_address *remote)
-{
-       struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
-                                          struct tsocket_context_bsd);
-       struct sockaddr *sa = NULL;
-       socklen_t sa_len = 0;
-       ssize_t ret;
-
-       if (remote) {
-               struct tsocket_address_bsd *bsda =
-                       talloc_get_type(remote->private_data,
-                       struct tsocket_address_bsd);
-
-               sa = &bsda->u.sa;
-               sa_len = sizeof(bsda->u.ss);
-       }
-
-       ret = sendto(bsds->fd, data, len, 0, sa, sa_len);
-
-       return ret;
-}
-
 static int tsocket_context_bsd_get_status(const struct tsocket_context *sock)
 {
        struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
@@ -1272,8 +1202,6 @@ static const struct tsocket_context_ops tsocket_context_bsd_ops = {
        .pending_data           = tsocket_context_bsd_pending_data,
        .readv_data             = tsocket_context_bsd_readv_data,
        .writev_data            = tsocket_context_bsd_writev_data,
-       .recvfrom_data          = tsocket_context_bsd_recvfrom_data,
-       .sendto_data            = tsocket_context_bsd_sendto_data,
 
        .get_status             = tsocket_context_bsd_get_status,
        .get_local_address      = tsocket_context_bsd_get_local_address,
@@ -1313,6 +1241,10 @@ static void tdgram_bsd_fde_handler(struct tevent_context *ev,
                return;
        }
        if (flags & TEVENT_FD_READ) {
+               if (!bsds->readable_handler) {
+                       TEVENT_FD_NOT_READABLE(bsds->fde);
+                       return;
+               }
                bsds->readable_handler(bsds->readable_private);
                return;
        }
@@ -1328,19 +1260,25 @@ static int tdgram_bsd_set_readable_handler(struct tdgram_bsd *bsds,
                        errno = EINVAL;
                        return -1;
                }
-
+               if (!bsds->readable_handler) {
+                       return 0;
+               }
                bsds->readable_handler = NULL;
                bsds->readable_private = NULL;
-               TEVENT_FD_NOT_READABLE(bsds->fde);
 
-               if (bsds->fde && !bsds->writeable_handler) {
-                       /* we don't need the fd event anymore */
-                       bsds->event_ptr = NULL;
-                       TALLOC_FREE(bsds->fde);
-               }
                return 0;
        }
 
+       /* read and write must use the same tevent_context */
+       if (bsds->event_ptr != ev) {
+               if (bsds->readable_handler || bsds->writeable_handler) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               bsds->event_ptr = NULL;
+               TALLOC_FREE(bsds->fde);
+       }
+
        if (bsds->fde == NULL) {
                bsds->fde = tevent_add_fd(ev, bsds,
                                          bsds->fd, TEVENT_FD_READ,
@@ -1352,15 +1290,10 @@ static int tdgram_bsd_set_readable_handler(struct tdgram_bsd *bsds,
 
                /* cache the event context we're running on */
                bsds->event_ptr = ev;
+       } else if (!bsds->readable_handler) {
+               TEVENT_FD_READABLE(bsds->fde);
        }
 
-       /* read and write must use the same tevent_context */
-       if (bsds->event_ptr != ev) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       TEVENT_FD_READABLE(bsds->fde);
        bsds->readable_handler = handler;
        bsds->readable_private = private_data;
 
@@ -1377,19 +1310,26 @@ static int tdgram_bsd_set_writeable_handler(struct tdgram_bsd *bsds,
                        errno = EINVAL;
                        return -1;
                }
-
+               if (!bsds->writeable_handler) {
+                       return 0;
+               }
                bsds->writeable_handler = NULL;
                bsds->writeable_private = NULL;
                TEVENT_FD_NOT_WRITEABLE(bsds->fde);
 
-               if (bsds->fde && !bsds->readable_handler) {
-                       /* we don't need the fd event anymore */
-                       bsds->event_ptr = NULL;
-                       TALLOC_FREE(bsds->fde);
-               }
                return 0;
        }
 
+       /* read and write must use the same tevent_context */
+       if (bsds->event_ptr != ev) {
+               if (bsds->readable_handler || bsds->writeable_handler) {
+                       errno = EINVAL;
+                       return -1;
+               }
+               bsds->event_ptr = NULL;
+               TALLOC_FREE(bsds->fde);
+       }
+
        if (bsds->fde == NULL) {
                bsds->fde = tevent_add_fd(ev, bsds,
                                          bsds->fd, TEVENT_FD_WRITE,
@@ -1401,15 +1341,10 @@ static int tdgram_bsd_set_writeable_handler(struct tdgram_bsd *bsds,
 
                /* cache the event context we're running on */
                bsds->event_ptr = ev;
+       } else if (!bsds->writeable_handler) {
+               TEVENT_FD_WRITEABLE(bsds->fde);
        }
 
-       /* read and write must use the same tevent_context */
-       if (bsds->event_ptr != ev) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       TEVENT_FD_WRITEABLE(bsds->fde);
        bsds->writeable_handler = handler;
        bsds->writeable_private = private_data;
 
@@ -1470,6 +1405,16 @@ static struct tevent_req *tdgram_bsd_recvfrom_send(TALLOC_CTX *mem_ctx,
                goto post;
        }
 
+       /*
+        * this is a fast path, not waiting for the
+        * socket to become explicit readable gains
+        * about 10%-20% performance in benchmark tests.
+        */
+       tdgram_bsd_recvfrom_handler(req);
+       if (!tevent_req_is_in_progress(req)) {
+               goto post;
+       }
+
        ret = tdgram_bsd_set_readable_handler(bsds, ev,
                                              tdgram_bsd_recvfrom_handler,
                                              req);
@@ -1634,6 +1579,16 @@ static struct tevent_req *tdgram_bsd_sendto_send(TALLOC_CTX *mem_ctx,
                goto post;
        }
 
+       /*
+        * this is a fast path, not waiting for the
+        * socket to become explicit writeable gains
+        * about 10%-20% performance in benchmark tests.
+        */
+       tdgram_bsd_sendto_handler(req);
+       if (!tevent_req_is_in_progress(req)) {
+               goto post;
+       }
+
        ret = tdgram_bsd_set_writeable_handler(bsds, ev,
                                               tdgram_bsd_sendto_handler,
                                               req);
@@ -1703,7 +1658,7 @@ static ssize_t tdgram_bsd_sendto_recv(struct tevent_req *req, int *perrno)
 }
 
 struct tdgram_bsd_disconnect_state {
-       int ret;
+       void *__dummy;
 };
 
 static struct tevent_req *tdgram_bsd_disconnect_send(TALLOC_CTX *mem_ctx,
@@ -1722,7 +1677,6 @@ static struct tevent_req *tdgram_bsd_disconnect_send(TALLOC_CTX *mem_ctx,
        if (req == NULL) {
                return NULL;
        }
-       state->ret = -1;
 
        if (bsds->read_req || bsds->write_req) {
                tevent_req_error(req, EBUSY);
@@ -1734,7 +1688,7 @@ static struct tevent_req *tdgram_bsd_disconnect_send(TALLOC_CTX *mem_ctx,
                goto post;
        }
 
-       state->ret = close(bsds->fd);
+       ret = close(bsds->fd);
        bsds->fd = -1;
        err = tsocket_error_from_errno(ret, errno, &dummy);
        if (tevent_req_error(req, err)) {
@@ -1750,14 +1704,9 @@ post:
 static int tdgram_bsd_disconnect_recv(struct tevent_req *req,
                                      int *perrno)
 {
-       struct tdgram_bsd_disconnect_state *state = tevent_req_data(req,
-                                       struct tdgram_bsd_disconnect_state);
        int ret;
 
        ret = tsocket_simple_int_recv(req, perrno);
-       if (ret == 0) {
-               ret = state->ret;
-       }
 
        tevent_req_received(req);
        return ret;