1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

lib/tsocket: add tstream_bsd_fail_readv_first_error()

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>
This commit is contained in:
Stefan Metzmacher 2023-01-12 10:08:56 +01:00 committed by Ralph Boehme
parent 5bedf1675e
commit 71e8727bdc
2 changed files with 45 additions and 2 deletions

View 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.

View 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))
{
/*