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
|
||||
* to create dummy clients based on real clients.
|
||||
@ -600,7 +556,6 @@ bool succp = false;
|
||||
&tls_log_info.li_enabled_logs)));
|
||||
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
ss_dassert(succp);
|
||||
dcb_next = dcb->memdata.next;
|
||||
dcb_final_free(dcb);
|
||||
dcb = dcb_next;
|
||||
@ -1928,72 +1883,91 @@ dcb_drain_writeq_SSL(DCB *dcb)
|
||||
void
|
||||
dcb_close(DCB *dcb)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc = 0;
|
||||
|
||||
CHK_DCB(dcb);
|
||||
CHK_DCB(dcb);
|
||||
|
||||
LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG,
|
||||
"%lu [dcb_close]",
|
||||
pthread_self())));
|
||||
|
||||
/**
|
||||
* dcb_close may be called for freshly created dcb, in which case
|
||||
* it only needs to be freed.
|
||||
*/
|
||||
if (dcb->state == DCB_STATE_ALLOC)
|
||||
LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG,
|
||||
"%lu [dcb_close]",
|
||||
pthread_self())));
|
||||
|
||||
if (DCB_STATE_UNDEFINED == dcb->state
|
||||
|| DCB_STATE_DISCONNECTED == dcb->state
|
||||
|| DCB_STATE_ZOMBIE == dcb->state)
|
||||
{
|
||||
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);
|
||||
return;
|
||||
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))));
|
||||
}
|
||||
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 ||
|
||||
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);
|
||||
}
|
||||
spinlock_release(&zombiespin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -302,10 +302,6 @@ poll_add_dcb(DCB *dcb)
|
||||
dcb,
|
||||
STRDCBSTATE(dcb->state))));
|
||||
}
|
||||
/*<
|
||||
* If dcb is in unexpected state, state change fails indicating that dcb
|
||||
* is not polling anymore.
|
||||
*/
|
||||
dcb->state = new_state;
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
/*
|
||||
|
||||
@ -64,7 +64,7 @@ int buflen;
|
||||
ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid");
|
||||
ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie");
|
||||
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_dfprintf(stderr, "\t..done\nProcess the zombies list");
|
||||
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 */
|
||||
int dcb_isclient(DCB *); /* the DCB is the client of the session */
|
||||
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 *),
|
||||
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);
|
||||
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
|
||||
|
||||
if (client_dcb == NULL)
|
||||
|
||||
{
|
||||
close(so);
|
||||
return n_connect;
|
||||
@ -283,7 +281,8 @@ int n_connect = 0;
|
||||
if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL)
|
||||
{
|
||||
client_dcb->protocol = NULL;
|
||||
dcb_add_to_zombieslist(client_dcb);
|
||||
close(so);
|
||||
dcb_close(client_dcb);
|
||||
return n_connect;
|
||||
}
|
||||
maxscaled_pr->username = NULL;
|
||||
@ -293,9 +292,9 @@ int n_connect = 0;
|
||||
client_dcb->session =
|
||||
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;
|
||||
}
|
||||
n_connect++;
|
||||
|
||||
@ -315,13 +315,13 @@ int n_connect = 0;
|
||||
|
||||
if (telnetd_pr == NULL)
|
||||
{
|
||||
dcb_add_to_zombieslist(client_dcb);
|
||||
dcb_close(client_dcb);
|
||||
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;
|
||||
}
|
||||
n_connect++;
|
||||
|
||||
Reference in New Issue
Block a user