]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1580. [bug] Zone destuction on final detach takes a long time.
authorMark Andrews <marka@isc.org>
Thu, 4 Mar 2004 06:56:41 +0000 (06:56 +0000)
committerMark Andrews <marka@isc.org>
Thu, 4 Mar 2004 06:56:41 +0000 (06:56 +0000)
                        [RT #3746]

1579.   [bug]           Multiple task managers could not be created.

CHANGES
lib/dns/db.c
lib/dns/include/dns/db.h
lib/dns/include/dns/events.h
lib/dns/include/dns/rbt.h
lib/dns/rbt.c
lib/dns/rbtdb.c
lib/dns/sdb.c
lib/dns/zone.c
lib/isc/task.c

diff --git a/CHANGES b/CHANGES
index af1a85a5a9f00f9062483e65c809efd351e891ef..3a4fe31a5f9425427f8822a83d8bbe7d53f75b37 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 1581.  [func]          Disable DNSSEC support by default.  To enable
                        DNSSEC specify "enable-dnssec yes;" in named.conf.
 
-1580.  [placeholder]   rt3746a
+1580.  [bug]           Zone destuction on final detach takes a long time.
+                       [RT #3746]
 
-1579.  [placeholder]   rt3746a
+1579.  [bug]           Multiple task managers could not be created.
 
 1578.  [bug]           Don't use CLASS E IPv4 addresses when resolving.
                        [RT #10346]
index c1203c6d848a5eda08d8cd2448415faf488ff249..8814dd710f9e474a13ce7877c56051faee23fe0e 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.c,v 1.72 2003/10/03 03:12:35 marka Exp $ */
+/* $Id: db.c,v 1.73 2004/03/04 06:56:38 marka Exp $ */
 
 /***
  *** Imports
@@ -730,6 +730,13 @@ dns_db_nodecount(dns_db_t *db) {
        return ((db->methods->nodecount)(db));
 }
 
+void
+dns_db_settask(dns_db_t *db, isc_task_t *task) {
+       REQUIRE(DNS_DB_VALID(db));
+
+       (db->methods->settask)(db, task);
+}
+
 isc_result_t
 dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg,
                isc_mem_t *mctx, dns_dbimplementation_t **dbimp)
index 975e2a0031f66330c23d6bacb2acc219bd8b91f7..04ef341f78c938de2e03910246f12f60520fdaa0 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.h,v 1.74 2003/10/03 03:12:35 marka Exp $ */
+/* $Id: db.h,v 1.75 2004/03/04 06:56:40 marka Exp $ */
 
 #ifndef DNS_DB_H
 #define DNS_DB_H 1
@@ -144,6 +144,7 @@ typedef struct dns_dbmethods {
        unsigned int    (*nodecount)(dns_db_t *db);
        isc_boolean_t   (*ispersistent)(dns_db_t *db);
        void            (*overmem)(dns_db_t *db, isc_boolean_t overmem);
+       void            (*settask)(dns_db_t *db, isc_task_t *);
 } dns_dbmethods_t;
 
 typedef isc_result_t
@@ -1189,6 +1190,16 @@ dns_db_nodecount(dns_db_t *db);
  *     The number of nodes in the database
  */
 
+void
+dns_db_settask(dns_db_t *db, isc_task_t *task);
+/*
+ * If task is set then the final detach maybe performed asynchronously.
+ *
+ * Requires:
+ *     'db' is a valid database.
+ *     'task' to be valid or NULL.
+ */
+
 isc_boolean_t
 dns_db_ispersistent(dns_db_t *db);
 /*
index d44dbd2f453fead369bf020fc685385ac771bc9c..b048f2697d2f146e680f70d3ebbbe7fd970b57ea 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: events.h,v 1.40 2002/09/04 02:26:13 jinmei Exp $ */
+/* $Id: events.h,v 1.41 2004/03/04 06:56:40 marka Exp $ */
 
 #ifndef DNS_EVENTS_H
 #define DNS_EVENTS_H 1
@@ -62,6 +62,7 @@
 #define DNS_EVENT_REQUESTCONTROL               (ISC_EVENTCLASS_DNS + 33)
 #define DNS_EVENT_DUMPQUANTUM                  (ISC_EVENTCLASS_DNS + 34)
 #define DNS_EVENT_IMPORTRECVDONE               (ISC_EVENTCLASS_DNS + 35)
+#define DNS_EVENT_FREESTORAGE                  (ISC_EVENTCLASS_DNS + 36)
 
 #define DNS_EVENT_FIRSTEVENT                   (ISC_EVENTCLASS_DNS + 0)
 #define DNS_EVENT_LASTEVENT                    (ISC_EVENTCLASS_DNS + 65535)
index 0d49eaa6e1e693bc8d4d93b4a8256abd4ca07a96..d82586f40b0c97bef8766217845237ab15921622 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbt.h,v 1.57 2002/12/31 05:40:15 marka Exp $ */
+/* $Id: rbt.h,v 1.58 2004/03/04 06:56:40 marka Exp $ */
 
 #ifndef DNS_RBT_H
 #define DNS_RBT_H 1
@@ -600,8 +600,13 @@ dns_rbt_nodecount(dns_rbt_t *rbt);
 
 void
 dns_rbt_destroy(dns_rbt_t **rbtp);
+isc_result_t
+dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum);
 /*
- * Stop working with a red-black tree of trees.
+ * Stop working with a red-black tree of trees.  Once dns_rbt_destroy2()
+ * has been called on a 'rbt' only dns_rbt_destroy() or dns_rbt_destroy2()
+ * may be used on the tree.  If 'quantum' is zero then the entire tree will
+ * be destroyed.
  *
  * Requires:
  *     *rbt is a valid rbt manager.
@@ -610,6 +615,10 @@ dns_rbt_destroy(dns_rbt_t **rbtp);
  *     All space allocated by the RBT library has been returned.
  *
  *     *rbt is invalidated as an rbt manager.
+ *
+ * Returns:
+ *     ISC_R_SUCCESS
+ *     ISC_R_QUOTA if 'quantum' nodes have been destroyed.
  */
 
 void
index 1094fdf6ee555a93ac93982a0b4efc9a16742532..c557a64200bbcba5fba77d9199267106c02628f5 100644 (file)
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbt.c,v 1.126 2004/03/03 22:40:56 marka Exp $ */
+/* $Id: rbt.c,v 1.127 2004/03/04 06:56:39 marka Exp $ */
 
 /* Principal Authors: DCL */
 
 #include <config.h>
 
 #include <isc/mem.h>
+#include <isc/platform.h>
 #include <isc/print.h>
 #include <isc/string.h>
 #include <isc/util.h>
@@ -63,6 +64,7 @@ struct dns_rbt {
        unsigned int            nodecount;
        unsigned int            hashsize;
        dns_rbtnode_t **        hashtable;
+       unsigned int            quantum;
 };
 
 #define RED 0
@@ -225,9 +227,12 @@ dns_rbt_addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order,
 static void
 dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp);
 
-static void
+static isc_result_t
 dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
 
+static void
+dns_rbt_deletetreeflat(dns_rbt_t *rbt, dns_rbtnode_t **nodep);
+
 /*
  * Initialize a red/black tree of trees.
  */
@@ -263,6 +268,7 @@ dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
                return (result);
        }
 #endif
