Move removal of closing DCB from poll list to the kill zombies processing, rather than immediately on close; modify persistent connections to obtain candidates for the pool from the kill zombies processing to be sure that they really are finished all previous processing.

This commit is contained in:
counterpoint
2015-08-24 16:19:25 +01:00
parent 37ac158791
commit 65c42e2d80
3 changed files with 41 additions and 40 deletions

View File

@ -536,6 +536,33 @@ dcb_process_victim_queue(DCB *listofdcb)
while (dcb != NULL)
{
DCB *nextdcb = NULL;
/*<
* Stop dcb's listening and modify state accordingly.
*/
if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING)
{
if (dcb->state == DCB_STATE_LISTENING)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"%lu [%s] Error : Removing DCB %p but was in state %s "
"which is not expected for a call to dcb_close, although it"
"should be processed correctly. ",
pthread_self(),
__func__,
dcb,
STRDCBSTATE(dcb->state))));
}
if ((dcb->state == DCB_STATE_POLLING && !dcb_maybe_add_persistent(dcb))
|| (dcb->state == DCB_STATE_LISTENING))
{
dcb_close_finish(dcb);
}
}
/* If DCB was put into persistent queue, will no longer be flagged zombie */
if (!dcb->dcb_is_zombie) continue;
if (dcb->fd > 0)
{
/*<
@ -1794,11 +1821,6 @@ dcb_close(DCB *dcb)
dcb,
dcb ? STRDCBSTATE(dcb->state) : "Invalid DCB")));
if (DCB_STATE_ZOMBIE == dcb->state)
{
return;
}
if (DCB_STATE_UNDEFINED == dcb->state
|| DCB_STATE_DISCONNECTED == dcb->state)
{
@ -1822,43 +1844,21 @@ dcb_close(DCB *dcb)
return;
}
/*<
* Stop dcb's listening and modify state accordingly.
*/
if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING)
{
if (dcb->state == DCB_STATE_LISTENING)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"%lu [dcb_close] Error : Removing DCB %p but was in state %s "
"which is not expected for a call to dcb_close, although it"
"should be processed correctly. ",
pthread_self(),
dcb,
STRDCBSTATE(dcb->state))));
}
if ((dcb->state == DCB_STATE_POLLING && !dcb_maybe_add_persistent(dcb))
|| (dcb->state == DCB_STATE_LISTENING))
{
dcb_close_finish(dcb);
}
}
spinlock_acquire(&zombiespin);
if (dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ALLOC)
if (dcb->dcb_is_zombie)
{
/*<
* Add closing dcb to the top of the list.
*/
dcb->memdata.next = zombies;
zombies = dcb;
/*<
* Set state which indicates that it has been added to zombies
* list.
*/
dcb->state = DCB_STATE_ZOMBIE;
return;
}
/*<
* Add closing dcb to the top of the list.
*/
dcb->dcb_is_zombie = true;
dcb->memdata.next = zombies;
zombies = dcb;
/*<
* Set state which indicates that it has been added to zombies
* list.
*/
spinlock_release(&zombiespin);
}
@ -1889,6 +1889,7 @@ dcb_maybe_add_persistent(DCB *dcb)
pthread_self(),
user)));
dcb->user = strdup(user);
dcb->dcb_is_zombie = false;
dcb->persistentstart = time(NULL);
session_unlink_dcb(dcb->session, dcb);
spinlock_acquire(&dcb->server->persistlock);

View File

@ -353,7 +353,6 @@ session_free(SESSION *session)
if (atomic_add(&session->refcount, -1) - 1)
{
/* Must be one or more references left */
ss_dassert(nlink > 0);
return false;
}
session->state = SESSION_STATE_TO_BE_FREED;

View File

@ -227,6 +227,7 @@ typedef struct dcb_callback {
typedef struct dcb {
skygw_chk_t dcb_chk_top;
bool dcb_errhandle_called; /*< this can be called only once */
bool dcb_is_zombie; /**< Whether the DCB is in the zombie list */
dcb_role_t dcb_role;
SPINLOCK dcb_initlock;
DCBEVENTQ evq; /**< The event queue for this DCB */