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. * Stop dcb's listening and modify state accordingly.
*/ */
rc = poll_remove_dcb(dcb); if (dcb->state == DCB_STATE_POLLING)
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); rc = poll_remove_dcb(dcb);
}
dcb_call_callback(dcb, DCB_REASON_CLOSE);
if (rc == 0) { if (rc == 0) {
LOGIF(LD, (skygw_log_write( LOGIF(LD, (skygw_log_write(
@ -1170,6 +1161,18 @@ dcb_close(DCB *dcb)
dcb, dcb,
STRDCBSTATE(dcb->state)))); 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) if (dcb->state == DCB_STATE_NOPOLLING)
{ {

View File

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

View File

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

View File

@ -815,21 +815,33 @@ clientReply(
* @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION
* *
*/ */
static void static void handleError(
handleError(
ROUTER *instance, ROUTER *instance,
void *router_session, void *router_session,
GWBUF *errbuf, GWBUF *errbuf,
DCB *backend_dcb, DCB *backend_dcb,
error_action_t action, error_action_t action,
bool *succp) bool *succp)
{ {
DCB *client = NULL; DCB *client_dcb;
SESSION *session = backend_dcb->session; 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 */ /** false because connection is not available anymore */
*succp = false; *succp = false;
ss_dassert(client != NULL);
} }
/** to be inline'd */ /** to be inline'd */

View File

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