MXS-1582 Close listener sockets on exit
If the listener socket refers to a Unix domain socket, the socket file will be deleted as well.
This commit is contained in:
parent
6f3a580168
commit
140620a366
@ -182,6 +182,7 @@ typedef struct dcb
|
||||
struct dcb *tail; /**< Last DCB in owning thread's list */
|
||||
} thread;
|
||||
uint32_t n_close; /** How many times dcb_close has been called. */
|
||||
char *path; /** If a Unix socket, the path it was bound to. */
|
||||
skygw_chk_t dcb_chk_tail;
|
||||
} DCB;
|
||||
|
||||
|
@ -234,6 +234,7 @@ dcb_final_free(DCB *dcb)
|
||||
if (SESSION_STATE_DUMMY != local_session->state)
|
||||
{
|
||||
bool is_client_dcb = (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role ||
|
||||
DCB_ROLE_SERVICE_LISTENER == dcb->dcb_role ||
|
||||
DCB_ROLE_INTERNAL == dcb->dcb_role);
|
||||
|
||||
session_put_ref(local_session);
|
||||
@ -331,6 +332,11 @@ dcb_free_all_memory(DCB *dcb)
|
||||
SSL_free(dcb->ssl);
|
||||
}
|
||||
|
||||
if (dcb->path)
|
||||
{
|
||||
MXS_FREE(dcb->path);
|
||||
}
|
||||
|
||||
// Ensure that id is immediately the wrong one.
|
||||
dcb->poll.thread.id = 0xdeadbeef;
|
||||
MXS_FREE(dcb);
|
||||
@ -1100,10 +1106,17 @@ void dcb_close(DCB *dcb)
|
||||
{
|
||||
dcb->n_close = 1;
|
||||
|
||||
Worker* worker = Worker::get(dcb->poll.thread.id);
|
||||
ss_dassert(worker);
|
||||
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
||||
{
|
||||
dcb_final_close(dcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
Worker* worker = Worker::get(dcb->poll.thread.id);
|
||||
ss_dassert(worker);
|
||||
|
||||
worker->register_zombie(dcb);
|
||||
worker->register_zombie(dcb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1220,6 +1233,14 @@ void dcb_final_close(DCB* dcb)
|
||||
|
||||
MXS_DEBUG("Closed socket %d on dcb %p.", dcb->fd, dcb);
|
||||
}
|
||||
|
||||
if (dcb->path)
|
||||
{
|
||||
if (unlink(dcb->path) != 0)
|
||||
{
|
||||
MXS_ERROR("Could not unlink %s: %s", dcb->path, mxs_strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
@ -2560,6 +2581,11 @@ int dcb_listen(DCB *listener, const char *config, const char *protocol_name)
|
||||
if (strchr(host, '/'))
|
||||
{
|
||||
listener_socket = dcb_listen_create_socket_unix(host);
|
||||
|
||||
if (listener_socket != -1)
|
||||
{
|
||||
listener->path = MXS_STRDUP_A(host);
|
||||
}
|
||||
}
|
||||
else if (port > 0)
|
||||
{
|
||||
@ -2776,41 +2802,44 @@ void dcb_add_to_list(DCB *dcb)
|
||||
*/
|
||||
static void dcb_remove_from_list(DCB *dcb)
|
||||
{
|
||||
if (dcb == this_unit.all_dcbs[dcb->poll.thread.id])
|
||||
if (dcb->dcb_role != DCB_ROLE_SERVICE_LISTENER)
|
||||
{
|
||||
DCB *tail = this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail;
|
||||
this_unit.all_dcbs[dcb->poll.thread.id] = this_unit.all_dcbs[dcb->poll.thread.id]->thread.next;
|
||||
|
||||
if (this_unit.all_dcbs[dcb->poll.thread.id])
|
||||
if (dcb == this_unit.all_dcbs[dcb->poll.thread.id])
|
||||
{
|
||||
this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail = tail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DCB *current = this_unit.all_dcbs[dcb->poll.thread.id]->thread.next;
|
||||
DCB *prev = this_unit.all_dcbs[dcb->poll.thread.id];
|
||||
DCB *tail = this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail;
|
||||
this_unit.all_dcbs[dcb->poll.thread.id] = this_unit.all_dcbs[dcb->poll.thread.id]->thread.next;
|
||||
|
||||
while (current)
|
||||
{
|
||||
if (current == dcb)
|
||||
if (this_unit.all_dcbs[dcb->poll.thread.id])
|
||||
{
|
||||
if (current == this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail)
|
||||
{
|
||||
this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail = prev;
|
||||
}
|
||||
prev->thread.next = current->thread.next;
|
||||
break;
|
||||
this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail = tail;
|
||||
}
|
||||
prev = current;
|
||||
current = current->thread.next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DCB *current = this_unit.all_dcbs[dcb->poll.thread.id]->thread.next;
|
||||
DCB *prev = this_unit.all_dcbs[dcb->poll.thread.id];
|
||||
|
||||
/** 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;
|
||||
while (current)
|
||||
{
|
||||
if (current == dcb)
|
||||
{
|
||||
if (current == this_unit.all_dcbs[dcb->poll.thread.id]->thread.tail)
|
||||
{
|
||||
this_unit.all_dcbs[dcb->poll.thread.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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1843,6 +1843,57 @@ void service_shutdown()
|
||||
spinlock_release(&service_spin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a listener
|
||||
*
|
||||
* @param sl The listener to destroy.
|
||||
*
|
||||
* @return The next listener or NULL if there is not one.
|
||||
*/
|
||||
static SERV_LISTENER* service_destroy_listener(SERV_LISTENER* sl)
|
||||
{
|
||||
SERV_LISTENER* next = sl->next;
|
||||
|
||||
dcb_close(sl->listener);
|
||||
|
||||
// TODO: What else should be closed and freed here?
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy one service instance
|
||||
*
|
||||
* @param svc The service to destroy.
|
||||
*/
|
||||
static void service_destroy_instance(SERVICE* svc)
|
||||
{
|
||||
SERV_LISTENER* sl = svc->ports;
|
||||
|
||||
while (sl)
|
||||
{
|
||||
sl = service_destroy_listener(sl);
|
||||
}
|
||||
|
||||
/* Call destroyInstance hook for routers */
|
||||
if (svc->router->destroyInstance && svc->router_instance)
|
||||
{
|
||||
svc->router->destroyInstance(svc->router_instance);
|
||||
}
|
||||
if (svc->n_filters)
|
||||
{
|
||||
MXS_FILTER_DEF **filters = svc->filters;
|
||||
for (int i = 0; i < svc->n_filters; i++)
|
||||
{
|
||||
if (filters[i]->obj->destroyInstance && filters[i]->filter)
|
||||
{
|
||||
/* Call destroyInstance hook for filters */
|
||||
filters[i]->obj->destroyInstance(filters[i]->filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void service_destroy_instances(void)
|
||||
{
|
||||
spinlock_acquire(&service_spin);
|
||||
@ -1850,23 +1901,8 @@ void service_destroy_instances(void)
|
||||
while (svc != NULL)
|
||||
{
|
||||
ss_dassert(svc->svc_do_shutdown);
|
||||
/* Call destroyInstance hook for routers */
|
||||
if (svc->router->destroyInstance && svc->router_instance)
|
||||
{
|
||||
svc->router->destroyInstance(svc->router_instance);
|
||||
}
|
||||
if (svc->n_filters)
|
||||
{
|
||||
MXS_FILTER_DEF **filters = svc->filters;
|
||||
for (int i = 0; i < svc->n_filters; i++)
|
||||
{
|
||||
if (filters[i]->obj->destroyInstance && filters[i]->filter)
|
||||
{
|
||||
/* Call destroyInstance hook for filters */
|
||||
filters[i]->obj->destroyInstance(filters[i]->filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
service_destroy_instance(svc);
|
||||
|
||||
svc = svc->next;
|
||||
}
|
||||
spinlock_release(&service_spin);
|
||||
|
Loading…
x
Reference in New Issue
Block a user