poll.c:dcb_close Don't call poll_remove_dcb anymore if DCB has already been removed from poll set.

mysql_backend.c, mysql_client.c free error message GWBUF after calling handleError
readconnroute.c:handleError send error message to client before returning.
readwritesplit.c:handleError don't free error message buffer anymore since the caller of handleError frees it.
This commit is contained in:
VilhoRaatikka
2014-11-01 20:00:59 +02:00
parent b6fe4e620a
commit 9ccbab1899
5 changed files with 148 additions and 139 deletions

View File

@ -1140,18 +1140,9 @@ dcb_close(DCB *dcb)
/*<
* Stop dcb's listening and modify state accordingly.
*/
rc = poll_remove_dcb(dcb);
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE);
/**
* close protocol and router session
*/
if (dcb->func.close != NULL)
if (dcb->state == DCB_STATE_POLLING)
{
dcb->func.close(dcb);
}
dcb_call_callback(dcb, DCB_REASON_CLOSE);
rc = poll_remove_dcb(dcb);
if (rc == 0) {
LOGIF(LD, (skygw_log_write(
@ -1170,6 +1161,18 @@ dcb_close(DCB *dcb)
dcb,
STRDCBSTATE(dcb->state))));
}
}
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE);
/**
* close protocol and router session
*/
if (dcb->func.close != NULL)
{
dcb->func.close(dcb);
}
dcb_call_callback(dcb, DCB_REASON_CLOSE);
if (dcb->state == DCB_STATE_NOPOLLING)
{

View File

@ -377,7 +377,7 @@ static int gw_read_backend_event(DCB *dcb) {
dcb,
ERRACT_REPLY_CLIENT,
&succp);
gwbuf_free(errbuf);
ss_dassert(!succp);
LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG,
@ -459,6 +459,7 @@ static int gw_read_backend_event(DCB *dcb) {
dcb,
ERRACT_NEW_CONNECTION,
&succp);
gwbuf_free(errbuf);
if (!succp)
{
@ -848,6 +849,7 @@ static int gw_error_backend_event(DCB *dcb)
dcb,
ERRACT_NEW_CONNECTION,
&succp);
gwbuf_free(errbuf);
/** There are not required backends available, close session. */
if (!succp) {
@ -1031,7 +1033,8 @@ gw_backend_hangup(DCB *dcb)
ERRACT_NEW_CONNECTION,
&succp);
/** There are not required backends available, close session. */
gwbuf_free(errbuf);
/** There are no required backends available, close session. */
if (!succp)
{
#if defined(SS_DEBUG)
@ -1039,7 +1042,6 @@ gw_backend_hangup(DCB *dcb)
LOGFILE_ERROR,
"Backend hangup -> closing session.")));
#endif
spinlock_acquire(&session->ses_lock);
session->state = SESSION_STATE_STOPPING;
spinlock_release(&session->ses_lock);
@ -1176,6 +1178,7 @@ static int backend_write_delayqueue(DCB *dcb)
dcb,
ERRACT_NEW_CONNECTION,
&succp);
gwbuf_free(errbuf);
if (!succp)
{

View File

@ -859,6 +859,7 @@ int gw_read_client_event(
dcb,
ERRACT_REPLY_CLIENT,
&succp);
gwbuf_free(errbuf);
ss_dassert(!succp);
dcb_close(dcb);

View File

@ -815,21 +815,33 @@ clientReply(
* @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION
*
*/
static void
handleError(
static void handleError(
ROUTER *instance,
void *router_session,
GWBUF *errbuf,
DCB *backend_dcb,
error_action_t action,
bool *succp)
{
DCB *client = NULL;
DCB *client_dcb;
SESSION *session = backend_dcb->session;
client = session->client;
session_state_t sesstate;
spinlock_acquire(&session->ses_lock);
sesstate = session->state;
client_dcb = session->client;
spinlock_release(&session->ses_lock);
ss_dassert(client_dcb != NULL);
if (sesstate == SESSION_STATE_ROUTER_READY)
{
CHK_DCB(client_dcb);
client_dcb->func.write(client_dcb, gwbuf_clone(errbuf));
}
/** false because connection is not available anymore */
*succp = false;
ss_dassert(client != NULL);
}
/** to be inline'd */

View File

@ -4023,7 +4023,7 @@ static void rwsplit_process_router_options(
*
* @param instance The router instance
* @param router_session The router session
* @param message The error message to reply
* @param errmsgbuf The error message to reply
* @param backend_dcb The backend DCB
* @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION
* @param succp Result of action.
@ -4102,12 +4102,7 @@ static void handle_error_reply_client(
if (sesstate == SESSION_STATE_ROUTER_READY)
{
CHK_DCB(client_dcb);
client_dcb->func.write(client_dcb, errmsg);
}
else
{
while ((errmsg=gwbuf_consume(errmsg, GWBUF_LENGTH(errmsg))) != NULL)
;
client_dcb->func.write(client_dcb, gwbuf_clone(errmsg));
}
}
@ -4157,14 +4152,9 @@ static bool handle_error_new_connection(
{
DCB* client_dcb;
client_dcb = ses->client;
client_dcb->func.write(client_dcb, errmsg);
client_dcb->func.write(client_dcb, gwbuf_clone(errmsg));
bref_clear_state(bref, BREF_WAITING_RESULT);
}
else
{
while ((errmsg=gwbuf_consume(errmsg, GWBUF_LENGTH(errmsg))) != NULL)
;
}
bref_clear_state(bref, BREF_IN_USE);
bref_set_state(bref, BREF_CLOSED);
/**