Merge branch 'release-1.0beta-refresh' of github.com:skysql/MaxScale into release-1.0beta-refresh

This commit is contained in:
Mark Riddoch
2014-09-19 08:03:16 +01:00
4 changed files with 34 additions and 15 deletions

View File

@ -403,18 +403,20 @@ DCB_CALLBACK *cb;
* operation of clearing this bit means that no bits are set in * operation of clearing this bit means that no bits are set in
* the memdata.bitmask then the DCB is no longer able to be * the memdata.bitmask then the DCB is no longer able to be
* referenced and it can be finally removed. * referenced and it can be finally removed.
* Thread won't clear its bit from bitmask of the DCB it is still using.
* *
* @param threadid The thread ID of the caller * @param threadid The thread ID of the caller
* @param dcb_in_use The DCB the thread currently uses, NULL or valid DCB.
*/ */
DCB * DCB *
dcb_process_zombies(int threadid) dcb_process_zombies(int threadid, DCB *dcb_in_use)
{ {
DCB *ptr, *lptr; DCB *ptr, *lptr;
DCB* dcb_list = NULL; DCB* dcb_list = NULL;
DCB* dcb = NULL; DCB* dcb = NULL;
bool succp = false; bool succp = false;
/*< /**
* Perform a dirty read to see if there is anything in the queue. * Perform a dirty read to see if there is anything in the queue.
* This avoids threads hitting the queue spinlock when the queue * This avoids threads hitting the queue spinlock when the queue
* is empty. This will really help when the only entry is being * is empty. This will really help when the only entry is being
@ -428,11 +430,19 @@ bool succp = false;
ptr = zombies; ptr = zombies;
lptr = NULL; lptr = NULL;
while (ptr) while (ptr)
{ {
bitmask_clear(&ptr->memdata.bitmask, threadid); CHK_DCB(ptr);
/** Don't clear the bit from DCB the user currently uses */
if (dcb_in_use == NULL || ptr != dcb_in_use)
{
bitmask_clear(&ptr->memdata.bitmask, threadid);
}
if (ptr == dcb_in_use)
ss_dassert(!bitmask_isallclear(&ptr->memdata.bitmask));
if (bitmask_isallclear(&ptr->memdata.bitmask)) if (bitmask_isallclear(&ptr->memdata.bitmask))
{ {
/*< /**
* Remove the DCB from the zombie queue * Remove the DCB from the zombie queue
* and call the final free routine for the * and call the final free routine for the
* DCB * DCB
@ -480,13 +490,14 @@ bool succp = false;
spinlock_release(&zombiespin); spinlock_release(&zombiespin);
dcb = dcb_list; dcb = dcb_list;
/*< Close, and set DISCONNECTED victims */ /** Close, and set DISCONNECTED victims */
while (dcb != NULL) { while (dcb != NULL) {
DCB* dcb_next = NULL; DCB* dcb_next = NULL;
int rc = 0; int rc = 0;
/*< /*<
* Close file descriptor and move to clean-up phase. * Close file descriptor and move to clean-up phase.
*/ */
ss_dassert(dcb_in_use != dcb);
rc = close(dcb->fd); rc = close(dcb->fd);
if (rc < 0) { if (rc < 0) {
@ -1928,7 +1939,7 @@ int rval = 0;
* and instead implements a queuing mechanism in which nested events are * and instead implements a queuing mechanism in which nested events are
* queued on the DCB such that when the thread processing the first event * queued on the DCB such that when the thread processing the first event
* returns it will read the queued event and process it. This allows the * returns it will read the queued event and process it. This allows the
* thread that woudl otherwise have to wait to process the nested event * thread that would otherwise have to wait to process the nested event
* to return immediately and and process other events. * to return immediately and and process other events.
* *
* @param dcb The DCB that has data available * @param dcb The DCB that has data available
@ -1945,7 +1956,7 @@ dcb_pollin(DCB *dcb, int thread_id)
if (dcb->readcheck) if (dcb->readcheck)
{ {
dcb->stats.n_readrechecks++; dcb->stats.n_readrechecks++;
dcb_process_zombies(thread_id); dcb_process_zombies(thread_id, dcb);
} }
dcb->readcheck = 0; dcb->readcheck = 0;
spinlock_release(&dcb->pollinlock); spinlock_release(&dcb->pollinlock);
@ -1988,7 +1999,7 @@ dcb_pollout(DCB *dcb, int thread_id)
do { do {
if (dcb->writecheck) if (dcb->writecheck)
{ {
dcb_process_zombies(thread_id); dcb_process_zombies(thread_id, dcb);
dcb->stats.n_writerechecks++; dcb->stats.n_writerechecks++;
} }
dcb->writecheck = 0; dcb->writecheck = 0;

View File

@ -633,12 +633,12 @@ DCB *zombies = NULL;
} /*< for */ } /*< for */
no_op = FALSE; no_op = FALSE;
} }
process_zombies: process_zombies:
if (thread_data) if (thread_data)
{ {
thread_data[thread_id].state = THREAD_ZPROCESSING; thread_data[thread_id].state = THREAD_ZPROCESSING;
} }
zombies = dcb_process_zombies(thread_id); zombies = dcb_process_zombies(thread_id, NULL);
if (zombies == NULL) { if (zombies == NULL) {
process_zombies_only = false; process_zombies_only = false;

View File

@ -289,7 +289,7 @@ DCB *dcb_clone(DCB *);
int dcb_read(DCB *, GWBUF **); int dcb_read(DCB *, GWBUF **);
int dcb_drain_writeq(DCB *); int dcb_drain_writeq(DCB *);
void dcb_close(DCB *); void dcb_close(DCB *);
DCB *dcb_process_zombies(int); /* Process Zombies */ DCB *dcb_process_zombies(int, DCB*); /* Process Zombies except the one behind the pointer */
void printAllDCBs(); /* Debug to print all DCB in the system */ void printAllDCBs(); /* Debug to print all DCB in the system */
void printDCB(DCB *); /* Debug print routine */ void printDCB(DCB *); /* Debug print routine */
void dprintAllDCBs(DCB *); /* Debug to print all DCB in the system */ void dprintAllDCBs(DCB *); /* Debug to print all DCB in the system */

View File

@ -1674,7 +1674,6 @@ static int routeQuery(
{ {
rses_is_closed = true; rses_is_closed = true;
} }
ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(querybuf)); ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(querybuf));
packet = GWBUF_DATA(querybuf); packet = GWBUF_DATA(querybuf);
@ -1702,7 +1701,6 @@ static int routeQuery(
(rses_is_closed ? "Router was closed" : (rses_is_closed ? "Router was closed" :
"Router has no backend servers where to " "Router has no backend servers where to "
"route to")))); "route to"))));
free(querybuf);
} }
goto retblock; goto retblock;
} }
@ -2195,7 +2193,17 @@ static void clientReply (
goto lock_failed; goto lock_failed;
} }
bref = get_bref_from_dcb(router_cli_ses, backend_dcb); bref = get_bref_from_dcb(router_cli_ses, backend_dcb);
#if !defined(FOR_BUG548_FIX_ONLY)
/** This makes the issue becoming visible in poll.c */
if (bref == NULL)
{
/** Unlock router session */
rses_end_locked_router_action(router_cli_ses);
goto lock_failed;
}
#endif
CHK_BACKEND_REF(bref); CHK_BACKEND_REF(bref);
scur = &bref->bref_sescmd_cur; scur = &bref->bref_sescmd_cur;
/** /**