diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index aae25c637..1c1e6a665 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -80,6 +80,7 @@ enum { TARG_TYPE_PROXY, /* target is a proxy ; use address with the proxy's settings */ TARG_TYPE_SERVER, /* target is a server ; use address with server's and its proxy's settings */ TARG_TYPE_APPLET, /* target is an applet ; use only the applet */ + TARG_TYPE_TASK, /* target is a task running an external applet */ }; #define SI_FL_CAP_SPLICE (SI_FL_CAP_SPLTCP) @@ -95,6 +96,7 @@ struct target { struct proxy *p; /* when type is TARG_TYPE_PROXY */ struct server *s; /* when type is TARG_TYPE_SERVER */ struct si_applet *a; /* when type is TARG_TYPE_APPLET */ + struct task *t; /* when type is TARG_TYPE_TASK */ } ptr; }; @@ -134,7 +136,6 @@ struct stream_interface { int conn_retries; /* number of connect retries left */ int fd; /* file descriptor for a stream driver when known */ struct { - struct si_applet *handler; /* applet to use instead of doing I/O */ void *private; /* may be used by any function above */ unsigned int st0, st1; /* may be used by any function above */ } applet; diff --git a/src/peers.c b/src/peers.c index 5e3b353e3..dd74ec3f9 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1053,7 +1053,8 @@ void peer_session_forceshutdown(struct session * session) { struct stream_interface *oldsi; - if (session->si[0].applet.handler == &peer_applet) { + if (session->si[0].target.type == TARG_TYPE_APPLET && + session->si[0].target.ptr.a == &peer_applet) { oldsi = &session->si[0]; } else { @@ -1156,7 +1157,6 @@ struct session *peer_session_create(struct peer *peer, struct peer_session *ps) s->si[0].err_type = SI_ET_NONE; s->si[0].err_loc = NULL; s->si[0].connect = NULL; - s->si[0].applet.handler = NULL; s->si[0].target.ptr.v = NULL; s->si[0].target.type = TARG_TYPE_NONE; s->si[0].exp = TICK_ETERNITY; @@ -1176,7 +1176,6 @@ struct session *peer_session_create(struct peer *peer, struct peer_session *ps) s->si[1].err_type = SI_ET_NONE; s->si[1].err_loc = NULL; s->si[1].connect = tcpv4_connect_server; - s->si[1].applet.handler = NULL; s->si[1].target.ptr.p = s->be; s->si[1].target.type = TARG_TYPE_PROXY; s->si[1].exp = TICK_ETERNITY; diff --git a/src/session.c b/src/session.c index 87f74641c..eb0a2521d 100644 --- a/src/session.c +++ b/src/session.c @@ -167,7 +167,6 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->si[0].err_type = SI_ET_NONE; s->si[0].err_loc = NULL; s->si[0].connect = NULL; - s->si[0].applet.handler = NULL; s->si[0].release = NULL; s->si[0].target.type = TARG_TYPE_NONE; s->si[0].target.ptr.v = NULL; @@ -192,7 +191,6 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->si[1].err_type = SI_ET_NONE; s->si[1].err_loc = NULL; s->si[1].connect = NULL; - s->si[1].applet.handler = NULL; s->si[1].release = NULL; s->si[1].target.type = TARG_TYPE_NONE; s->si[1].target.ptr.v = NULL; @@ -1796,7 +1794,7 @@ struct task *process_session(struct task *t) */ s->req->cons->state = SI_ST_REQ; /* new connection requested */ s->req->cons->conn_retries = s->be->conn_retries; - if (unlikely(s->req->cons->applet.handler && !s->req->cons->connect)) { + if (unlikely(s->req->cons->target.type == TARG_TYPE_APPLET && !s->req->cons->connect)) { s->req->cons->state = SI_ST_EST; /* connection established */ s->rep->flags |= BF_READ_ATTACHED; /* producer is now attached */ s->req->wex = TICK_ETERNITY; @@ -1953,10 +1951,10 @@ struct task *process_session(struct task *t) if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED)) session_process_counters(s); - if (s->rep->cons->state == SI_ST_EST && !s->rep->cons->applet.handler) + if (s->rep->cons->state == SI_ST_EST && s->rep->cons->target.type != TARG_TYPE_APPLET) s->rep->cons->update(s->rep->cons); - if (s->req->cons->state == SI_ST_EST && !s->req->cons->applet.handler) + if (s->req->cons->state == SI_ST_EST && s->req->cons->target.type != TARG_TYPE_APPLET) s->req->cons->update(s->req->cons); s->req->flags &= ~(BF_READ_NULL|BF_READ_PARTIAL|BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_READ_ATTACHED); @@ -1983,11 +1981,12 @@ struct task *process_session(struct task *t) /* Call the stream interfaces' I/O handlers when embedded. * Note that this one may wake the task up again. */ - if (s->req->cons->applet.handler || s->rep->cons->applet.handler) { - if (s->req->cons->applet.handler) - s->req->cons->applet.handler->fct(s->req->cons); - if (s->rep->cons->applet.handler) - s->rep->cons->applet.handler->fct(s->rep->cons); + if (s->req->cons->target.type == TARG_TYPE_APPLET || + s->rep->cons->target.type == TARG_TYPE_APPLET) { + if (s->req->cons->target.type == TARG_TYPE_APPLET) + s->req->cons->target.ptr.a->fct(s->req->cons); + if (s->rep->cons->target.type == TARG_TYPE_APPLET) + s->rep->cons->target.ptr.a->fct(s->rep->cons); if (task_in_rq(t)) { /* If we woke up, we don't want to requeue the * task to the wait queue, but rather requeue diff --git a/src/stream_interface.c b/src/stream_interface.c index db1397392..50e1f9c70 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -315,7 +315,6 @@ struct task *stream_int_register_handler(struct stream_interface *si, struct si_ si->connect = NULL; si->target.type = TARG_TYPE_APPLET; si->target.ptr.a = app; - si->applet.handler = app; si->release = NULL; si->flags |= SI_FL_WAIT_DATA; return si->owner; @@ -325,6 +324,8 @@ struct task *stream_int_register_handler(struct stream_interface *si, struct si_ * new task itself is returned and is assigned as si->owner. The stream_interface * pointer will be pointed to by the task's context. The handler can be detached * by using stream_int_unregister_handler(). + * FIXME: the code should be updated to ensure that we don't change si->owner + * anymore as this is not needed. However, process_session still relies on it. */ struct task *stream_int_register_handler_task(struct stream_interface *si, struct task *(*fct)(struct task *)) @@ -341,7 +342,6 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, si->connect = NULL; si->target.type = TARG_TYPE_NONE; si->target.ptr.v = NULL; - si->applet.handler = NULL; /* not used when running as an external task */ si->release = NULL; si->flags |= SI_FL_WAIT_DATA; @@ -349,6 +349,10 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, si->owner = t; if (!t) return t; + + si->target.type = TARG_TYPE_TASK; + si->target.ptr.t = t; + t->process = fct; t->context = si; task_wakeup(si->owner, TASK_WOKEN_INIT); @@ -362,12 +366,11 @@ struct task *stream_int_register_handler_task(struct stream_interface *si, */ void stream_int_unregister_handler(struct stream_interface *si) { - if (!si->applet.handler && si->owner) { + if (si->target.type == TARG_TYPE_TASK) { /* external handler : kill the task */ - task_delete(si->owner); - task_free(si->owner); + task_delete(si->target.ptr.t); + task_free(si->target.ptr.t); } - si->applet.handler = NULL; si->release = NULL; si->owner = NULL; si->target.type = TARG_TYPE_NONE; diff --git a/src/stream_sock.c b/src/stream_sock.c index 3c8563e26..1f45e3ff1 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -1252,7 +1252,6 @@ void stream_sock_prepare_interface(struct stream_interface *si) si->shutw = stream_sock_shutw; si->chk_rcv = stream_sock_chk_rcv; si->chk_snd = stream_sock_chk_snd; - si->applet.handler = NULL; }