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:
		@ -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)
 | 
			
		||||
                        {
 | 
			
		||||
                                if (dcb->state == DCB_STATE_POLLING)
 | 
			
		||||
                                {
 | 
			
		||||
                                        dcb_call_callback(dcb, DCB_REASON_NOT_RESPONDING);
 | 
			
		||||
                                dcb = dcb->next;
 | 
			
		||||
                                }
 | 
			
		||||
                        spinlock_release(&dcbspin);
 | 
			
		||||
                                dcb = dcb_get_next(dcb);
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
@ -887,7 +887,56 @@ return_fd:
 | 
			
		||||
static int
 | 
			
		||||
gw_backend_hangup(DCB *dcb)
 | 
			
		||||
{
 | 
			
		||||
        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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user