LIST_INIT(&cs->wait_list.list);
LIST_INIT(&cs->send_wait_list);
cs->conn = conn;
+ cs->rxbuf = BUF_NULL;
}
/* Initializes all required fields for a new connection. Note that it does the
return conn;
}
-/* Releases a conn_stream previously allocated by cs_new() */
+/* Releases the conn_stream's rx buf if it exists. The buffer is automatically
+ * replaced with a pointer to the empty buffer.
+ */
+static inline void cs_drop_rxbuf(struct conn_stream *cs)
+{
+ if (b_size(&cs->rxbuf)) {
+ b_free(&cs->rxbuf);
+ offer_buffers(NULL, tasks_run_queue);
+ }
+}
+
+/* Releases a conn_stream previously allocated by cs_new(), as well as any
+ * buffer it would still hold.
+ */
static inline void cs_free(struct conn_stream *cs)
{
if (cs->wait_list.task)
tasklet_free(cs->wait_list.task);
+
+ cs_drop_rxbuf(cs);
pool_free(pool_head_connstream, cs);
}
*/
struct conn_stream {
enum obj_type obj_type; /* differentiates connection from applet context */
+ /* 3 bytes hole here */
unsigned int flags; /* CS_FL_* */
struct connection *conn; /* xprt-level connection */
struct wait_list wait_list; /* We're in a wait list for send */
struct list send_wait_list; /* list of tasks to wake when we're ready to send */
+ struct buffer rxbuf; /* receive buffer, always valid (buf_empty or real buffer) */
void *data; /* pointer to upper layer's entity (eg: stream interface) */
const struct data_cb *data_cb; /* data layer callbacks. Must be set before xprt->init() */
void *ctx; /* mux-specific context */