mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-03-06 15:41:36 +01:00
MEDIUM: sock_raw: introduce a read0 callback that is different from shutr
This one is supposed to be called by the lower layer upon receiving a shutr notification, which is different from the call performed by the upper layer. Specifically, this function will ultimately not call EV_FD_* but will just manipulate event flags instead. The function also does not call shutw anymore and instead performs the necessary work. Splitting it into si-specific part and data-specific parts will not be easy.
This commit is contained in:
parent
8b117082bc
commit
3d8903fae0
@ -48,6 +48,7 @@ static int sock_raw_write(struct connection *conn);
|
||||
static void sock_raw_data_finish(struct stream_interface *si);
|
||||
static void sock_raw_shutr(struct stream_interface *si);
|
||||
static void sock_raw_shutw(struct stream_interface *si);
|
||||
static void sock_raw_read0(struct stream_interface *si);
|
||||
static void sock_raw_chk_rcv(struct stream_interface *si);
|
||||
static void sock_raw_chk_snd(struct stream_interface *si);
|
||||
|
||||
@ -456,7 +457,7 @@ static int sock_raw_read(struct connection *conn)
|
||||
b->flags |= BF_READ_NULL;
|
||||
if (b->flags & BF_AUTO_CLOSE)
|
||||
buffer_shutw_now(b);
|
||||
sock_raw_shutr(si);
|
||||
sock_raw_read0(si);
|
||||
goto out_wakeup;
|
||||
|
||||
out_error:
|
||||
@ -766,6 +767,55 @@ static void sock_raw_shutr(struct stream_interface *si)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function propagates a null read received on a connection. It updates
|
||||
* the stream interface. If the stream interface has SI_FL_NOHALF, we also
|
||||
* forward the close to the write side.
|
||||
*/
|
||||
static void sock_raw_read0(struct stream_interface *si)
|
||||
{
|
||||
si->ib->flags &= ~BF_SHUTR_NOW;
|
||||
if (si->ib->flags & BF_SHUTR)
|
||||
return;
|
||||
si->ib->flags |= BF_SHUTR;
|
||||
si->ib->rex = TICK_ETERNITY;
|
||||
si->flags &= ~SI_FL_WAIT_ROOM;
|
||||
|
||||
if (si->state != SI_ST_EST && si->state != SI_ST_CON)
|
||||
return;
|
||||
|
||||
if (si->ob->flags & BF_SHUTW)
|
||||
goto do_close;
|
||||
|
||||
if (si->flags & SI_FL_NOHALF) {
|
||||
/* we have to shut before closing, otherwise some short messages
|
||||
* may never leave the system, especially when there are remaining
|
||||
* unread data in the socket input buffer, or when nolinger is set.
|
||||
* However, if SI_FL_NOLINGER is explicitly set, we know there is
|
||||
* no risk so we close both sides immediately.
|
||||
*/
|
||||
if (si->flags & SI_FL_NOLINGER) {
|
||||
si->flags &= ~SI_FL_NOLINGER;
|
||||
setsockopt(si_fd(si), SOL_SOCKET, SO_LINGER,
|
||||
(struct linger *) &nolinger, sizeof(struct linger));
|
||||
}
|
||||
goto do_close;
|
||||
}
|
||||
|
||||
/* otherwise that's just a normal read shutdown */
|
||||
EV_FD_CLR(si_fd(si), DIR_RD);
|
||||
return;
|
||||
|
||||
do_close:
|
||||
conn_data_close(&si->conn);
|
||||
fd_delete(si_fd(si));
|
||||
si->state = SI_ST_DIS;
|
||||
si->exp = TICK_ETERNITY;
|
||||
if (si->release)
|
||||
si->release(si);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates a connected sock_raw file descriptor status and timeouts
|
||||
* according to the buffers' flags. It should only be called once after the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user