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:
@ -536,6 +536,33 @@ dcb_process_victim_queue(DCB *listofdcb)
|
|||||||
while (dcb != NULL)
|
while (dcb != NULL)
|
||||||
{
|
{
|
||||||
DCB *nextdcb = 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)
|
if (dcb->fd > 0)
|
||||||
{
|
{
|
||||||
/*<
|
/*<
|
||||||
@ -1794,11 +1821,6 @@ dcb_close(DCB *dcb)
|
|||||||
dcb,
|
dcb,
|
||||||
dcb ? STRDCBSTATE(dcb->state) : "Invalid DCB")));
|
dcb ? STRDCBSTATE(dcb->state) : "Invalid DCB")));
|
||||||
|
|
||||||
if (DCB_STATE_ZOMBIE == dcb->state)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DCB_STATE_UNDEFINED == dcb->state
|
if (DCB_STATE_UNDEFINED == dcb->state
|
||||||
|| DCB_STATE_DISCONNECTED == dcb->state)
|
|| DCB_STATE_DISCONNECTED == dcb->state)
|
||||||
{
|
{
|
||||||
@ -1822,43 +1844,21 @@ dcb_close(DCB *dcb)
|
|||||||
return;
|
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);
|
spinlock_acquire(&zombiespin);
|
||||||
if (dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ALLOC)
|
if (dcb->dcb_is_zombie)
|
||||||
{
|
{
|
||||||
/*<
|
return;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
/*<
|
||||||
|
* 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);
|
spinlock_release(&zombiespin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1889,6 +1889,7 @@ dcb_maybe_add_persistent(DCB *dcb)
|
|||||||
pthread_self(),
|
pthread_self(),
|
||||||
user)));
|
user)));
|
||||||
dcb->user = strdup(user);
|
dcb->user = strdup(user);
|
||||||
|
dcb->dcb_is_zombie = false;
|
||||||
dcb->persistentstart = time(NULL);
|
dcb->persistentstart = time(NULL);
|
||||||
session_unlink_dcb(dcb->session, dcb);
|
session_unlink_dcb(dcb->session, dcb);
|
||||||
spinlock_acquire(&dcb->server->persistlock);
|
spinlock_acquire(&dcb->server->persistlock);
|
||||||
|
|||||||
@ -353,7 +353,6 @@ session_free(SESSION *session)
|
|||||||
if (atomic_add(&session->refcount, -1) - 1)
|
if (atomic_add(&session->refcount, -1) - 1)
|
||||||
{
|
{
|
||||||
/* Must be one or more references left */
|
/* Must be one or more references left */
|
||||||
ss_dassert(nlink > 0);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
session->state = SESSION_STATE_TO_BE_FREED;
|
session->state = SESSION_STATE_TO_BE_FREED;
|
||||||
|
|||||||
@ -227,6 +227,7 @@ typedef struct dcb_callback {
|
|||||||
typedef struct dcb {
|
typedef struct dcb {
|
||||||
skygw_chk_t dcb_chk_top;
|
skygw_chk_t dcb_chk_top;
|
||||||
bool dcb_errhandle_called; /*< this can be called only once */
|
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;
|
dcb_role_t dcb_role;
|
||||||
SPINLOCK dcb_initlock;
|
SPINLOCK dcb_initlock;
|
||||||
DCBEVENTQ evq; /**< The event queue for this DCB */
|
DCBEVENTQ evq; /**< The event queue for this DCB */
|
||||||
|
|||||||
Reference in New Issue
Block a user