changeset 1906:4a8c9139e579

cleanup resolver
author Igor Sysoev <igor@sysoev.ru>
date Thu, 28 Feb 2008 20:38:34 +0000
parents 0cafbfd8112e
children 7d47e1681a62
files src/core/ngx_resolver.c src/core/ngx_resolver.h src/http/ngx_http_core_module.c src/mail/ngx_mail_core_module.c
diffstat 4 files changed, 83 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -50,6 +50,8 @@ typedef struct {
 ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc);
 
 
+static void ngx_resolver_cleanup(void *data);
+static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
 static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
     ngx_resolver_ctx_t *ctx);
 static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
@@ -90,17 +92,27 @@ static void *ngx_resolver_dup(ngx_resolv
 /* STUB: ngx_peer_addr_t * */
 
 ngx_resolver_t *
-ngx_resolver_create(ngx_peer_addr_t *addr, ngx_log_t *log)
+ngx_resolver_create(ngx_pool_t *pool, ngx_peer_addr_t *addr)
 {
     ngx_resolver_t        *r;
+    ngx_pool_cleanup_t    *cln;
     ngx_udp_connection_t  *uc;
 
-    r = ngx_calloc(sizeof(ngx_resolver_t), log);
+    cln = ngx_pool_cleanup_add(pool, 0);
+    if (cln == NULL) {
+        return NULL;
+    }
+
+    cln->handler = ngx_resolver_cleanup;
+
+    r = ngx_calloc(sizeof(ngx_resolver_t), pool->log);
     if (r == NULL) {
         return NULL;
     }
 
-    r->event = ngx_calloc(sizeof(ngx_event_t), log);
+    cln->data = r;
+
+    r->event = ngx_calloc(sizeof(ngx_event_t), pool->log);
     if (r->event == NULL) {
         return NULL;
     }
@@ -119,18 +131,18 @@ ngx_resolver_create(ngx_peer_addr_t *add
 
     r->event->handler = ngx_resolver_resend_handler;
     r->event->data = r;
-    r->event->log = log;
+    r->event->log = pool->log;
     r->ident = -1;
 
     r->resend_timeout = 5;
     r->expire = 30;
     r->valid = 300;
 
-    r->log = log;
+    r->log = pool->log;
     r->log_level = NGX_LOG_ALERT;
 
     if (addr) {
-        uc = ngx_calloc(sizeof(ngx_udp_connection_t), log);
+        uc = ngx_calloc(sizeof(ngx_udp_connection_t), pool->log);
         if (uc == NULL) {
             return NULL;
         }
@@ -140,13 +152,72 @@ ngx_resolver_create(ngx_peer_addr_t *add
         uc->sockaddr = addr->sockaddr;
         uc->socklen = addr->socklen;
         uc->server = addr->name;
-        uc->log = log;
+        uc->log = pool->log;
     }
 
     return r;
 }
 
 
+static void
+ngx_resolver_cleanup(void *data)
+{
+    ngx_resolver_t  *r = data;
+
+    if (r) {
+        ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
+                       "cleanup resolver");
+
+        ngx_resolver_cleanup_tree(r, &r->name_rbtree);
+
+        ngx_resolver_cleanup_tree(r, &r->addr_rbtree);
+
+        if (r->event) {
+            ngx_free(r->event);
+        }
+
+        if (r->udp_connection) {
+            if (r->udp_connection->connection) {
+                ngx_close_connection(r->udp_connection->connection);
+            }
+
+            ngx_free(r->udp_connection);
+        }
+
+        ngx_free(r);
+    }
+}
+
+
+static void
+ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree)
+{
+    ngx_resolver_ctx_t   *ctx, *next;
+    ngx_resolver_node_t  *rn;
+
+    while (tree->root != tree->sentinel) {
+
+        rn = (ngx_resolver_node_t *) ngx_rbtree_min(tree->root, tree->sentinel);
+
+        ngx_queue_remove(&rn->queue);
+
+        for (ctx = rn->waiting; ctx; ctx = next) {
+            next = ctx->next; 
+
+            if (ctx->event) {
+                ngx_resolver_free(r, ctx->event);
+            }
+
+            ngx_resolver_free(r, ctx);
+        }
+
+        ngx_rbtree_delete(tree, &rn->node);
+
+        ngx_resolver_free_node(r, rn);
+    }
+}
+
+
 ngx_resolver_ctx_t *
 ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
 {
@@ -707,6 +778,7 @@ ngx_resolver_send_query(ngx_resolver_t *
 
         uc->connection->data = r;
         uc->connection->read->handler = ngx_resolver_read_response;
+        uc->connection->read->resolver = 1;
     }
 
     n = ngx_send(uc->connection, rn->query, rn->qlen);
--- a/src/core/ngx_resolver.h
+++ b/src/core/ngx_resolver.h
@@ -131,7 +131,7 @@ struct ngx_resolver_ctx_s {
 };
 
 
-ngx_resolver_t *ngx_resolver_create(ngx_peer_addr_t *addr, ngx_log_t *log);
+ngx_resolver_t *ngx_resolver_create(ngx_pool_t *pool, ngx_peer_addr_t *addr);
 ngx_resolver_ctx_t *ngx_resolve_start(ngx_resolver_t *r,
     ngx_resolver_ctx_t *temp);
 ngx_int_t ngx_resolve_name(ngx_resolver_ctx_t *ctx);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2910,7 +2910,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
         conf->resolver = prev->resolver;
 
         if (conf->resolver == NULL) {
-            conf->resolver = ngx_resolver_create(NULL, cf->cycle->new_log);
+            conf->resolver = ngx_resolver_create(cf->pool, NULL);
             if (conf->resolver == NULL) {
                 return NGX_CONF_ERROR;
             }
@@ -3728,7 +3728,7 @@ ngx_http_core_resolver(ngx_conf_t *cf, n
         return NGX_CONF_ERROR;
     }
 
-    clcf->resolver = ngx_resolver_create(&u.addrs[0], cf->cycle->new_log);
+    clcf->resolver = ngx_resolver_create(cf->pool, &u.addrs[0]);
     if (clcf->resolver == NULL) {
         return NGX_OK;
     }
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -437,7 +437,7 @@ ngx_mail_core_resolver(ngx_conf_t *cf, n
         return NGX_CONF_ERROR;
     }
 
-    cscf->resolver = ngx_resolver_create(&u.addrs[0], cf->cycle->new_log);
+    cscf->resolver = ngx_resolver_create(cf->pool, &u.addrs[0]);
     if (cscf->resolver == NULL) {
         return NGX_CONF_OK;
     }