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,
 | 
					        const dcb_state_t new_state,
 | 
				
			||||||
        dcb_state_t*      old_state);
 | 
					        dcb_state_t*      old_state);
 | 
				
			||||||
static void dcb_call_callback(DCB *dcb, DCB_REASON reason);
 | 
					static void dcb_call_callback(DCB *dcb, DCB_REASON reason);
 | 
				
			||||||
 | 
					static DCB* dcb_get_next (DCB* dcb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DCB* dcb_get_zombies(void)
 | 
					DCB* dcb_get_zombies(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1728,6 +1729,41 @@ int	rval = 0;
 | 
				
			|||||||
	return rval;
 | 
						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 (
 | 
					void dcb_call_foreach (
 | 
				
			||||||
        SERVER* srv,
 | 
					        SERVER* srv,
 | 
				
			||||||
        DCB_REASON reason)
 | 
					        DCB_REASON reason)
 | 
				
			||||||
@ -1742,16 +1778,16 @@ void dcb_call_foreach (
 | 
				
			|||||||
                case DCB_REASON_NOT_RESPONDING: 
 | 
					                case DCB_REASON_NOT_RESPONDING: 
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                        DCB* dcb;
 | 
					                        DCB* dcb;
 | 
				
			||||||
 | 
					                        dcb = dcb_get_next(NULL);
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
                        spinlock_acquire(&dcbspin);
 | 
					                        while (dcb != NULL)
 | 
				
			||||||
                        
 | 
					 | 
				
			||||||
                        dcb = allDCBs;
 | 
					 | 
				
			||||||
                        while (dcb)
 | 
					 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                                dcb_call_callback(dcb, DCB_REASON_NOT_RESPONDING);
 | 
					                                if (dcb->state == DCB_STATE_POLLING)
 | 
				
			||||||
                                dcb = dcb->next;
 | 
					                                {
 | 
				
			||||||
 | 
					                                        dcb_call_callback(dcb, DCB_REASON_NOT_RESPONDING);
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                dcb = dcb_get_next(dcb);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        spinlock_release(&dcbspin);
 | 
					 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
 | 
				
			|||||||
@ -887,7 +887,56 @@ return_fd:
 | 
				
			|||||||
static int
 | 
					static int
 | 
				
			||||||
gw_backend_hangup(DCB *dcb)
 | 
					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;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -813,7 +813,7 @@ static bool get_dcb(
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                        backend_ref = rses->rses_master_ref;
 | 
					                        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;
 | 
					                                *p_dcb = backend_ref->bref_dcb;
 | 
				
			||||||
                                succp = true;
 | 
					                                succp = true;
 | 
				
			||||||
@ -2765,7 +2765,6 @@ static int router_handle_state_switch(
 | 
				
			|||||||
                case DCB_REASON_NOT_RESPONDING:
 | 
					                case DCB_REASON_NOT_RESPONDING:
 | 
				
			||||||
                        if (BREF_IS_WAITING_RESULT(bref))
 | 
					                        if (BREF_IS_WAITING_RESULT(bref))
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                                printf("foo");
 | 
					 | 
				
			||||||
                                dcb->func.hangup(dcb);
 | 
					                                dcb->func.hangup(dcb);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user