mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 05:41:26 +02:00
MINOR: stream: Only save previous connection state for the server side
The previous connection state on the client side was only used for debugging purpose to report client close. But this may be handled when the client stream-interface is switched from SI_ST_DIS to SI_ST_CLO. So, there only remains the previous connection state on the server side that is used by the stream, in process_stream(), to be able to set the correct termination flags. Thus, instead of keeping this info in the stream-interface for only one side, the info is now stored in the stream itself.
This commit is contained in:
parent
78ed7f247b
commit
a70a3548bc
@ -143,6 +143,7 @@ struct stream {
|
|||||||
|
|
||||||
int conn_retries; /* number of connect retries performed */
|
int conn_retries; /* number of connect retries performed */
|
||||||
unsigned int conn_exp; /* wake up time for connect, queue, turn-around, ... */
|
unsigned int conn_exp; /* wake up time for connect, queue, turn-around, ... */
|
||||||
|
enum si_state prev_conn_state; /* SI_ST*, copy of previous state of the server conn-stream */
|
||||||
|
|
||||||
struct list list; /* position in the thread's streams list */
|
struct list list; /* position in the thread's streams list */
|
||||||
struct mt_list by_srv; /* position in server stream list */
|
struct mt_list by_srv; /* position in server stream list */
|
||||||
|
@ -112,7 +112,6 @@ enum {
|
|||||||
struct stream_interface {
|
struct stream_interface {
|
||||||
/* struct members used by the "buffer" side */
|
/* struct members used by the "buffer" side */
|
||||||
enum si_state state; /* SI_ST* */
|
enum si_state state; /* SI_ST* */
|
||||||
enum si_state prev_state;/* SI_ST*, copy of previous state */
|
|
||||||
/* 16-bit hole here */
|
/* 16-bit hole here */
|
||||||
unsigned int flags; /* SI_FL_* */
|
unsigned int flags; /* SI_FL_* */
|
||||||
struct conn_stream *cs; /* points to the conn-streams that owns the endpoint (connection or applet) */
|
struct conn_stream *cs; /* points to the conn-streams that owns the endpoint (connection or applet) */
|
||||||
|
@ -109,7 +109,7 @@ static inline int si_init(struct stream_interface *si)
|
|||||||
si->err_type = SI_ET_NONE;
|
si->err_type = SI_ET_NONE;
|
||||||
si->flags &= SI_FL_ISBACK;
|
si->flags &= SI_FL_ISBACK;
|
||||||
si->cs = NULL;
|
si->cs = NULL;
|
||||||
si->state = si->prev_state = SI_ST_INI;
|
si->state = SI_ST_INI;
|
||||||
si->ops = &si_embedded_ops;
|
si->ops = &si_embedded_ops;
|
||||||
si->wait_event.tasklet = tasklet_new();
|
si->wait_event.tasklet = tasklet_new();
|
||||||
if (!si->wait_event.tasklet)
|
if (!si->wait_event.tasklet)
|
||||||
@ -126,7 +126,7 @@ static inline int si_init(struct stream_interface *si)
|
|||||||
*/
|
*/
|
||||||
static inline void si_set_state(struct stream_interface *si, int state)
|
static inline void si_set_state(struct stream_interface *si, int state)
|
||||||
{
|
{
|
||||||
si->state = si->prev_state = state;
|
si->state = si_strm(si)->prev_conn_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns a bit for a stream-int state, to match against SI_SB_* */
|
/* returns a bit for a stream-int state, to match against SI_SB_* */
|
||||||
|
@ -2766,7 +2766,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||||||
|
|
||||||
sockaddr_free(&s->csb->dst);
|
sockaddr_free(&s->csb->dst);
|
||||||
|
|
||||||
cs_si(s->csb)->state = cs_si(s->csb)->prev_state = SI_ST_INI;
|
si_set_state(cs_si(s->csb), SI_ST_INI);
|
||||||
cs_si(s->csb)->err_type = SI_ET_NONE;
|
cs_si(s->csb)->err_type = SI_ET_NONE;
|
||||||
cs_si(s->csb)->flags &= SI_FL_ISBACK; /* we're in the context of process_stream */
|
cs_si(s->csb)->flags &= SI_FL_ISBACK; /* we're in the context of process_stream */
|
||||||
s->csb->flags &= CS_FL_ISBACK | CS_FL_DONT_WAKE; /* we're in the context of process_stream */
|
s->csb->flags &= CS_FL_ISBACK | CS_FL_DONT_WAKE; /* we're in the context of process_stream */
|
||||||
|
61
src/stream.c
61
src/stream.c
@ -422,6 +422,7 @@ struct stream *stream_new(struct session *sess, struct conn_stream *cs, struct b
|
|||||||
s->pending_events = 0;
|
s->pending_events = 0;
|
||||||
s->conn_retries = 0;
|
s->conn_retries = 0;
|
||||||
s->conn_exp = TICK_ETERNITY;
|
s->conn_exp = TICK_ETERNITY;
|
||||||
|
s->prev_conn_state = SI_ST_INI;
|
||||||
t->process = process_stream;
|
t->process = process_stream;
|
||||||
t->context = s;
|
t->context = s;
|
||||||
t->expire = TICK_ETERNITY;
|
t->expire = TICK_ETERNITY;
|
||||||
@ -958,7 +959,7 @@ static void sess_set_term_flags(struct stream *s)
|
|||||||
s->flags |= SF_FINST_Q;
|
s->flags |= SF_FINST_Q;
|
||||||
else if (si_state_in(cs_si(s->csb)->state, SI_SB_REQ|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY))
|
else if (si_state_in(cs_si(s->csb)->state, SI_SB_REQ|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY))
|
||||||
s->flags |= SF_FINST_C;
|
s->flags |= SF_FINST_C;
|
||||||
else if (cs_si(s->csb)->state == SI_ST_EST || cs_si(s->csb)->prev_state == SI_ST_EST)
|
else if (cs_si(s->csb)->state == SI_ST_EST || s->prev_conn_state == SI_ST_EST)
|
||||||
s->flags |= SF_FINST_D;
|
s->flags |= SF_FINST_D;
|
||||||
else
|
else
|
||||||
s->flags |= SF_FINST_L;
|
s->flags |= SF_FINST_L;
|
||||||
@ -1780,9 +1781,23 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
DBG_TRACE_POINT(STRM_EV_STRM_PROC, s);
|
DBG_TRACE_POINT(STRM_EV_STRM_PROC, s);
|
||||||
|
|
||||||
/* nothing special to be done on client side */
|
/* nothing special to be done on client side */
|
||||||
if (unlikely(si_f->state == SI_ST_DIS))
|
if (unlikely(si_f->state == SI_ST_DIS)) {
|
||||||
si_f->state = SI_ST_CLO;
|
si_f->state = SI_ST_CLO;
|
||||||
|
|
||||||
|
/* This is needed only when debugging is enabled, to indicate
|
||||||
|
* client-side close.
|
||||||
|
*/
|
||||||
|
if (unlikely((global.mode & MODE_DEBUG) &&
|
||||||
|
(!(global.mode & MODE_QUIET) ||
|
||||||
|
(global.mode & MODE_VERBOSE)))) {
|
||||||
|
chunk_printf(&trash, "%08x:%s.clicls[%04x:%04x]\n",
|
||||||
|
s->uniq_id, s->be->id,
|
||||||
|
(unsigned short)conn_fd(cs_conn(si_f->cs)),
|
||||||
|
(unsigned short)conn_fd(cs_conn(si_b->cs)));
|
||||||
|
DISGUISE(write(1, trash.area, trash.data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* When a server-side connection is released, we have to count it and
|
/* When a server-side connection is released, we have to count it and
|
||||||
* check for pending connections on this server.
|
* check for pending connections on this server.
|
||||||
*/
|
*/
|
||||||
@ -1798,6 +1813,21 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
if (may_dequeue_tasks(srv, s->be))
|
if (may_dequeue_tasks(srv, s->be))
|
||||||
process_srv_queue(srv);
|
process_srv_queue(srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is needed only when debugging is enabled, to indicate
|
||||||
|
* server-side close.
|
||||||
|
*/
|
||||||
|
if (unlikely((global.mode & MODE_DEBUG) &&
|
||||||
|
(!(global.mode & MODE_QUIET) ||
|
||||||
|
(global.mode & MODE_VERBOSE)))) {
|
||||||
|
if (s->prev_conn_state == SI_ST_EST) {
|
||||||
|
chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
|
||||||
|
s->uniq_id, s->be->id,
|
||||||
|
(unsigned short)conn_fd(__cs_conn(si_f->cs)),
|
||||||
|
(unsigned short)conn_fd(cs_conn(si_b->cs)));
|
||||||
|
DISGUISE(write(1, trash.area, trash.data));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2392,33 +2422,6 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
s->csf->flags &= ~CS_FL_DONT_WAKE;
|
s->csf->flags &= ~CS_FL_DONT_WAKE;
|
||||||
s->csb->flags &= ~CS_FL_DONT_WAKE;
|
s->csb->flags &= ~CS_FL_DONT_WAKE;
|
||||||
|
|
||||||
/* This is needed only when debugging is enabled, to indicate
|
|
||||||
* client-side or server-side close. Please note that in the unlikely
|
|
||||||
* event where both sides would close at once, the sequence is reported
|
|
||||||
* on the server side first.
|
|
||||||
*/
|
|
||||||
if (unlikely((global.mode & MODE_DEBUG) &&
|
|
||||||
(!(global.mode & MODE_QUIET) ||
|
|
||||||
(global.mode & MODE_VERBOSE)))) {
|
|
||||||
if (si_b->state == SI_ST_CLO &&
|
|
||||||
si_b->prev_state == SI_ST_EST) {
|
|
||||||
chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
|
|
||||||
s->uniq_id, s->be->id,
|
|
||||||
(unsigned short)conn_fd(cs_conn(si_f->cs)),
|
|
||||||
(unsigned short)conn_fd(cs_conn(si_b->cs)));
|
|
||||||
DISGUISE(write(1, trash.area, trash.data));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (si_f->state == SI_ST_CLO &&
|
|
||||||
si_f->prev_state == SI_ST_EST) {
|
|
||||||
chunk_printf(&trash, "%08x:%s.clicls[%04x:%04x]\n",
|
|
||||||
s->uniq_id, s->be->id,
|
|
||||||
(unsigned short)conn_fd(cs_conn(si_f->cs)),
|
|
||||||
(unsigned short)conn_fd(cs_conn(si_b->cs)));
|
|
||||||
DISGUISE(write(1, trash.area, trash.data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (likely((si_f->state != SI_ST_CLO) || !si_state_in(si_b->state, SI_SB_INI|SI_SB_CLO) ||
|
if (likely((si_f->state != SI_ST_CLO) || !si_state_in(si_b->state, SI_SB_INI|SI_SB_CLO) ||
|
||||||
(req->analysers & AN_REQ_FLT_END) || (res->analysers & AN_RES_FLT_END))) {
|
(req->analysers & AN_REQ_FLT_END) || (res->analysers & AN_RES_FLT_END))) {
|
||||||
if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED) && !(s->flags & SF_IGNORE))
|
if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED) && !(s->flags & SF_IGNORE))
|
||||||
|
@ -988,8 +988,7 @@ void si_update_both(struct stream_interface *si_f, struct stream_interface *si_b
|
|||||||
req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
|
req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
|
||||||
res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
|
res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
|
||||||
|
|
||||||
si_f->prev_state = si_f->state;
|
si_strm(si_b)->prev_conn_state = si_b->state;
|
||||||
si_b->prev_state = si_b->state;
|
|
||||||
|
|
||||||
/* let's recompute both sides states */
|
/* let's recompute both sides states */
|
||||||
if (si_state_in(si_f->state, SI_SB_RDY|SI_SB_EST))
|
if (si_state_in(si_f->state, SI_SB_RDY|SI_SB_EST))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user