2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 16:15:27 +00:00

restructure creating and cleanup to more closely fit the other subsystem's methods. This removes one more todo item from my list.

This commit is contained in:
Michael Graff
2000-09-07 21:54:40 +00:00
parent abaec24086
commit 4e96d1fc06
5 changed files with 254 additions and 152 deletions

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwdclient.h,v 1.5 2000/08/01 01:12:09 tale Exp $ */
/* $Id: lwdclient.h,v 1.6 2000/09/07 21:54:39 explorer Exp $ */
#ifndef NAMED_LWDCLIENT_H
#define NAMED_LWDCLIENT_H 1
@@ -161,12 +161,14 @@ struct ns_lwdclient {
((c)->state = NS_LWDCLIENT_STATESENDDONE)
struct ns_lwdclientmgr {
ns_lwresd_t *lwresd;
isc_mem_t *mctx;
isc_task_t *task; /* owning task */
isc_socket_t *sock; /* socket to use */
dns_view_t *view;
unsigned int flags;
lwres_context_t *lwctx; /* lightweight proto context */
isc_task_t *task; /* owning task */
unsigned int flags;
ISC_LINK(ns_lwdclientmgr_t) link;
ISC_LIST(ns_lwdclient_t) idle; /* idle client slots */
ISC_LIST(ns_lwdclient_t) running; /* running clients */
};
@@ -174,6 +176,9 @@ struct ns_lwdclientmgr {
#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001
#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002
void
ns_lwdclientmgr_create(ns_lwresd_t *, unsigned int, isc_taskmgr_t *);
void
ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *);

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwresd.h,v 1.5 2000/08/01 01:12:10 tale Exp $ */
/* $Id: lwresd.h,v 1.6 2000/09/07 21:54:40 explorer Exp $ */
#ifndef NAMED_LWRESD_H
#define NAMED_LWRESD_H 1
@@ -27,19 +27,35 @@
struct ns_lwresd {
isc_uint32_t magic;
ns_lwdclientmgr_t *cmgr;
isc_mutex_t lock;
ISC_LIST(ns_lwdclientmgr_t) cmgrs;
isc_socket_t *sock;
unsigned int ntasks;
dns_view_t *view;
isc_mem_t *mctx;
isc_task_t *task;
dns_dispatchmgr_t *dispmgr;
isc_boolean_t shutting_down;
};
void
ns_lwresd_create(isc_mem_t *mctx, dns_view_t *view, ns_lwresd_t **lwresdp);
/*
* Trigger shutdown.
*/
void
ns_lwresd_destroy(ns_lwresd_t **lwresdp);
ns_lwresd_shutdown(ns_lwresd_t **lwresdp);
/*
* INTERNAL FUNCTIONS.
*/
void
lwresd_destroy(ns_lwresd_t *lwresdp);
void *
ns_lwresd_memalloc(void *arg, size_t size);
void
ns_lwresd_memfree(void *arg, void *mem, size_t size);
#endif /* NAMED_LWRESD_H */

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwdclient.c,v 1.6 2000/08/01 01:11:45 tale Exp $ */
/* $Id: lwdclient.c,v 1.7 2000/09/07 21:54:35 explorer Exp $ */
#include <config.h>
@@ -24,12 +24,19 @@
#include <isc/task.h>
#include <isc/util.h>
#include <dns/adb.h>
#include <dns/view.h>
#include <dns/log.h>
#include <named/types.h>
#include <named/lwresd.h>
#include <named/lwdclient.h>
#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0)
static void
lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev);
void
ns_lwdclient_log(int level, const char *format, ...) {
va_list args;
@@ -41,18 +48,124 @@ ns_lwdclient_log(int level, const char *format, ...) {
va_end(args);
}
static void
clientmgr_can_die(ns_lwdclientmgr_t *cm) {
if ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) == 0)
void
ns_lwdclientmgr_create(ns_lwresd_t *lwresd, unsigned int nclients,
isc_taskmgr_t *taskmgr)
{
ns_lwdclientmgr_t *cm;
ns_lwdclient_t *client;
unsigned int i;
cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t));
if (cm == NULL)
return;
if (ISC_LIST_HEAD(cm->running) != NULL)
cm->lwresd = lwresd;
cm->mctx = lwresd->mctx;
cm->sock = lwresd->sock;
cm->view = lwresd->view;
cm->lwctx = NULL;
cm->task = NULL;
cm->flags = 0;
ISC_LINK_INIT(cm, link);
ISC_LIST_INIT(cm->idle);
ISC_LIST_INIT(cm->running);
if (lwres_context_create(&cm->lwctx, cm->mctx,
ns_lwresd_memalloc, ns_lwresd_memfree,
LWRES_CONTEXT_SERVERMODE)
!= ISC_R_SUCCESS)
goto errout;
for (i = 0 ; i < nclients ; i++) {
client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t));
if (client != NULL) {
ns_lwdclient_log(50, "created client %p, manager %p",
client, cm);
ns_lwdclient_initialize(client, cm);
}
}
/*
* If we could create no clients, clean up and return.
*/
if (ISC_LIST_EMPTY(cm->idle))
goto errout;
if (isc_task_create(taskmgr, 0, &cm->task) != ISC_R_SUCCESS)
goto errout;
/*
* This MUST be last, since there is no way to cancel an onshutdown...
*/
if (isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, cm)
!= ISC_R_SUCCESS)
goto errout;
/*
* Nothing between the onshutdown call and the end of this
* function is allowed to fail without crashing the server
* via INSIST() or REQUIRE().
*/
ISC_LIST_APPEND(lwresd->cmgrs, cm, link);
return;
errout:
client = ISC_LIST_HEAD(cm->idle);
while (client != NULL) {
ISC_LIST_UNLINK(cm->idle, client, link);
isc_mem_put(lwresd->mctx, client, sizeof (*client));
client = ISC_LIST_HEAD(cm->idle);
}
if (cm->task != NULL)
isc_task_detach(&cm->task);
if (cm->lwctx != NULL)
lwres_context_destroy(&cm->lwctx);
isc_mem_put(lwresd->mctx, cm, sizeof (*cm));
}
static void
lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) {
ns_lwdclient_t *client;
ns_lwresd_t *lwresd = cm->lwresd;
if (!SHUTTINGDOWN(cm))
return;
/*
* run through the idle list and free the clients there. Idle
* clients do not have a recv running nor do they have any finds
* or similar running.
*/
client = ISC_LIST_HEAD(cm->idle);
while (client != NULL) {
ns_lwdclient_log(50, "destroying client %p, manager %p",
client, cm);
ISC_LIST_UNLINK(cm->idle, client, link);
isc_mem_put(cm->mctx, client, sizeof (*client));
client = ISC_LIST_HEAD(cm->idle);
}
if (!ISC_LIST_EMPTY(cm->running))
return;
lwres_context_destroy(&cm->lwctx);
isc_socket_detach(&cm->sock);
dns_view_detach(&cm->view);
cm->view = NULL;
cm->sock = NULL;
isc_task_detach(&cm->task);
LOCK(&lwresd->lock);
ISC_LIST_UNLINK(lwresd->cmgrs, cm, link);
ns_lwdclient_log(50, "destroying manager %p", cm);
isc_mem_put(lwresd->mctx, cm, sizeof (*cm));
UNLOCK(&lwresd->lock);
lwresd_destroy(lwresd);
}
static void
@@ -148,8 +261,10 @@ ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) {
isc_result_t result;
isc_region_t r;
if ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0)
if (SHUTTINGDOWN(cm)) {
lwdclientmgr_destroy(cm);
return (ISC_R_SUCCESS);
}
/*
* If a recv is already running, don't bother.
@@ -191,25 +306,50 @@ ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) {
return (ISC_R_SUCCESS);
}
void
ns_lwdclient_shutdown(isc_task_t *task, isc_event_t *ev) {
static void
lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) {
ns_lwdclientmgr_t *cm = ev->ev_arg;
ns_lwdclient_t *client;
REQUIRE((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) == 0);
REQUIRE(!SHUTTINGDOWN(cm));
ns_lwdclient_log(50, "got shutdown event, task %p", task);
ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p",
task, cm);
/*
* run through the idle list and free the clients there. Idle
* clients do not have a recv running nor do they have any finds
* or similar running.
*/
client = ISC_LIST_HEAD(cm->idle);
while (client != NULL) {
ns_lwdclient_log(50, "destroying client %p, manager %p",
client, cm);
ISC_LIST_UNLINK(cm->idle, client, link);
isc_mem_put(cm->mctx, client, sizeof (*client));
client = ISC_LIST_HEAD(cm->idle);
}
/*
* Cancel any pending I/O.
*/
if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0)
isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL);
/*
* Run through the running client list and kill off any finds
* in progress.
*/
/* XXXMLG */
client = ISC_LIST_HEAD(cm->running);
while (client != NULL) {
if (client->find != client->v4find
&& client->find != client->v6find)
dns_adb_cancelfind(client->find);
if (client->v4find != NULL)
dns_adb_cancelfind(client->v4find);
if (client->v6find != NULL)
dns_adb_cancelfind(client->v6find);
client = ISC_LIST_NEXT(client, link);
}
cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN;
@@ -237,8 +377,6 @@ ns_lwdclient_stateidle(ns_lwdclient_t *client) {
NS_LWDCLIENT_SETIDLE(client);
clientmgr_can_die(cm);
ns_lwdclient_startrecv(cm);
}

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwresd.c,v 1.14 2000/08/24 22:15:26 bwelling Exp $ */
/* $Id: lwresd.c,v 1.15 2000/09/07 21:54:36 explorer Exp $ */
/*
* Main program for the Lightweight Resolver Daemon.
@@ -60,9 +60,8 @@
/*
* The goal number of clients we can handle will be NTASKS * NRECVS.
*/
#define NTASKS 20 /* tasks to create to handle lwres queries */
#define NRECVS 5 /* max clients per task */
#define NTHREADS 1 /* # threads to create in thread manager */
#define NTASKS 2 /* tasks to create to handle lwres queries */
#define NRECVS 2 /* max clients per task */
static void
fatal(const char *msg, isc_result_t result) {
@@ -77,41 +76,43 @@ fatal(const char *msg, isc_result_t result) {
/*
* Wrappers around our memory management stuff, for the lwres functions.
*/
static void *
mem_alloc(void *arg, size_t size) {
void *
ns_lwresd_memalloc(void *arg, size_t size) {
return (isc_mem_get(arg, size));
}
static void
mem_free(void *arg, void *mem, size_t size) {
void
ns_lwresd_memfree(void *arg, void *mem, size_t size) {
isc_mem_put(arg, mem, size);
}
static void
shutdown_lwresd(isc_task_t *task, isc_event_t *event) {
ns_lwresd_t *lwresd = event->ev_arg;
void
lwresd_destroy(ns_lwresd_t *lwresd) {
isc_mem_t *mctx;
UNUSED(task);
LOCK(&lwresd->lock);
if (!ISC_LIST_EMPTY(lwresd->cmgrs) || (!lwresd->shutting_down)) {
UNLOCK(&lwresd->lock);
return;
}
/*
* At this point, nothing can have the lwresd locked, since there
* are no clients running.
*/
UNLOCK(&lwresd->lock);
dns_dispatchmgr_destroy(&lwresd->dispmgr);
/*
* Wait for everything to die off by waiting for the sockets
* to be detached.
*/
isc_socket_detach(&lwresd->sock);
/*
* Kill off the view.
*/
dns_view_detach(&lwresd->view);
isc_task_detach(&lwresd->task);
mctx = lwresd->mctx;
isc_event_free(&event);
lwresd->magic = 0;
isc_mem_put(mctx, lwresd, sizeof(*lwresd));
isc_mem_detach(&mctx);
}
static void
parse_resolv_conf(isc_mem_t *mctx, isc_sockaddrlist_t *forwarders) {
lwres_context_t *lwctx;
@@ -124,7 +125,7 @@ parse_resolv_conf(isc_mem_t *mctx, isc_sockaddrlist_t *forwarders) {
in_port_t port;
lwctx = NULL;
lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free,
lwresult = lwres_context_create(&lwctx, mctx, ns_lwresd_memalloc, ns_lwresd_memfree,
LWRES_CONTEXT_SERVERMODE);
if (lwresult != LWRES_R_SUCCESS)
return;
@@ -296,8 +297,8 @@ ns_lwresd_create(isc_mem_t *mctx, dns_view_t *view, ns_lwresd_t **lwresdp) {
ns_lwresd_t *lwresd;
isc_sockaddr_t localhost;
struct in_addr lh_addr;
unsigned int i, j;
ns_lwdclient_t *client;
unsigned int i;
ns_lwdclientmgr_t *cm;
isc_socket_t *sock;
isc_result_t result;
@@ -322,15 +323,21 @@ ns_lwresd_create(isc_mem_t *mctx, dns_view_t *view, ns_lwresd_t **lwresdp) {
lwresd = isc_mem_get(mctx, sizeof(*lwresd));
if (lwresd == NULL)
fatal("allocating lightweight resolver object", ISC_R_NOMEMORY);
fatal("allocating lightweight resolver object",
ISC_R_NOMEMORY);
lwresd->mctx = NULL;
isc_mem_attach(mctx, &lwresd->mctx);
lwresd->sock = sock;
result = isc_mutex_init(&lwresd->lock);
if (result != ISC_R_SUCCESS)
fatal("creating lock", result);
lwresd->shutting_down = ISC_FALSE;
lwresd->sock = sock;
lwresd->view = NULL;
lwresd->dispmgr = NULL;
ISC_LIST_INIT(lwresd->cmgrs);
if (view != NULL)
dns_view_attach(view, &lwresd->view);
else {
@@ -339,115 +346,50 @@ ns_lwresd_create(isc_mem_t *mctx, dns_view_t *view, ns_lwresd_t **lwresdp) {
fatal("failed to create default view", result);
}
lwresd->task = NULL;
result = isc_task_create(ns_g_taskmgr, 0, &lwresd->task);
if (result != ISC_R_SUCCESS)
fatal("allocating lightweight resolver task", result);
isc_task_setname(lwresd->task, "lwresd", lwresd);
result = isc_task_onshutdown(lwresd->task, shutdown_lwresd, lwresd);
if (result != ISC_R_SUCCESS)
fatal("allocating lwresd onshutdown event", result);
lwresd->cmgr = isc_mem_get(lwresd->mctx,
sizeof(ns_lwdclientmgr_t) * NTASKS);
if (lwresd->cmgr == NULL)
fatal("allocating lwresd client manager", ISC_R_NOMEMORY);
/*
* Create the managers.
*/
for (i = 0 ; i < NTASKS ; i++)
ns_lwdclientmgr_create(lwresd, NRECVS, ns_g_taskmgr);
/*
* Create one task for each client manager.
* Ensure that we have created at least one.
*/
for (i = 0 ; i < NTASKS ; i++) {
char name[16];
lwresd->cmgr[i].task = NULL;
lwresd->cmgr[i].sock = NULL;
isc_socket_attach(lwresd->sock, &lwresd->cmgr[i].sock);
lwresd->cmgr[i].view = NULL;
lwresd->cmgr[i].flags = 0;
result = isc_task_create(ns_g_taskmgr, 0,
&lwresd->cmgr[i].task);
if (result != ISC_R_SUCCESS)
break;
result = isc_task_onshutdown(lwresd->cmgr[i].task,
ns_lwdclient_shutdown,
&lwresd->cmgr[i]);
if (result != ISC_R_SUCCESS)
break;
ISC_LIST_INIT(lwresd->cmgr[i].idle);
ISC_LIST_INIT(lwresd->cmgr[i].running);
snprintf(name, sizeof(name), "lwd client %d", i);
isc_task_setname(lwresd->cmgr[i].task, name, &lwresd->cmgr[i]);
lwresd->cmgr[i].mctx = lwresd->mctx;
lwresd->cmgr[i].lwctx = NULL;
result = lwres_context_create(&lwresd->cmgr[i].lwctx,
lwresd->mctx,
mem_alloc, mem_free,
LWRES_CONTEXT_SERVERMODE);
if (result != ISC_R_SUCCESS) {
isc_task_detach(&lwresd->cmgr[i].task);
break;
}
dns_view_attach(lwresd->view, &lwresd->cmgr[i].view);
}
INSIST(i > 0);
lwresd->ntasks = i; /* remember how many we managed to create */
INSIST(!ISC_LIST_EMPTY(lwresd->cmgrs));
/*
* Now, run through each client manager and populate it with
* client structures. Do this by creating one receive for each
* task, in a loop, so each task has a chance of getting at least
* one client structure.
* Walk the list of clients and start each one up.
*/
for (i = 0 ; i < NRECVS ; i++) {
client = isc_mem_get(lwresd->mctx,
sizeof(ns_lwdclient_t) * lwresd->ntasks);
if (client == NULL)
break;
for (j = 0 ; j < lwresd->ntasks ; j++)
ns_lwdclient_initialize(&client[j], &lwresd->cmgr[j]);
}
INSIST(i > 0);
/*
* Issue one read request for each task we have.
*/
for (j = 0 ; j < lwresd->ntasks ; j++) {
result = ns_lwdclient_startrecv(&lwresd->cmgr[j]);
INSIST(result == ISC_R_SUCCESS);
LOCK(&lwresd->lock);
cm = ISC_LIST_HEAD(lwresd->cmgrs);
while (cm != NULL) {
ns_lwdclient_startrecv(cm);
cm = ISC_LIST_NEXT(cm, link);
}
UNLOCK(&lwresd->lock);
lwresd->magic = LWRESD_MAGIC;
*lwresdp = lwresd;
}
void
ns_lwresd_destroy(ns_lwresd_t **lwresdp) {
ns_lwresd_shutdown(ns_lwresd_t **lwresdp) {
ns_lwdclientmgr_t *cm;
ns_lwresd_t *lwresd;
ns_lwdclient_t *client;
isc_mem_t *mctx;
REQUIRE(lwresdp != NULL);
INSIST(lwresdp != NULL && VALID_LWRESD(*lwresdp));
lwresd = *lwresdp;
REQUIRE(VALID_LWRESD(lwresd));
mctx = lwresd->mctx;
/*
* Free up memory allocated. This is somewhat magical. We allocated
* the ns_lwdclient_t's in blocks, but the first task always has the
* first pointer. Just loop here, freeing them.
*/
client = ISC_LIST_HEAD(lwresd->cmgr[0].idle);
while (client != NULL) {
ISC_LIST_UNLINK(lwresd->cmgr[0].idle, client, link);
isc_mem_put(mctx, client,
sizeof(ns_lwdclient_t) * lwresd->ntasks);
client = ISC_LIST_HEAD(lwresd->cmgr[0].idle);
}
INSIST(ISC_LIST_EMPTY(lwresd->cmgr[0].running));
isc_mem_put(mctx, lwresd->cmgr, sizeof(ns_lwdclientmgr_t) * NTASKS);
lwresd->magic = 0;
isc_mem_put(mctx, lwresd, sizeof(*lwresd));
isc_mem_detach(&mctx);
*lwresdp = NULL;
LOCK(&lwresd->lock);
lwresd->shutting_down = ISC_TRUE;
cm = ISC_LIST_HEAD(lwresd->cmgrs);
while (cm != NULL) {
isc_task_shutdown(cm->task);
cm = ISC_LIST_NEXT(cm, link);
}
UNLOCK(&lwresd->lock);
lwresd_destroy(lwresd);
}

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: main.c,v 1.82 2000/08/30 20:40:04 bwelling Exp $ */
/* $Id: main.c,v 1.83 2000/09/07 21:54:37 explorer Exp $ */
#include <config.h>
@@ -518,11 +518,12 @@ setup(void) {
static void
cleanup(void) {
if (lwresd_only)
ns_lwresd_shutdown(&ns_g_lwresd);
destroy_managers();
if (lwresd_only)
ns_lwresd_destroy(&ns_g_lwresd);
else
if (!lwresd_only)
ns_server_destroy(&ns_g_server);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,