Unify DCB close processing to single function dcb_close. Remove dcb_add_to_zombieslist (incorporating logic into dcb_close). Alter logic so that DCB that is just allocated will still go to zombie list if dcb->fd is not closed.
This commit is contained in:
@ -248,50 +248,6 @@ dcb_free(DCB *dcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the DCB to the end of zombies list.
|
|
||||||
*
|
|
||||||
* Adding to list occurs once per DCB. This is ensured by changing the
|
|
||||||
* state of DCB to DCB_STATE_ZOMBIE after addition. Prior insertion, DCB state
|
|
||||||
* is checked and operation proceeds only if state differs from DCB_STATE_ZOMBIE.
|
|
||||||
* @param dcb The DCB to add to the zombie list
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
dcb_add_to_zombieslist(DCB *dcb)
|
|
||||||
{
|
|
||||||
bool succp = false;
|
|
||||||
dcb_state_t prev_state = DCB_STATE_UNDEFINED;
|
|
||||||
|
|
||||||
CHK_DCB(dcb);
|
|
||||||
|
|
||||||
/*<
|
|
||||||
* Protect zombies list access.
|
|
||||||
*/
|
|
||||||
spinlock_acquire(&zombiespin);
|
|
||||||
/*<
|
|
||||||
* If dcb is already added to zombies list, return.
|
|
||||||
*/
|
|
||||||
if (dcb->state != DCB_STATE_NOPOLLING) {
|
|
||||||
ss_dassert(dcb->state != DCB_STATE_POLLING &&
|
|
||||||
dcb->state != DCB_STATE_LISTENING);
|
|
||||||
spinlock_release(&zombiespin);
|
|
||||||
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;
|
|
||||||
|
|
||||||
spinlock_release(&zombiespin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clone a DCB for internal use, mostly used for specialist filters
|
* Clone a DCB for internal use, mostly used for specialist filters
|
||||||
* to create dummy clients based on real clients.
|
* to create dummy clients based on real clients.
|
||||||
@ -600,7 +556,6 @@ bool succp = false;
|
|||||||
&tls_log_info.li_enabled_logs)));
|
&tls_log_info.li_enabled_logs)));
|
||||||
|
|
||||||
dcb->state = DCB_STATE_DISCONNECTED;
|
dcb->state = DCB_STATE_DISCONNECTED;
|
||||||
ss_dassert(succp);
|
|
||||||
dcb_next = dcb->memdata.next;
|
dcb_next = dcb->memdata.next;
|
||||||
dcb_final_free(dcb);
|
dcb_final_free(dcb);
|
||||||
dcb = dcb_next;
|
dcb = dcb_next;
|
||||||
@ -1928,72 +1883,91 @@ dcb_drain_writeq_SSL(DCB *dcb)
|
|||||||
void
|
void
|
||||||
dcb_close(DCB *dcb)
|
dcb_close(DCB *dcb)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
CHK_DCB(dcb);
|
CHK_DCB(dcb);
|
||||||
|
|
||||||
LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG,
|
LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG,
|
||||||
"%lu [dcb_close]",
|
"%lu [dcb_close]",
|
||||||
pthread_self())));
|
pthread_self())));
|
||||||
|
|
||||||
/**
|
if (DCB_STATE_UNDEFINED == dcb->state
|
||||||
* dcb_close may be called for freshly created dcb, in which case
|
|| DCB_STATE_DISCONNECTED == dcb->state
|
||||||
* it only needs to be freed.
|
|| DCB_STATE_ZOMBIE == dcb->state)
|
||||||
*/
|
{
|
||||||
if (dcb->state == DCB_STATE_ALLOC)
|
LOGIF(LE, (skygw_log_write(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"%lu [dcb_close] Error : Removing DCB %p but was in state %s "
|
||||||
|
"which is not legal for a call to dcb_close. ",
|
||||||
|
pthread_self(),
|
||||||
|
dcb,
|
||||||
|
STRDCBSTATE(dcb->state))));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dcb_close may be called for freshly created dcb, in which case
|
||||||
|
* it only needs to be freed.
|
||||||
|
*/
|
||||||
|
if (dcb->state == DCB_STATE_ALLOC && dcb->fd != DCBFD_CLOSED)
|
||||||
|
{
|
||||||
|
dcb_final_free(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)
|
||||||
{
|
{
|
||||||
dcb_final_free(dcb);
|
LOGIF(LE, (skygw_log_write(
|
||||||
return;
|
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))));
|
||||||
}
|
}
|
||||||
|
rc = poll_remove_dcb(dcb);
|
||||||
|
/*
|
||||||
|
* Return will always be 0 or function will have crashed
|
||||||
|
*/
|
||||||
|
LOGIF(LD, (skygw_log_write(
|
||||||
|
LOGFILE_DEBUG,
|
||||||
|
"%lu [dcb_close] Removed dcb %p in state %s from "
|
||||||
|
"poll set.",
|
||||||
|
pthread_self(),
|
||||||
|
dcb,
|
||||||
|
STRDCBSTATE(dcb->state))));
|
||||||
|
/**
|
||||||
|
* close protocol and router session
|
||||||
|
*/
|
||||||
|
if (dcb->func.close != NULL)
|
||||||
|
{
|
||||||
|
dcb->func.close(dcb);
|
||||||
|
}
|
||||||
|
/** Call possible callback for this DCB in case of close */
|
||||||
|
dcb_call_callback(dcb, DCB_REASON_CLOSE);
|
||||||
|
}
|
||||||
|
assert (dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ALLOC);
|
||||||
|
|
||||||
|
spinlock_acquire(&zombiespin);
|
||||||
|
|
||||||
|
/*<
|
||||||
|
* 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;
|
||||||
|
|
||||||
ss_dassert(dcb->state == DCB_STATE_POLLING ||
|
spinlock_release(&zombiespin);
|
||||||
dcb->state == DCB_STATE_NOPOLLING ||
|
|
||||||
dcb->state == DCB_STATE_ZOMBIE);
|
|
||||||
|
|
||||||
/*<
|
|
||||||
* Stop dcb's listening and modify state accordingly.
|
|
||||||
*/
|
|
||||||
if (dcb->state == DCB_STATE_POLLING)
|
|
||||||
{
|
|
||||||
rc = poll_remove_dcb(dcb);
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
LOGIF(LD, (skygw_log_write(
|
|
||||||
LOGFILE_DEBUG,
|
|
||||||
"%lu [dcb_close] Removed dcb %p in state %s from "
|
|
||||||
"poll set.",
|
|
||||||
pthread_self(),
|
|
||||||
dcb,
|
|
||||||
STRDCBSTATE(dcb->state))));
|
|
||||||
} else {
|
|
||||||
LOGIF(LE, (skygw_log_write(
|
|
||||||
LOGFILE_ERROR,
|
|
||||||
"Error : Removing DCB fd == %d in state %s from "
|
|
||||||
"poll set failed.",
|
|
||||||
dcb->fd,
|
|
||||||
STRDCBSTATE(dcb->state))));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc == 0)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* close protocol and router session
|
|
||||||
*/
|
|
||||||
if (dcb->func.close != NULL)
|
|
||||||
{
|
|
||||||
dcb->func.close(dcb);
|
|
||||||
}
|
|
||||||
/** Call possible callback for this DCB in case of close */
|
|
||||||
dcb_call_callback(dcb, DCB_REASON_CLOSE);
|
|
||||||
|
|
||||||
if (dcb->state == DCB_STATE_NOPOLLING)
|
|
||||||
{
|
|
||||||
dcb_add_to_zombieslist(dcb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ss_dassert(dcb->state == DCB_STATE_NOPOLLING ||
|
|
||||||
dcb->state == DCB_STATE_ZOMBIE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -302,10 +302,6 @@ poll_add_dcb(DCB *dcb)
|
|||||||
dcb,
|
dcb,
|
||||||
STRDCBSTATE(dcb->state))));
|
STRDCBSTATE(dcb->state))));
|
||||||
}
|
}
|
||||||
/*<
|
|
||||||
* If dcb is in unexpected state, state change fails indicating that dcb
|
|
||||||
* is not polling anymore.
|
|
||||||
*/
|
|
||||||
dcb->state = new_state;
|
dcb->state = new_state;
|
||||||
spinlock_release(&dcb->dcb_initlock);
|
spinlock_release(&dcb->dcb_initlock);
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -64,7 +64,7 @@ int buflen;
|
|||||||
ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid");
|
ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid");
|
||||||
ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie");
|
ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie");
|
||||||
clone->state = DCB_STATE_NOPOLLING;
|
clone->state = DCB_STATE_NOPOLLING;
|
||||||
dcb_add_to_zombieslist(clone);
|
dcb_close(clone);
|
||||||
ss_info_dassert(dcb_get_zombies() == clone, "Clone DCB must be start of zombie list now");
|
ss_info_dassert(dcb_get_zombies() == clone, "Clone DCB must be start of zombie list now");
|
||||||
ss_dfprintf(stderr, "\t..done\nProcess the zombies list");
|
ss_dfprintf(stderr, "\t..done\nProcess the zombies list");
|
||||||
dcb_process_zombies(0);
|
dcb_process_zombies(0);
|
||||||
|
|||||||
@ -330,7 +330,6 @@ const char *gw_dcb_state2string(int); /* DCB state to string */
|
|||||||
void dcb_printf(DCB *, const char *, ...); /* DCB version of printf */
|
void dcb_printf(DCB *, const char *, ...); /* DCB version of printf */
|
||||||
int dcb_isclient(DCB *); /* the DCB is the client of the session */
|
int dcb_isclient(DCB *); /* the DCB is the client of the session */
|
||||||
void dcb_hashtable_stats(DCB *, void *); /**< Print statisitics */
|
void dcb_hashtable_stats(DCB *, void *); /**< Print statisitics */
|
||||||
void dcb_add_to_zombieslist(DCB* dcb);
|
|
||||||
int dcb_add_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *),
|
int dcb_add_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *),
|
||||||
void *);
|
void *);
|
||||||
int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *),
|
int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, void *),
|
||||||
|
|||||||
@ -270,9 +270,7 @@ int n_connect = 0;
|
|||||||
{
|
{
|
||||||
atomic_add(&dcb->stats.n_accepts, 1);
|
atomic_add(&dcb->stats.n_accepts, 1);
|
||||||
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
|
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
|
||||||
|
|
||||||
if (client_dcb == NULL)
|
if (client_dcb == NULL)
|
||||||
|
|
||||||
{
|
{
|
||||||
close(so);
|
close(so);
|
||||||
return n_connect;
|
return n_connect;
|
||||||
@ -283,7 +281,8 @@ int n_connect = 0;
|
|||||||
if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL)
|
if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL)
|
||||||
{
|
{
|
||||||
client_dcb->protocol = NULL;
|
client_dcb->protocol = NULL;
|
||||||
dcb_add_to_zombieslist(client_dcb);
|
close(so);
|
||||||
|
dcb_close(client_dcb);
|
||||||
return n_connect;
|
return n_connect;
|
||||||
}
|
}
|
||||||
maxscaled_pr->username = NULL;
|
maxscaled_pr->username = NULL;
|
||||||
@ -293,9 +292,9 @@ int n_connect = 0;
|
|||||||
client_dcb->session =
|
client_dcb->session =
|
||||||
session_alloc(dcb->session->service, client_dcb);
|
session_alloc(dcb->session->service, client_dcb);
|
||||||
|
|
||||||
if (poll_add_dcb(client_dcb) == -1)
|
if (poll_add_dcb(client_dcb))
|
||||||
{
|
{
|
||||||
dcb_add_to_zombieslist(dcb);
|
dcb_close(dcb);
|
||||||
return n_connect;
|
return n_connect;
|
||||||
}
|
}
|
||||||
n_connect++;
|
n_connect++;
|
||||||
|
|||||||
@ -315,13 +315,13 @@ int n_connect = 0;
|
|||||||
|
|
||||||
if (telnetd_pr == NULL)
|
if (telnetd_pr == NULL)
|
||||||
{
|
{
|
||||||
dcb_add_to_zombieslist(client_dcb);
|
dcb_close(client_dcb);
|
||||||
return n_connect;
|
return n_connect;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll_add_dcb(client_dcb) == -1)
|
if (poll_add_dcb(client_dcb))
|
||||||
{
|
{
|
||||||
dcb_add_to_zombieslist(dcb);
|
dcb_close(dcb);
|
||||||
return n_connect;
|
return n_connect;
|
||||||
}
|
}
|
||||||
n_connect++;
|
n_connect++;
|
||||||
|
|||||||
Reference in New Issue
Block a user