Commit 4e96d1fc authored by Michael Graff's avatar Michael Graff
Browse files

restructure creating and cleanup to more closely fit the other subsystem's...

restructure creating and cleanup to more closely fit the other subsystem's methods.  This removes one more todo item from my list.
parent abaec240
......@@ -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 *);
......
......@@ -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_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_destroy(ns_lwresd_t **lwresdp);
ns_lwresd_memfree(void *arg, void *mem, size_t size);
#endif /* NAMED_LWRESD_H */
......@@ -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);
}
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;
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
clientmgr_can_die(ns_lwdclientmgr_t *cm) {
if ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) == 0)
lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) {
ns_lwdclient_t *client;
ns_lwresd_t *lwresd = cm->lwresd;
if (!SHUTTINGDOWN(cm))
return;
if (ISC_LIST_HEAD(cm->running) != NULL)
/*
* 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(!SHUTTINGDOWN(cm));
REQUIRE((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) == 0);
ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p",
task, cm);
ns_lwdclient_log(50, "got shutdown event, task %p", task);
/*
* 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);
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);
}
......
......@@ -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;
UNUSED(task);
void
lwresd_destroy(ns_lwresd_t *lwresd) {
isc_mem_t *mctx;
dns_dispatchmgr_destroy(&lwresd->dispmgr);
LOCK(&lwresd->lock);
if (!ISC_LIST_EMPTY(lwresd->cmgrs) || (!lwresd->shutting_down)) {
UNLOCK(&lwresd->lock);
return;
}
/*
* Wait for everything to die off by waiting for the sockets
* to be detached.
* At this point, nothing can have the lwresd locked, since there
* are no clients running.
*/
isc_socket_detach(&lwresd->sock);
UNLOCK(&lwresd->lock);
/*
* Kill off the view.
*/
dns_dispatchmgr_destroy(&lwresd->dispmgr);
isc_socket_detach(&lwresd->sock);
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 one task for each client manager.
* Create the managers.
*/
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 */
for (i = 0 ; i < NTASKS ; i++)
ns_lwdclientmgr_create(lwresd, NRECVS, ns_g_taskmgr);
/*
* 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.
* Ensure that we have created at least one.
*/
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);
INSIST(!ISC_LIST_EMPTY(lwresd->cmgrs));
/*
* Issue one read request for each task we have.
* Walk the list of clients and start each one up.
*/
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);
lwresd = *lwresdp;
REQUIRE(VALID_LWRESD(lwresd));
INSIST(lwresdp != NULL && VALID_LWRESD(*lwresdp));
mctx = lwresd->mctx;
lwresd = *lwresdp;
*lwresdp = NULL;
/*
* 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);
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);
}
INSIST(ISC_LIST_EMPTY(lwresd->cmgr[0].running));
UNLOCK(&lwresd->lock);
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;
lwresd_destroy(lwresd);
}
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment