]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/tsocket: add tstream_bsd_fail_readv_first_error()
authorStefan Metzmacher <metze@samba.org>
Thu, 12 Jan 2023 09:08:56 +0000 (10:08 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 24 Oct 2023 09:36:37 +0000 (09:36 +0000)
This gives the caller the option to fail immediately if
TEVENT_FD_ERROR appear even with pending bytes in the
recv queue.

Servers typically want to activate this in order to avoid
pointless work, while clients typically want to read
pending responses from the recv queue.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/tsocket/tsocket.h
lib/tsocket/tsocket_bsd.c

index 22eb758bccde072c5cccdd5c38d62fce637858f9..07e10c84a8a91c77aa43db273da67b98095d630b 100644 (file)
@@ -844,6 +844,28 @@ int _tdgram_unix_socket(const struct tsocket_address *local,
 bool tstream_bsd_optimize_readv(struct tstream_context *stream,
                                bool on);
 
+/**
+ * @brief Request that tstream_readv_send() fails within pending data
+ *
+ * By default we allow pending data to be drained from the
+ * recv queue, before we report EPIPE when reaching EOF.
+ *
+ * For server applications it's typically useful to
+ * fail early in order to avoid useless work,
+ * as the response can't be transferred to the client anyway.
+ *
+ * @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 early fail on and off.
+ *
+ * @return              The old boolean value.
+ *
+ * @see tstream_readv_send()
+ */
+bool tstream_bsd_fail_readv_first_error(struct tstream_context *stream,
+                                       bool on);
+
 /**
  * @brief Connect async to a TCP endpoint and create a tstream_context for the
  * stream based communication.
index 2b53d0d79cf8dbea203c1f785c427d6e5d1314de..4483b03b19f21d9a5137c046c6abf01d5161ba96 100644 (file)
@@ -1650,6 +1650,7 @@ struct tstream_bsd {
        void *event_ptr;
        struct tevent_fd *fde;
        bool optimize_readv;
+       bool fail_readv_first_error;
 
        void *readable_private;
        void (*readable_handler)(void *private_data);
@@ -1676,6 +1677,25 @@ bool tstream_bsd_optimize_readv(struct tstream_context *stream,
        return old;
 }
 
+bool tstream_bsd_fail_readv_first_error(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->fail_readv_first_error;
+       bsds->fail_readv_first_error = on;
+
+       return old;
+}
+
 static void tstream_bsd_fde_handler(struct tevent_context *ev,
                                    struct tevent_fd *fde,
                                    uint16_t flags,
@@ -1692,10 +1712,11 @@ static void tstream_bsd_fde_handler(struct tevent_context *ev,
                 * So we have to check TEVENT_FD_READ
                 * as well as bsds->readable_handler
                 *
-                * We drain remaining data from the
-                * recv queue if available.
+                * We only drain remaining data from the
+                * the recv queue if available and desired.
                 */
                if ((flags & TEVENT_FD_READ) &&
+                   !bsds->fail_readv_first_error &&
                    (bsds->readable_handler != NULL))
                {
                        /*