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)
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;
};
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;
{
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 {
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;
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;
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;
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;
*/
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;
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);
/* 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
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;
* 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 *))
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;
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);
*/
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;
si->shutw = stream_sock_shutw;
si->chk_rcv = stream_sock_chk_rcv;
si->chk_snd = stream_sock_chk_snd;
- si->applet.handler = NULL;
}