+       rbt->quantum = 0;
        rbt->magic = RBT_MAGIC;
 
        *rbtp = rbt;
@@ -275,13 +281,22 @@ dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
  */
 void
 dns_rbt_destroy(dns_rbt_t **rbtp) {
+       RUNTIME_CHECK(dns_rbt_destroy2(rbtp, 0) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) {
        dns_rbt_t *rbt;
 
        REQUIRE(rbtp != NULL && VALID_RBT(*rbtp));
 
        rbt = *rbtp;
 
-       dns_rbt_deletetree(rbt, rbt->root);
+       rbt->quantum = quantum;
+
+       dns_rbt_deletetreeflat(rbt, &rbt->root);
+       if (rbt->root != NULL)
+               return (ISC_R_QUOTA);
 
        INSIST(rbt->nodecount == 0);
 
@@ -292,8 +307,8 @@ dns_rbt_destroy(dns_rbt_t **rbtp) {
        rbt->magic = 0;
 
        isc_mem_put(rbt->mctx, rbt, sizeof(*rbt));
-
        *rbtp = NULL;
+       return (ISC_R_SUCCESS);
 }
 
 unsigned int
@@ -1258,7 +1273,8 @@ dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse)
 
        if (DOWN(node) != NULL) {
                if (recurse)
-                       dns_rbt_deletetree(rbt, DOWN(node));
+                       RUNTIME_CHECK(dns_rbt_deletetree(rbt, DOWN(node))
+                                     == ISC_R_SUCCESS);
                else {
                        if (DATA(node) != NULL && rbt->data_deleter != NULL)
                                rbt->data_deleter(DATA(node),
@@ -1527,7 +1543,7 @@ hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) {
 
        REQUIRE(DNS_RBTNODE_VALID(node));
 
-       if (rbt->nodecount >= rbt->hashsize)
+       if (rbt->nodecount >= (rbt->hashsize *3))
                rehash(rbt);
 
        hash_add_node(rbt, node);
@@ -1976,19 +1992,75 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) {
  * a pointer needs to be told that this tree no longer exists,
  * this function would need to adjusted accordingly.
  */
-static void
+static isc_result_t
 dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
+       isc_result_t result = ISC_R_SUCCESS;
        REQUIRE(VALID_RBT(rbt));
 
        if (node == NULL)
+               return (result);
+
+       if (LEFT(node) != NULL) {
+               result = dns_rbt_deletetree(rbt, LEFT(node));
+               if (result != ISC_R_SUCCESS)
+                       goto done;
+               LEFT(node) = NULL;
+       }
+       if (RIGHT(node) != NULL) {
+               result = dns_rbt_deletetree(rbt, RIGHT(node));
+               if (result != ISC_R_SUCCESS)
+                       goto done;
+               RIGHT(node) = NULL;
+       }
+       if (DOWN(node) != NULL) {
+               result = dns_rbt_deletetree(rbt, DOWN(node));
+               if (result != ISC_R_SUCCESS)
+                       goto done;
+               DOWN(node) = NULL;
+       }
+ done:
+       if (result != ISC_R_SUCCESS)
+               return (result);
+       if (rbt->quantum != 0 && --rbt->quantum == 0)
+               return (ISC_R_QUOTA);
+
+       if (DATA(node) != NULL && rbt->data_deleter != NULL)
+               rbt->data_deleter(DATA(node), rbt->deleter_arg);
+
+       unhash_node(rbt, node);
+#if DNS_RBT_USEMAGIC
+       node->magic = 0;
+#endif
+       isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
+       rbt->nodecount--;
+       return (result);
+}
+
+static void
+dns_rbt_deletetreeflat(dns_rbt_t *rbt, dns_rbtnode_t **nodep) {
+       dns_rbtnode_t *parent;
+       dns_rbtnode_t *node = *nodep;
+       REQUIRE(VALID_RBT(rbt));
+
+ again:
+       if (node == NULL) {
+               *nodep = NULL;
                return;
+       }
 
-       if (LEFT(node) != NULL)
-               dns_rbt_deletetree(rbt, LEFT(node));
-       if (RIGHT(node) != NULL)
-               dns_rbt_deletetree(rbt, RIGHT(node));
-       if (DOWN(node) != NULL)
-               dns_rbt_deletetree(rbt, DOWN(node));
+ traverse:
+       if (LEFT(node) != NULL) {
+               node = LEFT(node);
+               goto traverse;
+       }
+       if (RIGHT(node) != NULL) {
+               node = RIGHT(node);
+               goto traverse;
+       }
+       if (DOWN(node) != NULL) {
+               node = DOWN(node);
+               goto traverse;
+       }
 
        if (DATA(node) != NULL && rbt->data_deleter != NULL)
                rbt->data_deleter(DATA(node), rbt->deleter_arg);
@@ -1997,8 +2069,23 @@ dns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {
 #if DNS_RBT_USEMAGIC
        node->magic = 0;
 #endif
+       parent = PARENT(node);
+       if (parent != NULL) {
+               if (LEFT(parent) == node)
+                       LEFT(parent) = NULL;
+               else if (DOWN(parent) == node)
+                       DOWN(parent) = NULL;
+               else if (RIGHT(parent) == node)
+                       RIGHT(parent) = NULL;
+       }
        isc_mem_put(rbt->mctx, node, NODE_SIZE(node));
        rbt->nodecount--;
+       node = parent;
+       if (rbt->quantum != 0 && --rbt->quantum == 0) {
+               *nodep = node;
+               return;
+       }
+       goto again;
 }
 
 static void
index 9cc1a35d34ba5da95d5bb58b390d226583608b3a..9f812741a935d3b4409fae3b6351cd0492f93274 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.194 2004/03/04 02:46:28 marka Exp $ */
+/* $Id: rbtdb.c,v 1.195 2004/03/04 06:56:39 marka Exp $ */
 
 /*
  * Principal Author: Bob Halley
@@ -23,6 +23,7 @@
 
 #include <config.h>
 
+#include <isc/event.h>
 #include <isc/mem.h>
 #include <isc/print.h>
 #include <isc/mutex.h>
 #include <isc/refcount.h>
 #include <isc/rwlock.h>
 #include <isc/string.h>
+#include <isc/task.h>
 #include <isc/util.h>
 
 #include <dns/db.h>
 #include <dns/dbiterator.h>
+#include <dns/events.h>
 #include <dns/fixedname.h>
 #include <dns/log.h>
 #include <dns/masterdump.h>
@@ -215,6 +218,7 @@ typedef struct {
        rbtdb_version_t *               future_version;
        rbtdb_versionlist_t             open_versions;
        isc_boolean_t                   overmem;
+       isc_task_t *                    task;
        /* Locked by tree_lock. */
        dns_rbt_t *                     tree;
        isc_boolean_t                   secure;
@@ -339,6 +343,9 @@ typedef struct rbtdb_dbiterator {
 #define IS_STUB(rbtdb)  (((rbtdb)->common.attributes & DNS_DBATTR_STUB)  != 0)
 #define IS_CACHE(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_CACHE) != 0)
 
+static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log,
+                      isc_event_t *event);
+
 /*
  * Locking
  *
@@ -382,10 +389,20 @@ attach(dns_db_t *source, dns_db_t **targetp) {
 }
 
 static void
-free_rbtdb(dns_rbtdb_t *rbtdb) {
+free_rbtdb_callback(isc_task_t *task, isc_event_t *event) {
+       dns_rbtdb_t *rbtdb = event->ev_arg;
+
+       UNUSED(task);
+
+       free_rbtdb(rbtdb, ISC_TRUE, event);
+}
+
+static void
+free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
        unsigned int i;
        isc_ondestroy_t ondest;
-       isc_mem_t *mctx;
+       isc_result_t result;
+       char buf[DNS_NAME_FORMATSIZE];
 
        REQUIRE(EMPTY(rbtdb->open_versions));
        REQUIRE(rbtdb->future_version == NULL);
@@ -393,23 +410,53 @@ free_rbtdb(dns_rbtdb_t *rbtdb) {
        if (rbtdb->current_version != NULL)
                isc_mem_put(rbtdb->common.mctx, rbtdb->current_version,
                            sizeof(rbtdb_version_t));
+ again:
+       if (rbtdb->tree != NULL) {
+               result = dns_rbt_destroy2(&rbtdb->tree,
+                                         (rbtdb->task != NULL) ? 5 : 0);
+               if (result == ISC_R_QUOTA) {
+                       INSIST(rbtdb->task != NULL);
+                       if (event == NULL)
+                               event = isc_event_allocate(rbtdb->common.mctx,
+                                                          NULL,
+                                                        DNS_EVENT_FREESTORAGE,
+                                                          free_rbtdb_callback,
+                                                          rbtdb,
+                                                          sizeof(isc_event_t));
+                       if (event == NULL)
+                               goto again;
+                       isc_task_send(rbtdb->task, &event);
+                       return;
+               }
+               INSIST(result == ISC_R_SUCCESS && rbtdb->tree == NULL);
+       }
+       if (event != NULL)
+               isc_event_free(&event);
+       if (log) {
+               if (dns_name_dynamic(&rbtdb->common.origin))
+                       dns_name_format(&rbtdb->common.origin, buf,
+                                       sizeof(buf));
+               else
+                       strcpy(buf, "<UNKNOWN>");
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+                             DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
+                             "done free_rbtdb(%s)", buf);
+       }
        if (dns_name_dynamic(&rbtdb->common.origin))
                dns_name_free(&rbtdb->common.origin, rbtdb->common.mctx);
-       if (rbtdb->tree != NULL)
-               dns_rbt_destroy(&rbtdb->tree);
        for (i = 0; i < rbtdb->node_lock_count; i++)
                DESTROYLOCK(&rbtdb->node_locks[i].lock);
        isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks,
                    rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
        isc_rwlock_destroy(&rbtdb->tree_lock);
        isc_refcount_destroy(&rbtdb->references);
+       if (rbtdb->task != NULL)
+               isc_task_detach(&rbtdb->task);
        DESTROYLOCK(&rbtdb->lock);
        rbtdb->common.magic = 0;
        rbtdb->common.impmagic = 0;
        ondest = rbtdb->common.ondest;
-       mctx = rbtdb->common.mctx;
-       isc_mem_put(mctx, rbtdb, sizeof(*rbtdb));
-       isc_mem_detach(&mctx);
+       isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
        isc_ondestroy_notify(&ondest, rbtdb);
 }
 
@@ -439,8 +486,18 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
                if (rbtdb->active == 0)
                        want_free = ISC_TRUE;
                UNLOCK(&rbtdb->lock);
-               if (want_free)
-                       free_rbtdb(rbtdb);
+               if (want_free) {
+                       char buf[DNS_NAME_FORMATSIZE];
+                       if (dns_name_dynamic(&rbtdb->common.origin))
+                               dns_name_format(&rbtdb->common.origin, buf,
+                                               sizeof(buf));
+                       else
+                               strcpy(buf, "<UNKNOWN>");
+                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+                                     DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
+                                     "calling free_rbtdb(%s)", buf);
+                       free_rbtdb(rbtdb, ISC_TRUE, NULL);
+               }
        }
 }
 
@@ -3166,8 +3223,18 @@ detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
                if (rbtdb->active == 0)
                        want_free = ISC_TRUE;
                UNLOCK(&rbtdb->lock);
-               if (want_free)
-                       free_rbtdb(rbtdb);
+               if (want_free) {
+                       char buf[DNS_NAME_FORMATSIZE];
+                       if (dns_name_dynamic(&rbtdb->common.origin))
+                               dns_name_format(&rbtdb->common.origin, buf,
+                                               sizeof(buf));
+                       else
+                               strcpy(buf, "<UNKNOWN>");
+                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+                                     DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),
+                                     "calling free_rbtdb(%s)", buf);
+                       free_rbtdb(rbtdb, ISC_TRUE, NULL);
+               }
        }
 }
 
@@ -4552,6 +4619,22 @@ nodecount(dns_db_t *db) {
        return (count);
 }
 
+static void
+settask(dns_db_t *db, isc_task_t *task) {
+       dns_rbtdb_t *rbtdb;
+
+       rbtdb = (dns_rbtdb_t *)db;
+
+       REQUIRE(VALID_RBTDB(rbtdb));
+
+       LOCK(&rbtdb->lock);
+       if (rbtdb->task != NULL)
+               isc_task_detach(&rbtdb->task);
+       if (task != NULL)
+               isc_task_attach(task, &rbtdb->task);
+       UNLOCK(&rbtdb->lock);
+}
+
 static isc_boolean_t
 ispersistent(dns_db_t *db) {
        UNUSED(db);
@@ -4584,7 +4667,8 @@ static dns_dbmethods_t zone_methods = {
        issecure,
        nodecount,
        ispersistent,
-       overmem
+       overmem,
+       settask
 };
 
 static dns_dbmethods_t cache_methods = {
@@ -4613,7 +4697,8 @@ static dns_dbmethods_t cache_methods = {
        issecure,
        nodecount,
        ispersistent,
-       overmem
+       overmem,
+       settask
 };
 
 isc_result_t
@@ -4714,7 +4799,7 @@ dns_rbtdb_create
         */
        result = dns_name_dupwithoffsets(origin, mctx, &rbtdb->common.origin);
        if (result != ISC_R_SUCCESS) {
-               free_rbtdb(rbtdb);
+               free_rbtdb(rbtdb, ISC_FALSE, NULL);
                return (result);
        }
 
@@ -4723,7 +4808,7 @@ dns_rbtdb_create
         */
        result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->tree);
        if (result != ISC_R_SUCCESS) {
-               free_rbtdb(rbtdb);
+               free_rbtdb(rbtdb, ISC_FALSE, NULL);
                return (result);
        }
        /*
@@ -4745,7 +4830,7 @@ dns_rbtdb_create
                                         &rbtdb->origin_node);
                if (result != ISC_R_SUCCESS) {
                        INSIST(result != ISC_R_EXISTS);
-                       free_rbtdb(rbtdb);
+                       free_rbtdb(rbtdb, ISC_FALSE, NULL);
                        return (result);
                }
                /*
@@ -4771,6 +4856,7 @@ dns_rbtdb_create
        rbtdb->attributes = 0;
        rbtdb->secure = ISC_FALSE;
        rbtdb->overmem = ISC_FALSE;
+       rbtdb->task = NULL;
 
        /*
         * Version Initialization.
@@ -4780,7 +4866,7 @@ dns_rbtdb_create
        rbtdb->next_serial = 2;
        rbtdb->current_version = allocate_version(mctx, 1, 0, ISC_FALSE);
        if (rbtdb->current_version == NULL) {
-               free_rbtdb(rbtdb);
+               free_rbtdb(rbtdb, ISC_FALSE, NULL);
                return (ISC_R_NOMEMORY);
        }
        rbtdb->future_version = NULL;
index 60c048cc18b5d06592776cb497b65acc4ac040bb..6ebe3850795527297183912a318c9dc4290bddad 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sdb.c,v 1.43 2004/02/27 20:41:44 marka Exp $ */
+/* $Id: sdb.c,v 1.44 2004/03/04 06:56:39 marka Exp $ */
 
 #include <config.h>
 
@@ -1200,6 +1200,12 @@ overmem(dns_db_t *db, isc_boolean_t overmem) {
        UNUSED(overmem);
 }
 
+static void
+settask(dns_db_t *db, isc_task_t *task) {
+       UNUSED(db);
+       UNUSED(task);
+}
+
 
 static dns_dbmethods_t sdb_methods = {
        attach,
@@ -1227,7 +1233,8 @@ static dns_dbmethods_t sdb_methods = {
        issecure,
        nodecount,
        ispersistent,
-       overmem
+       overmem,
+       settask
 };
 
 static isc_result_t
index e04eac53d0557d0e0c63ccdc508a8557bc8e3b30..20b217db32117acbcd1ca0b494917ea59ab99c59 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.407 2004/03/02 02:37:11 marka Exp $ */
+/* $Id: zone.c,v 1.408 2004/03/04 06:56:39 marka Exp $ */
 
 #include <config.h>
 
@@ -1046,6 +1046,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
                             isc_result_totext(result));
                goto cleanup;
        }
+       dns_db_settask(db, zone->task);
 
        if (! dns_db_ispersistent(db)) {
                if (zone->masterfile != NULL) {
@@ -4049,6 +4050,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
                                             dns_result_totext(result));
                                goto cleanup;
                        }
+                       dns_db_settask(stub->db, zone->task);
                }
 
                dns_db_newversion(stub->db, &stub->version);
@@ -5079,6 +5081,8 @@ dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
        if (zone->task != NULL)
                isc_task_detach(&zone->task);
        isc_task_attach(task, &zone->task);
+       if (zone->db != NULL)
+               dns_db_settask(zone->db, zone->task);
        UNLOCK_ZONE(zone);
 }
 
@@ -5267,6 +5271,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
        if (zone->db != NULL)
                dns_db_detach(&zone->db);
        dns_db_attach(db, &zone->db);
+       dns_db_settask(zone->db, zone->task);
        DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
        return (ISC_R_SUCCESS);
 
index 4d8431915ba298c103d0228b5d3fc6fc870b212c..3027493604022443ded4b6d77d86dd9a4e2a48e3 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: task.c,v 1.89 2003/10/25 00:09:13 jinmei Exp $ */
+/* $Id: task.c,v 1.90 2004/03/04 06:56:41 marka Exp $ */
 
 /*
  * Principal Author: Bob Halley
@@ -1132,7 +1132,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
        }
        isc_thread_setconcurrency(workers);
 #else /* ISC_PLATFORM_USETHREADS */
-       manager->refs = 0;
+       manager->refs = 1;
        taskmgr = manager;
 #endif /* ISC_PLATFORM_USETHREADS */