]> 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:28 +0000 (06:56 +0000)
committerMark Andrews <marka@isc.org>
Thu, 4 Mar 2004 06:56:28 +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 c4dabf43f2a9767780f23c8149b10c7cf758ab51..56267b2277e814c918dc0173c98b68a8d40a3895 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 1582.  [bug]           rrset-order failed to work on RRsets with more
                        than 32 elements. [RT #10381]
 
+1580.  [bug]           Zone destuction on final detach takes a long time.
+                       [RT #3746]
+
+1579.  [bug]           Multiple task managers could not be created.
+
 1578.  [bug]           Don't use CLASS E IPv4 addresses when resolving.
                        [RT #10346]
 
index 166eb5aa672f0c39cc2446d877f21e080bb316fd..96114fb751d56898aac31c6481c4faac19296f93 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.c,v 1.69.2.3 2003/10/09 07:32:36 marka Exp $ */
+/* $Id: db.c,v 1.69.2.4 2004/03/04 06:56:26 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 4aa2607516f02b97bde00ee1dc0f5d810f0ac64b..c91eedfdf75ac35711c5b6e8dc84f70985633c7c 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.h,v 1.67.2.2 2003/10/09 07:32:39 marka Exp $ */
+/* $Id: db.h,v 1.67.2.3 2004/03/04 06:56:27 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
@@ -1172,6 +1173,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 9935327d1e2a6fac1796aeabfdb7ed2461e765ea..7c6f0f7118cf108f789ff83c05674ee6bdd4621c 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: events.h,v 1.37.2.1 2002/09/04 02:47:08 jinmei Exp $ */
+/* $Id: events.h,v 1.37.2.2 2004/03/04 06:56:28 marka Exp $ */
 
 #ifndef DNS_EVENTS_H
 #define DNS_EVENTS_H 1
@@ -61,6 +61,7 @@
 #define DNS_EVENT_DISPATCHCONTROL              (ISC_EVENTCLASS_DNS + 32)
 #define DNS_EVENT_REQUESTCONTROL               (ISC_EVENTCLASS_DNS + 33)
 #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 b0b7af314227905e62655ef663a8f496178133d6..bca28155bf8eb373e5fef9bfa30b88068ea98a8c 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbt.h,v 1.55 2001/06/01 03:07:54 halley Exp $ */
+/* $Id: rbt.h,v 1.55.2.1 2004/03/04 06:56:28 marka Exp $ */
 
 #ifndef DNS_RBT_H
 #define DNS_RBT_H 1
@@ -588,8 +588,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.
@@ -598,6 +603,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 febdcf6b0f5de96bf5f0f14dab2061db80221996..4754f5daf25c4189d5904e51d77aafff10b8b386 100644 (file)
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbt.c,v 1.115.2.3 2004/03/03 22:38:20 marka Exp $ */
+/* $Id: rbt.c,v 1.115.2.4 2004/03/04 06:56:26 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
@@ -246,9 +248,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.
  */
@@ -284,6 +289,7 @@ dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *),
                return (result);
        }
 #endif
+       rbt->quantum = 0;
        rbt->magic = RBT_MAGIC;
 
        *rbtp = rbt;
@@ -296,13 +302,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);
 
@@ -313,8 +328,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
@@ -1405,8 +1420,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),
@@ -1667,7 +1682,7 @@ rehash(dns_rbt_t *rbt) {
 static inline void
 hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) {
 
-       if (rbt->nodecount >= rbt->hashsize)
+       if (rbt->nodecount >= (rbt->hashsize * 3))
                rehash(rbt);
 
        hash_add_node(rbt, node);
@@ -2113,26 +2128,97 @@ 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);
 
        unhash_node(rbt, node);
+       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 ed8ba61846a8f122b70b36eeea02109909c8f2d1..b3783325bdc4821c7358d0f2956e5fbe417c35c3 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.168.2.14 2004/03/04 02:46:24 marka Exp $ */
+/* $Id: rbtdb.c,v 1.168.2.15 2004/03/04 06:56:26 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>
@@ -180,6 +183,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;
@@ -298,6 +302,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
  *
@@ -341,10 +348,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);
@@ -352,23 +369,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);
 }
 
@@ -398,8 +445,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);
+               }
        }
 }
 
@@ -3068,8 +3125,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);
+               }
        }
 }
 
@@ -4377,6 +4444,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);
@@ -4409,7 +4492,8 @@ static dns_dbmethods_t zone_methods = {
        issecure,
        nodecount,
        ispersistent,
-       overmem
+       overmem,
+       settask
 };
 
 static dns_dbmethods_t cache_methods = {
@@ -4438,7 +4522,8 @@ static dns_dbmethods_t cache_methods = {
        issecure,
        nodecount,
        ispersistent,
-       overmem
+       overmem,
+       settask
 };
 
 isc_result_t
@@ -4539,7 +4624,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);
        }
 
@@ -4548,7 +4633,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);
        }
        /*
@@ -4570,7 +4655,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);
                }
                /*
@@ -4596,6 +4681,7 @@ dns_rbtdb_create
        rbtdb->attributes = 0;
        rbtdb->secure = ISC_FALSE;
        rbtdb->overmem = ISC_FALSE;
+       rbtdb->task = NULL;
 
        /*
         * Version Initialization.
@@ -4605,7 +4691,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 fb0cbb97a9230a1b0bd1edf25b512b828237f5a0..a66766c7a8e06fcd2de755ca17309e49bd4a7f81 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sdb.c,v 1.35.2.2 2003/10/09 07:32:38 marka Exp $ */
+/* $Id: sdb.c,v 1.35.2.3 2004/03/04 06:56:26 marka Exp $ */
 
 #include <config.h>
 
@@ -1145,6 +1145,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,
@@ -1172,7 +1178,8 @@ static dns_dbmethods_t sdb_methods = {
        issecure,
        nodecount,
        ispersistent,
-       overmem
+       overmem,
+       settask
 };
 
 static isc_result_t
index f1cb1611dc273174123a9e995bda4ffe3911a425..d3e3c902208fedb688209ba03c5050a0fe45076a 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.333.2.29 2004/03/02 02:36:41 marka Exp $ */
+/* $Id: zone.c,v 1.333.2.30 2004/03/04 06:56:27 marka Exp $ */
 
 #include <config.h>
 
@@ -998,6 +998,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) {
@@ -3632,6 +3633,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);
@@ -4571,6 +4573,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);
 }
 
@@ -4759,6 +4763,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 4aa8d0de14c726e7594b790aef31f0904297f602..669a2cb4df28186d206604df6b20a7a4b57749fa 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: task.c,v 1.85.2.3 2002/08/06 02:20:39 marka Exp $ */
+/* $Id: task.c,v 1.85.2.4 2004/03/04 06:56:28 marka Exp $ */
 
 /*
  * Principal Author: Bob Halley
@@ -1118,7 +1118,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 */