From e650930487aa717b06a3efbae6cb3bb86f4f9f57 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Mon, 23 Jun 2014 10:10:04 +0100 Subject: [PATCH] Cleanup up branch session on close. --- server/core/dcb.c | 35 +++++++++++++++++++++++++++++++++-- server/include/dcb.h | 5 +++++ server/modules/filter/tee.c | 19 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index edf6b26a5..f9f9eafbe 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -140,6 +140,7 @@ DCB *rval; rval->remote = NULL; rval->user = NULL; + rval->flags = 0; spinlock_acquire(&dcbspin); if (allDCBs == NULL) @@ -270,6 +271,7 @@ DCB *clone; } clone->fd = -1; + clone->flags |= DCBF_CLONE; clone->state = orig->state; clone->data = orig->data; if (orig->remote) @@ -347,7 +349,7 @@ DCB_CALLBACK *cb; if (dcb->protocol != NULL) free(dcb->protocol); - if (dcb->data) + if (dcb->data && ((dcb->flags & DCBF_CLONE) ==0)) free(dcb->data); if (dcb->remote) free(dcb->remote); @@ -1225,6 +1227,8 @@ DCB *dcb; dcb_printf(pdcb, "\t\tNo. of Accepts: %d\n", dcb->stats.n_accepts); dcb_printf(pdcb, "\t\tNo. of High Water Events: %d\n", dcb->stats.n_high_water); dcb_printf(pdcb, "\t\tNo. of Low Water Events: %d\n", dcb->stats.n_low_water); + if (dcb->flags & DCBF_CLONE) + dcb_printf(pdcb, "\t\tDCB is a clone.\n"); dcb = dcb->next; } spinlock_release(&dcbspin); @@ -1289,6 +1293,8 @@ dprintDCB(DCB *pdcb, DCB *dcb) dcb->stats.n_high_water); dcb_printf(pdcb, "\t\tNo. of Low Water Events: %d\n", dcb->stats.n_low_water); + if (dcb->flags & DCBF_CLONE) + dcb_printf(pdcb, "\t\tDCB is a clone.\n"); } /** @@ -1319,7 +1325,7 @@ gw_dcb_state2string (int state) { } /** - * A DCB based wrapper for printf. Allows formattign printing to + * A DCB based wrapper for printf. Allows formatting printing to * a descritor control block. * * @param dcb Descriptor to write to @@ -1858,18 +1864,43 @@ void dcb_call_foreach ( } +/** + * Null protocol write routine used for cloned dcb's. It merely consumes + * buffers written on the cloned DCB. + * + * @params dcb The descriptor control block + * @params buf The buffer beign written + * @return Always returns a good write operation result + */ static int dcb_null_write(DCB *dcb, GWBUF *buf) { + while (buf) + { + buf = gwbuf_consume(buf, GWBUF_LENGTH(buf)); + } return 1; } +/** + * Null protocol close operation for use by cloned DCB's. + * + * @param dcb The DCB being closed. + */ static int dcb_null_close(DCB *dcb) { return 0; } +/** + * Null protocol auth operation for use by cloned DCB's. + * + * @param dcb The DCB being closed. + * @param server The server to auth against + * @param session The user session + * @param buf The buffer with the new auth request + */ static int dcb_null_auth(DCB *dcb, SERVER *server, SESSION *session, GWBUF *buf) { diff --git a/server/include/dcb.h b/server/include/dcb.h index 0830a8c6c..3a2cace5c 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -207,6 +207,7 @@ typedef struct dcb { #endif int fd; /**< The descriptor */ dcb_state_t state; /**< Current descriptor state */ + int flags; /**< DCB flags */ char *remote; /**< Address of remote end */ char *user; /**< User name for connection */ struct sockaddr_in ipv4; /**< remote end IPv4 address */ @@ -296,4 +297,8 @@ bool dcb_set_state( DCB* dcb, dcb_state_t new_state, dcb_state_t* old_state); + + +/* DCB flags values */ +#define DCBF_CLONE 0x0001 /* DCB is a clone */ #endif /* _DCB_H */ diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 80061d691..908117acf 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -52,6 +52,7 @@ #include #include #include +#include #include extern int lm_enabled_logfiles_bitmask; @@ -296,7 +297,8 @@ char *remote, *userName; /** * Close a session with the filter, this is the mechanism * by which a filter may cleanup data structure etc. - * In the case of the QLA filter we simple close the file descriptor. + * In the case of the tee filter we need to close down the + * "branch" session. * * @param instance The filter instance data * @param session The session being closed @@ -305,10 +307,23 @@ static void closeSession(FILTER *instance, void *session) { TEE_SESSION *my_session = (TEE_SESSION *)session; +ROUTER_OBJECT *router; +void *router_instance, *rsession; +SESSION *bsession; if (my_session->active) { - session_free(my_session->branch_session); + bsession = my_session->branch_session; + router = bsession->service->router; + router_instance = bsession->service->router_instance; + rsession = bsession->router_session; + /** Close router session and all its connections */ + router->closeSession(router_instance, rsession); + dcb_free(my_session->branch_dcb); + /* No need to free the session, this is done as + * a side effect of closign the client DCB of the + * session. + */ } }