struct stconn;
-/* cs_data_cb describes the data layer's recv and send callbacks which are called
- * when I/O activity was detected after the transport layer is ready. These
- * callbacks are supposed to make use of the xprt_ops above to exchange data
- * from/to buffers and pipes. The <wake> callback is used to report activity
- * at the transport layer, which can be a connection opening/close, or any
- * data movement. It may abort a connection by returning < 0.
- */
-struct data_cb {
- int (*wake)(struct stconn *sc); /* data-layer callback to report activity */
- char name[8]; /* data layer name, zero-terminated */
-};
-
-
/* A Stream Endpoint Descriptor (sedesc) is the link between the stream
* connector (ex. conn_stream) and the Stream Endpoint (mux or appctx).
* It always exists for either of them, and binds them together. It also
unsigned int flags;
};
-/* operations available on a stream connector */
+/* sc_app_ops describes the application layer's operations and notification
+ * callbacks when I/O activity is reported and to use to perform shutr/shutw.
+ * There are very few combinations in practice (strm/chk <-> none/mux/applet).
+ */
struct sc_app_ops {
void (*chk_rcv)(struct stconn *); /* chk_rcv function, may not be null */
void (*chk_snd)(struct stconn *); /* chk_snd function, may not be null */
void (*shutr)(struct stconn *); /* shut read function, may not be null */
void (*shutw)(struct stconn *); /* shut write function, may not be null */
+ int (*wake)(struct stconn *); /* data-layer callback to report activity */
+ char name[8]; /* data layer name, zero-terminated */
};
/*
struct wait_event wait_event; /* We're in a wait list */
struct sedesc *sedesc; /* points to the stream endpoint descriptor */
enum obj_type *app; /* points to the applicative point (stream or check) */
- const struct data_cb *data_cb; /* data layer callbacks. Must be set before xprt->init() */
- struct sc_app_ops *ops; /* general operations used at the app layer */
+ const struct sc_app_ops *app_ops; /* general operations used at the app layer */
struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */
struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */
};
}
static inline const char *cs_get_data_name(const struct stconn *cs)
{
- if (!cs->data_cb)
+ if (!cs->app_ops)
return "NONE";
- return cs->data_cb->name;
+ return cs->app_ops->name;
}
/* shut read */
/* Sends a shutr to the endpoint using the data layer */
static inline void cs_shutr(struct stconn *cs)
{
- if (likely(cs->ops->shutr))
- cs->ops->shutr(cs);
+ if (likely(cs->app_ops->shutr))
+ cs->app_ops->shutr(cs);
}
/* Sends a shutw to the endpoint using the data layer */
static inline void cs_shutw(struct stconn *cs)
{
- if (likely(cs->ops->shutw))
- cs->ops->shutw(cs);
+ if (likely(cs->app_ops->shutw))
+ cs->app_ops->shutw(cs);
}
/* This is to be used after making some room available in a channel. It will
return;
sc_ep_set(cs, SE_FL_RX_WAIT_EP);
- if (likely(cs->ops->chk_rcv))
- cs->ops->chk_rcv(cs);
+ if (likely(cs->app_ops->chk_rcv))
+ cs->app_ops->chk_rcv(cs);
}
/* Calls chk_snd on the endpoint using the data layer */
static inline void cs_chk_snd(struct stconn *cs)
{
- if (likely(cs->ops->chk_snd))
- cs->ops->chk_snd(cs);
+ if (likely(cs->app_ops->chk_snd))
+ cs->app_ops->chk_snd(cs);
}
/* Combines both cs_update_rx() and cs_update_tx() at once */
stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate));
}
- cs->data_cb->wake(cs);
+ cs->app_ops->wake(cs);
channel_release_buffer(cs_ic(cs), &app->buffer_wait);
return t;
}
INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);
-struct data_cb check_conn_cb = {
- .wake = wake_srv_chk,
- .name = "CHCK",
-};
-
-
/* Dummy frontend used to create all checks sessions. */
struct proxy checks_fe;
static void sc_app_chk_rcv_applet(struct stconn *cs);
static void sc_app_chk_snd_applet(struct stconn *cs);
+static int cs_conn_process(struct stconn *cs);
+static int cs_conn_recv(struct stconn *cs);
+static int cs_conn_send(struct stconn *cs);
+static int cs_applet_process(struct stconn *cs);
+
/* stream connector operations for connections */
struct sc_app_ops sc_app_conn_ops = {
.chk_rcv = sc_app_chk_rcv_conn,
.chk_snd = sc_app_chk_snd_conn,
.shutr = sc_app_shutr_conn,
.shutw = sc_app_shutw_conn,
+ .wake = cs_conn_process,
+ .name = "STRM",
};
/* stream connector operations for embedded tasks */
.chk_snd = sc_app_chk_snd,
.shutr = sc_app_shutr,
.shutw = sc_app_shutw,
+ .wake = NULL, /* may never be used */
+ .name = "NONE", /* may never be used */
};
-/* stream connector operations for connections */
+/* stream connector operations for applets */
struct sc_app_ops sc_app_applet_ops = {
.chk_rcv = sc_app_chk_rcv_applet,
.chk_snd = sc_app_chk_snd_applet,
.shutr = sc_app_shutr_applet,
.shutw = sc_app_shutw_applet,
-};
-
-static int cs_conn_process(struct stconn *cs);
-static int cs_conn_recv(struct stconn *cs);
-static int cs_conn_send(struct stconn *cs);
-static int cs_applet_process(struct stconn *cs);
-
-struct data_cb cs_data_conn_cb = {
- .wake = cs_conn_process,
- .name = "STRM",
-};
-
-struct data_cb cs_data_applet_cb = {
.wake = cs_applet_process,
.name = "STRM",
};
+/* stream connector for health checks on connections */
+struct sc_app_ops sc_app_check_ops = {
+ .chk_rcv = NULL,
+ .chk_snd = NULL,
+ .shutr = NULL,
+ .shutw = NULL,
+ .wake = wake_srv_chk,
+ .name = "CHCK",
+};
/* Initializes an endpoint */
void sedesc_init(struct sedesc *sedesc)
cs->state = SC_ST_INI;
cs->hcto = TICK_ETERNITY;
cs->app = NULL;
- cs->data_cb = NULL;
+ cs->app_ops = NULL;
cs->src = NULL;
cs->dst = NULL;
cs->wait_event.tasklet = NULL;
cs->flags |= flags;
sc_ep_set(cs, SE_FL_DETACHED);
cs->app = &strm->obj_type;
- cs->ops = &sc_app_embedded_ops;
- cs->data_cb = NULL;
+ cs->app_ops = &sc_app_embedded_ops;
return cs;
}
cs->flags |= flags;
sc_ep_set(cs, SE_FL_DETACHED);
cs->app = &check->obj_type;
- cs->data_cb = &check_conn_cb;
+ cs->app_ops = &sc_app_check_ops;
return cs;
}
cs->wait_event.events = 0;
}
- cs->ops = &sc_app_conn_ops;
- cs->data_cb = &cs_data_conn_cb;
+ cs->app_ops = &sc_app_conn_ops;
}
else if (cs_check(cs)) {
if (!cs->wait_event.tasklet) {
cs->wait_event.events = 0;
}
- cs->data_cb = &check_conn_cb;
+ cs->app_ops = &sc_app_check_ops;
}
return 0;
}
cs->sedesc->se = endp;
sc_ep_set(cs, SE_FL_T_APPLET);
sc_ep_clr(cs, SE_FL_DETACHED);
- if (cs_strm(cs)) {
- cs->ops = &sc_app_applet_ops;
- cs->data_cb = &cs_data_applet_cb;
- }
+ if (cs_strm(cs))
+ cs->app_ops = &sc_app_applet_ops;
}
/* Attaches a stconn to a app layer and sets the relevant
cs->wait_event.tasklet->context = cs;
cs->wait_event.events = 0;
- cs->ops = &sc_app_conn_ops;
- cs->data_cb = &cs_data_conn_cb;
+ cs->app_ops = &sc_app_conn_ops;
}
else if (sc_ep_test(cs, SE_FL_T_APPLET)) {
- cs->ops = &sc_app_applet_ops;
- cs->data_cb = &cs_data_applet_cb;
+ cs->app_ops = &sc_app_applet_ops;
}
else {
- cs->ops = &sc_app_embedded_ops;
- cs->data_cb = NULL;
+ cs->app_ops = &sc_app_embedded_ops;
}
return 0;
}
*/
cs->flags &= SC_FL_ISBACK;
if (cs_strm(cs))
- cs->ops = &sc_app_embedded_ops;
- cs->data_cb = NULL;
+ cs->app_ops = &sc_app_embedded_ops;
+ else
+ cs->app_ops = NULL;
cs_free_cond(csp);
}
return;
cs->app = NULL;
- cs->data_cb = NULL;
+ cs->app_ops = NULL;
sockaddr_free(&cs->src);
sockaddr_free(&cs->dst);
return 0;
fail:
/* let the upper layer know the connection failed */
- cs->data_cb->wake(cs);
+ cs->app_ops->wake(cs);
return -1;
} else
return conn_complete_session(conn);
fcgi_strm_notify_recv(fstrm);
fcgi_strm_notify_send(fstrm);
}
- else if (fcgi_strm_sc(fstrm) && fcgi_strm_sc(fstrm)->data_cb->wake != NULL) {
+ else if (fcgi_strm_sc(fstrm) && fcgi_strm_sc(fstrm)->app_ops->wake != NULL) {
TRACE_POINT(FCGI_EV_STRM_WAKE, fstrm->fconn->conn, fstrm);
- fcgi_strm_sc(fstrm)->data_cb->wake(fcgi_strm_sc(fstrm));
+ fcgi_strm_sc(fstrm)->app_ops->wake(fcgi_strm_sc(fstrm));
}
}
h1_wake_stream_for_recv(h1s);
h1_wake_stream_for_send(h1s);
}
- else if (h1s_sc(h1s) && h1s_sc(h1s)->data_cb->wake != NULL) {
+ else if (h1s_sc(h1s) && h1s_sc(h1s)->app_ops->wake != NULL) {
TRACE_POINT(H1_EV_STRM_WAKE, h1s->h1c->conn, h1s);
- h1s_sc(h1s)->data_cb->wake(h1s_sc(h1s));
+ h1s_sc(h1s)->app_ops->wake(h1s_sc(h1s));
}
}
h2s_notify_recv(h2s);
h2s_notify_send(h2s);
}
- else if (h2s_sc(h2s) && h2s_sc(h2s)->data_cb->wake != NULL) {
+ else if (h2s_sc(h2s) && h2s_sc(h2s)->app_ops->wake != NULL) {
TRACE_POINT(H2_EV_STRM_WAKE, h2s->h2c->conn, h2s);
- h2s_sc(h2s)->data_cb->wake(h2s_sc(h2s));
+ h2s_sc(h2s)->app_ops->wake(h2s_sc(h2s));
}
TRACE_LEAVE(H2_EV_H2S_WAKE, h2s->h2c->conn, h2s);
ctx->conn->subs->events = 0;
tasklet_wakeup(ctx->conn->subs->tasklet);
ctx->conn->subs = NULL;
- } else if (pt_sc(ctx)->data_cb->wake)
- pt_sc(ctx)->data_cb->wake(pt_sc(ctx));
+ } else if (pt_sc(ctx)->app_ops->wake)
+ pt_sc(ctx)->app_ops->wake(pt_sc(ctx));
TRACE_DEVEL("leaving waking up CS", PT_EV_CONN_WAKE, ctx->conn);
return t;
}
TRACE_ENTER(PT_EV_CONN_WAKE, ctx->conn);
if (!se_fl_test(ctx->endp, SE_FL_ORPHAN)) {
- ret = pt_sc(ctx)->data_cb->wake ? pt_sc(ctx)->data_cb->wake(pt_sc(ctx)) : 0;
+ ret = pt_sc(ctx)->app_ops->wake ? pt_sc(ctx)->app_ops->wake(pt_sc(ctx)) : 0;
if (ret < 0) {
TRACE_DEVEL("leaving waking up CS", PT_EV_CONN_WAKE, ctx->conn);
qcs_notify_recv(qcs);
qcs_notify_send(qcs);
}
- else if (qcs->endp->sc->data_cb->wake) {
- qcs->endp->sc->data_cb->wake(qcs->endp->sc);
+ else if (qcs->endp->sc->app_ops->wake) {
+ qcs->endp->sc->app_ops->wake(qcs->endp->sc);
}
}
}