Modified dcb_call_foreach so that it doesn't hold spinlock (dcbspin) continuously because it caused deadlock when new slaves were tried to connect with.

Fixed a few smallish things.
This commit is contained in:
VilhoRaatikka 2014-06-13 14:52:04 +03:00
parent dfc9141a38
commit 09d20d1059
3 changed files with 94 additions and 10 deletions

View File

@ -83,6 +83,7 @@ static bool dcb_set_state_nomutex(
const dcb_state_t new_state,
dcb_state_t* old_state);
static void dcb_call_callback(DCB *dcb, DCB_REASON reason);
static DCB* dcb_get_next (DCB* dcb);
DCB* dcb_get_zombies(void)
{
@ -1728,6 +1729,41 @@ int rval = 0;
return rval;
}
static DCB* dcb_get_next (
DCB* dcb)
{
DCB* p;
spinlock_acquire(&dcbspin);
p = allDCBs;
if (dcb == NULL || p == NULL)
{
dcb = p;
}
else
{
while (p != NULL && dcb != p)
{
p = p->next;
}
if (p != NULL)
{
dcb = p->next;
}
else
{
dcb = NULL;
}
}
spinlock_release(&dcbspin);
return dcb;
}
void dcb_call_foreach (
SERVER* srv,
DCB_REASON reason)
@ -1742,16 +1778,16 @@ void dcb_call_foreach (
case DCB_REASON_NOT_RESPONDING:
{
DCB* dcb;
dcb = dcb_get_next(NULL);
spinlock_acquire(&dcbspin);
dcb = allDCBs;
while (dcb)
while (dcb != NULL)
{
dcb_call_callback(dcb, DCB_REASON_NOT_RESPONDING);
dcb = dcb->next;
if (dcb->state == DCB_STATE_POLLING)
{
dcb_call_callback(dcb, DCB_REASON_NOT_RESPONDING);
}
dcb = dcb_get_next(dcb);
}
spinlock_release(&dcbspin);
break;
}

View File

@ -887,7 +887,56 @@ return_fd:
static int
gw_backend_hangup(DCB *dcb)
{
/*< vraa : errorHandle */
SESSION* session;
void* rsession;
ROUTER_OBJECT* router;
ROUTER* router_instance;
int rc = 0;
bool succp;
CHK_DCB(dcb);
session = dcb->session;
CHK_SESSION(session);
rsession = session->router_session;
router = session->service->router;
router_instance = session->service->router_instance;
mysql_send_custom_error(
dcb->session->client,
1,
0,
"Lost connection to backend server.");
/**
* errorHandle :
* - sulje katkennut yhteys - miten?
* - etsi riittävä määrä servereitä
* - jos epäonnistui, sammuta sessio
* - jos onnistui, jatka
*
* Jos sammutetaan :
* - dcb_close - backend->func.close()
*/
/*< vraa : errorHandle */
/*
*
- lähetä virheviesti clientille jos odottaa
errorHandle :
- etsi riittävä määrä servereitä
- jos epäonnistui, sammuta sessio
- jos onnistui, jatka
*/
router->handleError(router_instance,
rsession,
"Lost connection to backend server",
dcb,
ERRACT_NEW_CONNECTION,
&succp);
if (succp) {
dcb_close(dcb);
}
return 1;
}

View File

@ -813,7 +813,7 @@ static bool get_dcb(
{
backend_ref = rses->rses_master_ref;
if (BREF_IS_IN_USE((&backend_ref[i])))
if (BREF_IS_IN_USE(backend_ref))
{
*p_dcb = backend_ref->bref_dcb;
succp = true;
@ -2765,7 +2765,6 @@ static int router_handle_state_switch(
case DCB_REASON_NOT_RESPONDING:
if (BREF_IS_WAITING_RESULT(bref))
{
printf("foo");
dcb->func.hangup(dcb);
}
break;