Changeset 2124


Ignore:
Timestamp:
Jul 12, 2008 9:50:48 AM (11 years ago)
Author:
bennylp
Message:

Ticket #560: Optimize the memory usage of DNS resolver

Location:
pjproject/trunk/pjlib-util
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/include/pjlib-util/config.h

    r2039 r2124  
    179179 * (#pj_dns_packet_dup()) is also capable of performing name compressions. 
    180180 * 
    181  * Default: 1000 (as a broad guidance, 400 is good for 4 SRV entries). 
     181 * Default: 512 
    182182 */ 
    183183#ifndef PJ_DNS_RESOLVER_RES_BUF_SIZE 
    184 #   define PJ_DNS_RESOLVER_RES_BUF_SIZE             1000 
     184#   define PJ_DNS_RESOLVER_RES_BUF_SIZE             512 
    185185#endif 
    186186 
  • pjproject/trunk/pjlib-util/src/pjlib-util/resolver.c

    r2039 r2124  
    151151    PJ_DECL_LIST_MEMBER(struct cached_res); 
    152152 
     153    pj_pool_t               *pool;          /**< Cache's pool.              */ 
    153154    struct res_key           key;           /**< Resource key.              */ 
    154     char                     buf[RES_BUF_SZ];/**< Resource buffer.          */ 
    155155    pj_hash_entry_buf        hbuf;          /**< Hash buffer                */ 
    156156    pj_time_val              expiry_time;   /**< Expiration time.           */ 
     
    195195    /* Hash table for cached response */ 
    196196    pj_hash_table_t     *hrescache;     /**< Cached response in hash table  */ 
    197  
    198     /* Cached response free list */ 
    199     struct cached_res    res_free_nodes; 
    200197 
    201198    /* Pending asynchronous query, hashed by transaction ID. */ 
     
    296293    } 
    297294 
    298     /* Response cache hash table and item list */ 
     295    /* Response cache hash table */ 
    299296    resv->hrescache = pj_hash_create(pool, RES_HASH_TABLE_SIZE); 
    300     pj_list_init(&resv->res_free_nodes); 
    301297 
    302298    /* Query hash table and free list. */ 
     
    352348                                             pj_bool_t notify) 
    353349{ 
     350    pj_hash_iterator_t it_buf, *it; 
    354351    PJ_ASSERT_RETURN(resolver, PJ_EINVAL); 
    355352 
     
    358355         * Notify pending queries if requested. 
    359356         */ 
    360         pj_hash_iterator_t it_buf, *it; 
    361  
    362357        it = pj_hash_first(resolver->hquerybyid, &it_buf); 
    363358        while (it) { 
     
    378373    } 
    379374 
     375    /* Destroy cached entries */ 
     376    it = pj_hash_first(resolver->hrescache, &it_buf); 
     377    while (it) { 
     378        struct cached_res *cache; 
     379 
     380        cache = (struct cached_res*) pj_hash_this(resolver->hrescache, it); 
     381        pj_hash_set(NULL, resolver->hrescache, &cache->key,  
     382                    sizeof(cache->key), 0, NULL); 
     383        pj_pool_release(cache->pool); 
     384 
     385        it = pj_hash_first(resolver->hrescache, &it_buf); 
     386    } 
     387 
    380388    if (resolver->own_timer && resolver->timer) { 
    381389        pj_timer_heap_destroy(resolver->timer); 
     
    640648 
    641649 
     650/* Allocate new cache entry */ 
     651static struct cached_res *alloc_entry(pj_dns_resolver *resolver) 
     652{ 
     653    pj_pool_t *pool; 
     654    struct cached_res *cache; 
     655 
     656    pool = pj_pool_create(resolver->pool->factory, "dnscache", 
     657                          RES_BUF_SZ, 256, NULL); 
     658    cache = PJ_POOL_ZALLOC_T(pool, struct cached_res); 
     659    cache->pool = pool; 
     660 
     661    return cache; 
     662} 
     663 
     664/* Put unused/expired cached entry to the free list */ 
     665static void free_entry(pj_dns_resolver *resolver, struct cached_res *cache) 
     666{ 
     667    PJ_UNUSED_ARG(resolver); 
     668    pj_pool_release(cache->pool); 
     669} 
     670 
     671 
    642672/* 
    643673 * Create and start asynchronous DNS query for a single resource. 
     
    724754 
    725755        /* Store the entry into free nodes */ 
    726         pj_list_push_back(&resolver->res_free_nodes, cache); 
     756        free_entry(resolver, cache); 
    727757 
    728758        /* Must continue with creating a query now */ 
     
    10661096{ 
    10671097    struct cached_res *cache; 
    1068     pj_pool_t *res_pool; 
    10691098    pj_uint32_t hval=0, ttl; 
    1070     PJ_USE_EXCEPTION; 
    10711099 
    10721100    /* If status is unsuccessful, clear the same entry from the cache */ 
     
    10751103                                                  sizeof(*key), &hval); 
    10761104        if (cache) 
    1077             pj_list_push_back(&resolver->res_free_nodes, cache); 
     1105            free_entry(resolver, cache); 
    10781106        pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL); 
    10791107    } 
     
    11111139                                                  sizeof(*key), &hval); 
    11121140        if (cache) 
    1113             pj_list_push_back(&resolver->res_free_nodes, cache); 
     1141            free_entry(resolver, cache); 
    11141142        pj_hash_set(NULL, resolver->hrescache, key, sizeof(*key), hval, NULL); 
    11151143        return; 
     
    11201148                                              sizeof(*key), &hval); 
    11211149    if (cache == NULL) { 
    1122         if (!pj_list_empty(&resolver->res_free_nodes)) { 
    1123             cache = resolver->res_free_nodes.next; 
    1124             pj_list_erase(cache); 
    1125         } else { 
    1126             cache = PJ_POOL_ZALLOC_T(resolver->pool, struct cached_res); 
    1127         } 
     1150        cache = alloc_entry(resolver); 
    11281151    } 
    11291152 
     
    11341157     * the name being requested. 
    11351158     */ 
    1136     res_pool = pj_pool_create_on_buf("respool", cache->buf, sizeof(cache->buf)); 
    1137     PJ_TRY { 
    1138         cache->pkt = NULL; 
    1139         pj_dns_packet_dup(res_pool, pkt,  
    1140                           PJ_DNS_NO_NS | PJ_DNS_NO_AR, 
    1141                           &cache->pkt); 
    1142     } 
    1143     PJ_CATCH_ANY { 
    1144         PJ_LOG(1,(THIS_FILE,  
    1145                   "Not enough memory to duplicate DNS response. Response was " 
    1146                   "truncated.")); 
    1147     } 
    1148     PJ_END; 
     1159    cache->pkt = NULL; 
     1160    pj_dns_packet_dup(cache->pool, pkt,  
     1161                      PJ_DNS_NO_NS | PJ_DNS_NO_AR, 
     1162                      &cache->pkt); 
    11491163 
    11501164    /* Calculate expiration time */ 
     
    11631177    pj_hash_set_np(resolver->hrescache, &cache->key, sizeof(*key), hval, 
    11641178                   cache->hbuf, cache); 
     1179 
    11651180} 
    11661181 
     
    12531268{ 
    12541269    pj_dns_resolver *resolver; 
    1255     pj_pool_t *pool; 
     1270    pj_pool_t *pool = NULL; 
    12561271    pj_dns_parsed_packet *dns_pkt; 
    12571272    pj_dns_async_query *q; 
     
    13831398 
    13841399read_next_packet: 
     1400    if (pool) { 
     1401        /* needed just in case PJ_HAS_POOL_ALT_API is set */ 
     1402        pj_pool_release(pool); 
     1403    } 
    13851404    bytes_read = sizeof(resolver->udp_rx_pkt); 
    13861405    resolver->udp_addr_len = sizeof(resolver->udp_src_addr); 
     
    15161535        } 
    15171536    } 
    1518     PJ_LOG(3,(resolver->name.ptr, "  Nb. of cached response free nodes: %u", 
    1519               pj_list_size(&resolver->res_free_nodes))); 
    15201537    PJ_LOG(3,(resolver->name.ptr, "  Nb. of pending queries: %u (%u)", 
    15211538              pj_hash_count(resolver->hquerybyid), 
Note: See TracChangeset for help on using the changeset viewer.