diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index eedce43f86..28c5db7694 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Thu Feb 12 15:13:11 CST 2009 +Thu Feb 12 15:14:36 CST 2009 diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h b/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h index 9eb8ab642b..4af3b95abe 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sofia-resolv/sres_cache.h @@ -90,6 +90,10 @@ SRESPUBFUN void sres_cache_free_answers(sres_cache_t *, sres_record_t **); /** Free and zero one record. */ SRESPUBFUN void sres_cache_free_one(sres_cache_t *, sres_record_t *answer); +/** Copy list of records */ +SRESPUBFUN +sres_record_t **sres_cache_copy_answers(sres_cache_t *, sres_record_t **); + /** Remove old records from cache. */ SRESPUBFUN void sres_cache_clean(sres_cache_t *cache, time_t now); diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c index 7c5a6bfe1a..902cc3651b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres_cache.c @@ -131,6 +131,8 @@ su_inline void _sres_cache_free_one(sres_cache_t *cache, sres_record_t *answer); su_inline void _sres_cache_free_answers(sres_cache_t *cache, sres_record_t **answers); +su_inline sres_record_t **_sres_cache_copy_answers( + sres_cache_t *, sres_record_t **); static unsigned sres_hash_key(const char *string); @@ -458,6 +460,20 @@ void sres_cache_free_one(sres_cache_t *cache, sres_record_t *answer) } } +/** Copy the list of records. */ +sres_record_t ** +sres_cache_copy_answers(sres_cache_t *cache, sres_record_t **answers) +{ + sres_record_t **copy = NULL; + + if (answers && LOCK(cache)) { + copy = _sres_cache_copy_answers(cache, answers); + UNLOCK(cache); + } + + return copy; +} + /* ---------------------------------------------------------------------- */ /* Private functions */ @@ -488,6 +504,29 @@ void _sres_cache_free_one(sres_cache_t *cache, sres_record_t *answer) } } +su_inline sres_record_t ** +_sres_cache_copy_answers(sres_cache_t *cache, sres_record_t **answers) +{ + int i, n; + sres_record_t **copy; + + for (n = 0; answers[n] != NULL; n++) + ; + + copy = su_alloc(cache->cache_home, (n + 1) * (sizeof *copy)); + if (copy == NULL) + return NULL; + + for (i = 0; i < n; i++) { + copy[i] = answers[i]; + copy[i]->sr_refcount++; + } + + copy[i] = NULL; + + return copy; +} + /** Calculate a hash key for a string */ static unsigned diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c index d499d10392..82fb92b64e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/torture_sresolv.c @@ -234,6 +234,7 @@ int test_cache(void) BEGIN(); sres_a_record_t *a, a0[1], **all; + sres_record_t **copy; char host[128]; sres_cache_t *cache; time_t now, base; @@ -292,6 +293,11 @@ int test_cache(void) for (i = 0, N; i < N; i++) TEST(all[i]->a_record->r_refcount, 2); + TEST_1(copy = sres_cache_copy_answers(cache, (sres_record_t **)all)); + + for (i = 0, N; i < N; i++) + TEST(all[i]->a_record->r_refcount, 3); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t0); for (now = base; now <= base + 3660; now += 30) @@ -306,6 +312,11 @@ int test_cache(void) (unsigned)N, (long unsigned)t2.tv_sec, t2.tv_nsec); } + for (i = 0, N; i < N; i++) + TEST(all[i]->a_record->r_refcount, 2); + + sres_cache_free_answers(cache, copy), copy = NULL; + for (i = 0, N; i < N; i++) TEST(all[i]->a_record->r_refcount, 1);