int status, const struct chunk *msg)
{
buffer_write_ena(t->rep);
- buffer_shutw(t->req);
- buffer_shutr(t->rep);
+ t->req->cons->shutw(t->req->cons);
+ t->req->cons->shutr(t->req->cons);
if (status > 0 && msg) {
t->txn.status = status;
if (t->fe->mode == PR_MODE_HTTP)
process_srv_queue(s->srv);
/* Failed and not retryable. */
- buffer_shutr(si->ib);
- buffer_shutw(si->ob);
+ si->shutr(si);
+ si->shutw(si);
si->ob->flags |= BF_WRITE_ERROR;
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
if (s->srv)
s->srv->failed_conns++;
s->be->failed_conns++;
- buffer_shutr(si->ib);
- buffer_shutw(si->ob);
+ si->shutr(si);
+ si->shutw(si);
si->ob->flags |= BF_WRITE_TIMEOUT;
if (!si->err_type)
si->err_type = SI_ET_QUEUE_TO;
/* give up */
si->exp = TICK_ETERNITY;
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
- buffer_shutr(si->ib);
- buffer_shutw(si->ob);
+ si->shutr(si);
+ si->shutw(si);
si->err_type |= SI_ET_QUEUE_ABRT;
si->state = SI_ST_CLO;
return;
(si->ob->flags & BF_EMPTY || s->be->options & PR_O_ABRT_CLOSE))) {
/* give up */
si->exp = TICK_ETERNITY;
- buffer_shutr(si->ib);
- buffer_shutw(si->ob);
+ si->shutr(si);
+ si->shutw(si);
si->err_type |= SI_ET_CONN_ABRT;
si->state = SI_ST_CLO;
return;
rdr.len += 4;
/* prepare to return without error. */
- buffer_shutr(si->ib);
- buffer_shutw(si->ob);
+ si->shutr(si);
+ si->shutw(si);
si->err_type = SI_ET_NONE;
si->err_loc = NULL;
si->state = SI_ST_CLO;
return;
/* we did not get any server, let's check the cause */
- buffer_shutr(si->ib);
- buffer_shutw(si->ob);
+ si->shutr(si);
+ si->shutw(si);
si->ob->flags |= BF_WRITE_ERROR;
if (!si->err_type)
si->err_type = SI_ET_CONN_OTHER;
/* 1c: Manage buffer timeouts. */
if (unlikely(s->req->flags & (BF_READ_TIMEOUT|BF_WRITE_TIMEOUT))) {
if (s->req->flags & BF_READ_TIMEOUT) {
- buffer_shutr(s->req);
+ //buffer_shutr(s->req);
s->req->cons->shutr(s->req->prod);
}
if (s->req->flags & BF_WRITE_TIMEOUT) {
- buffer_shutw(s->req);
+ //buffer_shutw(s->req);
s->req->cons->shutw(s->req->cons);
}
}
if (unlikely(s->rep->flags & (BF_READ_TIMEOUT|BF_WRITE_TIMEOUT))) {
if (s->rep->flags & BF_READ_TIMEOUT) {
- buffer_shutr(s->rep);
+ //buffer_shutr(s->rep);
s->rep->cons->shutr(s->rep->prod);
}
if (s->rep->flags & BF_WRITE_TIMEOUT) {
- buffer_shutw(s->rep);
+ //buffer_shutw(s->rep);
s->rep->cons->shutw(s->rep->cons);
}
}
*/
if (unlikely((s->req->flags & (BF_SHUTW|BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR)) == (BF_EMPTY|BF_WRITE_ENA|BF_SHUTR)) ||
unlikely((s->req->flags & (BF_SHUTW|BF_SHUTW_NOW)) == BF_SHUTW_NOW)) {
- buffer_shutw(s->req);
+ //buffer_shutw(s->req);
s->req->cons->shutw(s->req->cons);
}
if (unlikely((s->req->flags & (BF_SHUTW|BF_SHUTR|BF_SHUTR_NOW)) == BF_SHUTW)) {
/* write closed on server side, let's forward it to the client */
- buffer_shutr_now(s->req);
+ //buffer_shutr_now(s->req);
s->req->prod->shutr(s->req->prod);
}
if (unlikely((s->rep->flags & (BF_SHUTW|BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR)) == (BF_EMPTY|BF_WRITE_ENA|BF_SHUTR)) ||
unlikely((s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW)) == BF_SHUTW_NOW)) {
- buffer_shutw(s->rep);
+ //buffer_shutw(s->rep);
s->rep->cons->shutw(s->rep->cons);
}
if (unlikely((s->rep->flags & (BF_SHUTW|BF_SHUTR|BF_SHUTR_NOW)) == BF_SHUTW)) {
/* write closed on client side, let's forward it to the server */
- buffer_shutr_now(s->rep);
+ //buffer_shutr_now(s->rep);
s->rep->prod->shutr(s->rep->prod);
}
((req->flags & BF_EMPTY && !(req->flags & BF_WRITE_ACTIVITY)) ||
s->be->options & PR_O_ABRT_CLOSE)))) {
/* give up */
- req->wex = TICK_ETERNITY;
- fd_delete(si->fd);
- buffer_shutw(req);
- buffer_shutr(rep);
- si->state = SI_ST_DIS;
+ si->shutw(si);
si->err_type |= SI_ET_CONN_ABRT;
si->err_loc = s->srv;
return 1;
if (may_dequeue_tasks(s->srv, s->be))
process_srv_queue(s->srv);
- buffer_shutw(si->ob);
+ si->shutw(si);
si->ob->flags |= BF_WRITE_ERROR;
- buffer_shutr(si->ib);
+ si->shutr(si);
si->ib->flags |= BF_READ_ERROR;
si->state = SI_ST_CLO;
/* we received a shutdown */
fdtab[fd].ev &= ~FD_POLL_HUP;
b->flags |= BF_READ_NULL;
- buffer_shutr(b);
-
- /* Maybe we have to completely close the local socket */
- if (si->ob->flags & BF_SHUTW)
- goto do_close_and_return;
- EV_FD_CLR(fd, DIR_RD);
+ stream_sock_shutr(si);
goto out_wakeup;
out_error:
fdtab[fd].state = FD_STERROR;
fdtab[fd].ev &= ~FD_POLL_STICKY;
si->flags |= SI_FL_ERR;
- goto wakeup_return;
-
- do_close_and_return:
- si->state = SI_ST_DIS;
- fd_delete(fd);
- wakeup_return:
task_wakeup(si->owner, TASK_WOKEN_IO);
return 1;
}
/* Maybe we just wrote the last chunk and need to close ? */
if ((b->flags & (BF_SHUTW|BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR)) == (BF_EMPTY|BF_WRITE_ENA|BF_SHUTR)) {
if (si->state == SI_ST_EST) {
- buffer_shutw(b);
- if (si->ib->flags & BF_SHUTR)
- goto do_close_and_return;
- shutdown(fd, SHUT_WR);
+ stream_sock_shutw(si);
+ b->wex = TICK_ETERNITY;
+ goto out_wakeup;
}
}
fdtab[fd].state = FD_STERROR;
fdtab[fd].ev &= ~FD_POLL_STICKY;
si->flags |= SI_FL_ERR;
- goto wakeup_return;
-
- do_close_and_return:
- si->state = SI_ST_DIS;
- fd_delete(fd);
- wakeup_return:
task_wakeup(si->owner, TASK_WOKEN_IO);
return 1;
}
/*
* This function performs a shutdown-write on a stream interface in a connected or
* init state (it does nothing for other states). It either shuts the write side
- * or closes the file descriptor and marks itself as closed. No buffer flags are
- * changed, it's up to the caller to adjust them. The sole purpose of this
- * function is to be called from the other stream interface to notify of a
- * close_read, or by itself upon a full write leading to an empty buffer.
+ * or closes the file descriptor and marks itself as closed. The buffer flags are
+ * updated to reflect the new state.
*/
void stream_sock_shutw(struct stream_interface *si)
{
+ if (si->ob->flags & BF_SHUTW)
+ return;
+ si->ob->flags |= BF_SHUTW;
+ si->ob->wex = TICK_ETERNITY;
+
switch (si->state) {
case SI_ST_EST:
if (!(si->ib->flags & BF_SHUTR)) {
* response buffer as shutr
*/
fd_delete(si->fd);
- buffer_shutr(si->ib);
+ si->ib->flags |= BF_SHUTR;
si->state = SI_ST_DIS;
return;
}
/*
* This function performs a shutdown-read on a stream interface in a connected or
* init state (it does nothing for other states). It either shuts the read side
- * or closes the file descriptor and marks itself as closed. No buffer flags are
- * changed, it's up to the caller to adjust them. The sole purpose of this
- * function is to be called from the other stream interface to notify of a
- * close_read, or by itself upon a full write leading to an empty buffer.
+ * or closes the file descriptor and marks itself as closed. The buffer flags are
+ * updated to reflect the new state.
*/
void stream_sock_shutr(struct stream_interface *si)
{
+ if (si->ib->flags & BF_SHUTR)
+ return;
+ si->ib->flags |= BF_SHUTR;
+ si->ib->rex = TICK_ETERNITY;
+
if (si->state != SI_ST_EST && si->state != SI_ST_CON)
return;