MXS-1929: Close listener DCBs
When a service is freed, it will free all of its listeners causing their respective DCBs to be closed. This requires that listeners can be removed from the worker DCB list.
This commit is contained in:
parent
b93eaf6fb2
commit
23d944b82e
@ -2804,49 +2804,46 @@ static void dcb_add_to_list(DCB *dcb)
|
||||
*/
|
||||
static void dcb_remove_from_list(DCB *dcb)
|
||||
{
|
||||
if (dcb->dcb_role != DCB_ROLE_SERVICE_LISTENER)
|
||||
int id = static_cast<RoutingWorker*>(dcb->poll.owner)->id();
|
||||
|
||||
if (dcb == this_unit.all_dcbs[id])
|
||||
{
|
||||
int id = static_cast<RoutingWorker*>(dcb->poll.owner)->id();
|
||||
DCB *tail = this_unit.all_dcbs[id]->thread.tail;
|
||||
this_unit.all_dcbs[id] = this_unit.all_dcbs[id]->thread.next;
|
||||
|
||||
if (dcb == this_unit.all_dcbs[id])
|
||||
if (this_unit.all_dcbs[id])
|
||||
{
|
||||
DCB *tail = this_unit.all_dcbs[id]->thread.tail;
|
||||
this_unit.all_dcbs[id] = this_unit.all_dcbs[id]->thread.next;
|
||||
|
||||
if (this_unit.all_dcbs[id])
|
||||
{
|
||||
this_unit.all_dcbs[id]->thread.tail = tail;
|
||||
}
|
||||
this_unit.all_dcbs[id]->thread.tail = tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the creation of the DCB failed, it will not have been added
|
||||
// to the list at all. And if it happened to be the first DCB to be
|
||||
// created, then `prev` is NULL at this point.
|
||||
DCB *prev = this_unit.all_dcbs[id];
|
||||
DCB *current = prev ? prev->thread.next : NULL;
|
||||
|
||||
while (current)
|
||||
{
|
||||
if (current == dcb)
|
||||
{
|
||||
if (current == this_unit.all_dcbs[id]->thread.tail)
|
||||
{
|
||||
this_unit.all_dcbs[id]->thread.tail = prev;
|
||||
}
|
||||
prev->thread.next = current->thread.next;
|
||||
break;
|
||||
}
|
||||
prev = current;
|
||||
current = current->thread.next;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reset the next and tail pointers so that if this DCB is added to the list
|
||||
* again, it will be in a clean state. */
|
||||
dcb->thread.next = NULL;
|
||||
dcb->thread.tail = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the creation of the DCB failed, it will not have been added
|
||||
// to the list at all. And if it happened to be the first DCB to be
|
||||
// created, then `prev` is NULL at this point.
|
||||
DCB *prev = this_unit.all_dcbs[id];
|
||||
DCB *current = prev ? prev->thread.next : NULL;
|
||||
|
||||
while (current)
|
||||
{
|
||||
if (current == dcb)
|
||||
{
|
||||
if (current == this_unit.all_dcbs[id]->thread.tail)
|
||||
{
|
||||
this_unit.all_dcbs[id]->thread.tail = prev;
|
||||
}
|
||||
prev->thread.next = current->thread.next;
|
||||
break;
|
||||
}
|
||||
prev = current;
|
||||
current = current->thread.next;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reset the next and tail pointers so that if this DCB is added to the list
|
||||
* again, it will be in a clean state. */
|
||||
dcb->thread.next = NULL;
|
||||
dcb->thread.tail = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,6 +154,12 @@ void listener_free(SERV_LISTENER* listener)
|
||||
users_free(listener->users);
|
||||
}
|
||||
|
||||
if (listener->listener)
|
||||
{
|
||||
dcb_close(listener->listener);
|
||||
}
|
||||
|
||||
SSL_LISTENER_free(listener->ssl);
|
||||
MXS_FREE(listener->address);
|
||||
MXS_FREE(listener->authenticator);
|
||||
MXS_FREE(listener->auth_options);
|
||||
|
@ -184,6 +184,33 @@ void service_free(SERVICE* service)
|
||||
{
|
||||
ss_dassert(atomic_load_int(&service->client_count) == 0);
|
||||
|
||||
spinlock_acquire(&service_spin);
|
||||
|
||||
if (service == allServices)
|
||||
{
|
||||
allServices = allServices->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (SERVICE* s = allServices; s; s = s->next)
|
||||
{
|
||||
if (s->next == service)
|
||||
{
|
||||
s->next = service->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&service_spin);
|
||||
|
||||
while (service->ports)
|
||||
{
|
||||
auto tmp = service->ports;
|
||||
service->ports = service->ports->next;
|
||||
listener_free(tmp);
|
||||
}
|
||||
|
||||
if (service->router && service->router_instance)
|
||||
{
|
||||
service->router->destroyInstance(service->router_instance);
|
||||
|
Loading…
x
Reference in New Issue
Block a user