diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index db166c9b2..cfba68735 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -100,6 +100,7 @@ struct stream_interface { void (*chk_snd)(struct stream_interface *);/* chk_snd function */ int (*connect)(struct stream_interface *, struct proxy *, struct server *, struct sockaddr *, struct sockaddr *); /* connect function if any */ + void (*release)(struct stream_interface *); /* handler to call after the last close() */ void (*iohandler)(struct stream_interface *); /* internal I/O handler when embedded */ struct buffer *ib, *ob; /* input and output buffers */ int conn_retries; /* number of connect retries left */ diff --git a/src/session.c b/src/session.c index 556fffefc..10c7f13d6 100644 --- a/src/session.c +++ b/src/session.c @@ -139,6 +139,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->si[0].err_loc = NULL; s->si[0].connect = NULL; s->si[0].iohandler = NULL; + s->si[0].release = NULL; s->si[0].exp = TICK_ETERNITY; s->si[0].flags = SI_FL_NONE; @@ -161,6 +162,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->si[1].err_loc = NULL; s->si[1].connect = NULL; s->si[1].iohandler = NULL; + s->si[1].release = NULL; s->si[1].shutr = stream_int_shutr; s->si[1].shutw = stream_int_shutw; s->si[1].exp = TICK_ETERNITY; @@ -434,6 +436,9 @@ int sess_update_st_con_tcp(struct session *s, struct stream_interface *si) si->flags &= ~SI_FL_CAP_SPLICE; fd_delete(si->fd); + if (si->release) + si->release(si); + if (si->err_type) return 0; diff --git a/src/stream_interface.c b/src/stream_interface.c index c45abdbe8..113f01c65 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -178,6 +178,9 @@ void stream_int_shutr(struct stream_interface *si) si->exp = TICK_ETERNITY; } + if (si->release) + si->release(si); + /* note that if the task exist, it must unregister itself once it runs */ if (!(si->flags & SI_FL_DONT_WAKE) && si->owner) task_wakeup(si->owner, TASK_WOKEN_IO); @@ -214,6 +217,9 @@ void stream_int_shutw(struct stream_interface *si) si->exp = TICK_ETERNITY; } + if (si->release) + si->release(si); + /* note that if the task exist, it must unregister itself once it runs */ if (!(si->flags & SI_FL_DONT_WAKE) && si->owner) task_wakeup(si->owner, TASK_WOKEN_IO); @@ -289,6 +295,7 @@ struct task *stream_int_register_handler(struct stream_interface *si, si->chk_snd = stream_int_chk_snd; si->connect = NULL; si->iohandler = fct; + si->release = NULL; si->flags |= SI_FL_WAIT_DATA; return si->owner; } @@ -312,6 +319,7 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, si->chk_snd = stream_int_chk_snd; si->connect = NULL; si->iohandler = NULL; /* not used when running as an external task */ + si->release = NULL; si->flags |= SI_FL_WAIT_DATA; t = task_new(); @@ -337,6 +345,7 @@ void stream_int_unregister_handler(struct stream_interface *si) task_free(si->owner); } si->iohandler = NULL; + si->release = NULL; si->owner = NULL; } diff --git a/src/stream_sock.c b/src/stream_sock.c index 2d5ef6d70..8cd721ea7 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -875,6 +875,9 @@ void stream_sock_shutw(struct stream_interface *si) si->exp = TICK_ETERNITY; return; } + + if (si->release) + si->release(si); } /* @@ -899,6 +902,9 @@ void stream_sock_shutr(struct stream_interface *si) fd_delete(si->fd); si->state = SI_ST_DIS; si->exp = TICK_ETERNITY; + + if (si->release) + si->release(si); return; } EV_FD_CLR(si->fd, DIR_RD);