diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index a4e263457e..3bf2c4c1d0 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Feb 25 13:40:08 CST 2009 +Thu Feb 26 12:22:23 CST 2009 diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h index 3a9f31f2f0..8af6ddebd5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_alloc.h @@ -101,6 +101,8 @@ SU_DLL int su_home_threadsafe(su_home_t *home); SU_DLL int su_home_has_parent(su_home_t const *home); +SU_DLL su_home_t *su_home_parent(su_home_t const *home); + SU_DLL void su_home_check(su_home_t const *home); SU_DLL int su_home_check_alloc(su_home_t const *home, void const *data); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c index 247f93eb41..075bd77e95 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c @@ -746,8 +746,21 @@ void *su_home_clone(su_home_t *parent, isize_t size) /** Return true if home is a clone. */ int su_home_has_parent(su_home_t const *home) { - return home && !home->suh_lock && - home->suh_blocks && home->suh_blocks->sub_parent; + return su_home_parent(home) != NULL; +} + +/** Return home's parent home. */ +su_home_t *su_home_parent(su_home_t const *home) +{ + su_home_t *parent = NULL; + + if (home && home->suh_blocks) { + su_block_t *sub = MEMLOCK(home); + parent = sub->sub_parent; + UNLOCK(home); + } + + return parent; } /** Allocate a memory block. @@ -1134,6 +1147,12 @@ int su_home_move(su_home_t *dst, su_home_t *src) for (i = 0; i < n; i++) if (s->sub_nodes[i].sua_data) { su_block_add(d, s->sub_nodes[i].sua_data)[0] = s->sub_nodes[i]; + if (s->sub_nodes[i].sua_home) { + su_home_t *subhome = s->sub_nodes[i].sua_data; + su_block_t *subsub = MEMLOCK(subhome); + subsub->sub_parent = dst; + UNLOCK(subhome); + } } s->sub_used = 0; @@ -1152,8 +1171,21 @@ int su_home_move(su_home_t *dst, su_home_t *src) s = MEMLOCK(src); if (s && s->sub_used) { + n = s->sub_n; + + for (i = 0; i < n; i++) { + if (s->sub_nodes[i].sua_data && s->sub_nodes[i].sua_home) { + su_home_t *subhome = s->sub_nodes[i].sua_data; + su_block_t *subsub = MEMLOCK(subhome); + subsub->sub_parent = dst; + UNLOCK(subhome); + } + } + s->sub_used = 0; memset(s->sub_nodes, 0, s->sub_n * sizeof (s->sub_nodes[0])); + + s->sub_used = 0; } UNLOCK(src); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c b/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c index 336422aaf5..d8f7d0078d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/torture_su_alloc.c @@ -192,6 +192,34 @@ static int test_alloc(void) TEST(h1->suh_size, 13); } + /* Test su_home_parent() */ + TEST_1(h0 = su_home_new(sizeof *h0)); + TEST_1(h1 = su_home_clone(h0->home, sizeof *h1)); + TEST_1(h2 = su_home_clone(h1->home, sizeof *h2)); + TEST_1(h3 = su_home_clone(h2->home, sizeof *h3)); + + TEST_P(su_home_parent(h0->home), NULL); + TEST_P(su_home_parent(h1->home), h0); + TEST_P(su_home_parent(h2->home), h1); + TEST_P(su_home_parent(h3->home), h2); + TEST(su_home_move(h0->home, h1->home), 0); + TEST_P(su_home_parent(h2->home), h0); + TEST_P(su_home_parent(h3->home), h2); + TEST(su_home_move(h0->home, h2->home), 0); + TEST_P(su_home_parent(h3->home), h0); + + su_home_move(NULL, h0->home); + + TEST_P(su_home_parent(h0->home), NULL); + TEST_P(su_home_parent(h1->home), NULL); + TEST_P(su_home_parent(h2->home), NULL); + TEST_P(su_home_parent(h3->home), NULL); + + su_home_unref(h0->home); + su_home_unref(h1->home); + su_home_unref(h2->home); + su_home_unref(h3->home); + END(); }