lib/tsocket: disable the syscall optimization for recvfrom/readv by default
authorStefan Metzmacher <metze@samba.org>
Fri, 2 Nov 2012 12:45:49 +0000 (13:45 +0100)
committerVolker Lendecke <vl@samba.org>
Mon, 5 Nov 2012 16:13:39 +0000 (17:13 +0100)
We only do the optimization on recvfrom/readv if the caller asked for it.

This is needed because in most cases we preferr to flush send
buffers before receiving incoming requests.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
lib/tsocket/tsocket.h
lib/tsocket/tsocket_bsd.c

index 3aca536124172c3f58842359dfd09769d75b664e..98f864e6a570c7e4f6261708215563c51e4d8c17 100644 (file)
@@ -627,6 +627,27 @@ int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
 char *tsocket_address_unix_path(const struct tsocket_address *addr,
                                TALLOC_CTX *mem_ctx);
 
+/**
+ * @brief Request a syscall optimization for tdgram_recvfrom_send()
+ *
+ * This function is only used to reduce the amount of syscalls and
+ * optimize performance. You should only use this if you know
+ * what you're doing.
+ *
+ * The optimization is off by default.
+ *
+ * @param[in]  dgram    The tdgram_context of a bsd socket, if this
+ *                      not a bsd socket the function does nothing.
+ *
+ * @param[in]  on       The boolean value to turn the optimization on and off.
+ *
+ * @return              The old boolean value.
+ *
+ * @see tdgram_recvfrom_send()
+ */
+bool tdgram_bsd_optimize_recvfrom(struct tdgram_context *dgram,
+                                 bool on);
+
 #ifdef DOXYGEN
 /**
  * @brief Create a tdgram_context for a ipv4 or ipv6 UDP communication.
@@ -688,6 +709,27 @@ int _tdgram_unix_socket(const struct tsocket_address *local,
        _tdgram_unix_socket(local, remote, mem_ctx, dgram, __location__)
 #endif
 
+/**
+ * @brief Request a syscall optimization for tstream_readv_send()
+ *
+ * This function is only used to reduce the amount of syscalls and
+ * optimize performance. You should only use this if you know
+ * what you're doing.
+ *
+ * The optimization is off by default.
+ *
+ * @param[in]  stream   The tstream_context of a bsd socket, if this
+ *                      not a bsd socket the function does nothing.
+ *
+ * @param[in]  on       The boolean value to turn the optimization on and off.
+ *
+ * @return              The old boolean value.
+ *
+ * @see tstream_readv_send()
+ */
+bool tstream_bsd_optimize_readv(struct tstream_context *stream,
+                               bool on);
+
 /**
  * @brief Connect async to a TCP endpoint and create a tstream_context for the
  * stream based communication.
index 135fd027aa562736aaca2a5601716f0ecf564d77..56dff68dd2f6b21a015ac2729da517d002627abc 100644 (file)
@@ -654,6 +654,7 @@ struct tdgram_bsd {
 
        void *event_ptr;
        struct tevent_fd *fde;
+       bool optimize_recvfrom;
 
        void *readable_private;
        void (*readable_handler)(void *private_data);
@@ -661,6 +662,25 @@ struct tdgram_bsd {
        void (*writeable_handler)(void *private_data);
 };
 
+bool tdgram_bsd_optimize_recvfrom(struct tdgram_context *dgram,
+                                 bool on)
+{
+       struct tdgram_bsd *bsds =
+               talloc_get_type(_tdgram_context_data(dgram),
+               struct tdgram_bsd);
+       bool old;
+
+       if (bsds == NULL) {
+               /* not a bsd socket */
+               return false;
+       }
+
+       old = bsds->optimize_recvfrom;
+       bsds->optimize_recvfrom = on;
+
+       return old;
+}
+
 static void tdgram_bsd_fde_handler(struct tevent_context *ev,
                                   struct tevent_fd *fde,
                                   uint16_t flags,
@@ -838,14 +858,25 @@ 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;
+       if (bsds->optimize_recvfrom) {
+               /*
+                * We only do the optimization on
+                * recvfrom if the caller asked for it.
+                *
+                * This is needed because in most cases
+                * we preferr to flush send buffers before
+                * receiving incoming requests.
+                */
+               tdgram_bsd_recvfrom_handler(req);
+               if (!tevent_req_is_in_progress(req)) {
+                       goto post;
+               }
        }
 
        ret = tdgram_bsd_set_readable_handler(bsds, ev,
@@ -1405,6 +1436,7 @@ struct tstream_bsd {
 
        void *event_ptr;
        struct tevent_fd *fde;
+       bool optimize_readv;
 
        void *readable_private;
        void (*readable_handler)(void *private_data);
@@ -1412,6 +1444,25 @@ struct tstream_bsd {
        void (*writeable_handler)(void *private_data);
 };
 
+bool tstream_bsd_optimize_readv(struct tstream_context *stream,
+                               bool on)
+{
+       struct tstream_bsd *bsds =
+               talloc_get_type(_tstream_context_data(stream),
+               struct tstream_bsd);
+       bool old;
+
+       if (bsds == NULL) {
+               /* not a bsd socket */
+               return false;
+       }
+
+       old = bsds->optimize_readv;
+       bsds->optimize_readv = on;
+
+       return old;
+}
+
 static void tstream_bsd_fde_handler(struct tevent_context *ev,
                                    struct tevent_fd *fde,
                                    uint16_t flags,
@@ -1624,9 +1675,19 @@ static struct tevent_req *tstream_bsd_readv_send(TALLOC_CTX *mem_ctx,
         * socket to become explicit readable gains
         * about 10%-20% performance in benchmark tests.
         */
-       tstream_bsd_readv_handler(req);
-       if (!tevent_req_is_in_progress(req)) {
-               goto post;
+       if (bsds->optimize_readv) {
+               /*
+                * We only do the optimization on
+                * readv if the caller asked for it.
+                *
+                * This is needed because in most cases
+                * we preferr to flush send buffers before
+                * receiving incoming requests.
+                */
+               tstream_bsd_readv_handler(req);
+               if (!tevent_req_is_in_progress(req)) {
+                       goto post;
+               }
        }
 
        ret = tstream_bsd_set_readable_handler(bsds, ev,