int su_home_mutex_lock(su_home_t *home) #endif { int error; if (home == NULL) return su_seterrno(EFAULT); #if (defined(HAVE_MEMLEAK_LOG) && (HAVE_MEMLEAK_LOG != 1)) if (home->suh_blocks == NULL || !_su_home_ref_by(home, file, line, function)) #else if (home->suh_blocks == NULL || !su_home_ref(home)) #endif return su_seterrno(EINVAL); /* Uninitialized home */ if (!home->suh_lock) return 0; /* No-op */ error = _su_home_mutex_locker(home->suh_lock); if (error) return su_seterrno(error); return 0; }
/** @internal Add dialog usage */ nua_dialog_usage_t *nua_dialog_usage_add(nua_owner_t *own, struct nua_dialog_state *ds, nua_usage_class const *uclass, sip_event_t const *event) { if (ds) { sip_event_t *o; nua_dialog_usage_t *du, **prev_du; prev_du = nua_dialog_usage_at(ds, uclass, event); du = *prev_du; if (du) { /* Already exists */ SU_DEBUG_5(("nua(%p): adding already existing %s usage%s%s\n", (void *)own, nua_dialog_usage_name(du), event ? " with event " : "", event ? event->o_type : "")); if (prev_du != &ds->ds_usage) { /* Move as a first usage in the list */ *prev_du = du->du_next; du->du_next = ds->ds_usage; ds->ds_usage = du; } return du; } o = event ? sip_event_dup(own, event) : NULL; if (o != NULL || event == NULL) du = su_zalloc(own, sizeof *du + uclass->usage_size); if (du) { su_home_ref(own); du->du_dialog = ds; du->du_class = uclass; du->du_event = o; if (uclass->usage_add(own, ds, du) < 0) { su_home_unref(own); su_free(own, o); su_free(own, du); return NULL; } SU_DEBUG_5(("nua(%p): adding %s usage%s%s\n", (void *)own, nua_dialog_usage_name(du), o ? " with event " : "", o ? o->o_type :"")); du->du_next = ds->ds_usage, ds->ds_usage = du; return du; } su_free(own, o); } return NULL; }
/** Increase reference count on a resolver cache object. */ sres_cache_t *sres_cache_ref(sres_cache_t *cache) { return su_home_ref(cache->cache_home); }
/** Test basic memory home operations */ static int test_alloc(void) { exhome_t *h0, *h1, *h2, *h3; su_home_t home[1] = { SU_HOME_INIT(home) }; su_home_t home0[1]; enum { N = 40 }; void *m0[N], *m1[N], *m; char *c, *c0, *p0, *p1; int i; enum { destructed_once = 1 }; int d0, d1a, d1, d2, d3; BEGIN(); /* su_home_init() was not initializing suh_locks */ memset(home0, 0xff, sizeof home0); TEST(su_home_init(home0), 0); TEST_VOID(su_home_deinit(home0)); TEST_1(h0 = su_home_new(sizeof(*h0))); TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1))); d0 = d1a = d1 = d2 = d3 = 0; h0->p = &d0; h1->p = &d1a; TEST(su_home_destructor(h0->home, exdestructor), 0); TEST(su_home_destructor(h1->home, exdestructor), 0); TEST_1(h2 = su_home_ref(h0->home)); su_home_unref(h0->home); TEST(d0, 0); for (i = 0; i < 128; i++) TEST_1(su_alloc(h0->home, 16)); for (i = 0; i < 128; i++) TEST_1(su_alloc(h1->home, 16)); su_home_unref(h1->home); TEST(d1a, destructed_once); TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1))); TEST(su_home_destructor(h1->home, exdestructor), 0); h1->p = &d1; for (i = 0; i < 128; i++) TEST_1(su_alloc(h1->home, 16)); for (i = 0; i < 128; i++) TEST_1(su_alloc(h2->home, 16)); su_home_unref(h2->home); /* Should call destructor of cloned home, too */ TEST(d0, destructed_once); TEST(d1, destructed_once); 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(su_home_threadsafe(h0->home), 0); for (i = 0; i < N; i++) { TEST_1(m0[i] = su_zalloc(h3->home, 20)); TEST_1(m1[i] = su_zalloc(h2->home, 20)); } TEST_1(m = su_zalloc(h2->home, 20)); TEST_1(su_in_home(h2->home, m)); TEST_1(!su_in_home(h2->home, (char *)m + 1)); TEST_1(!su_in_home(h2->home, (void *)(intptr_t)su_in_home)); TEST_1(!su_in_home(h3->home, m)); TEST_1(!su_in_home(NULL, m)); TEST_1(!su_in_home(h3->home, NULL)); TEST(su_home_move(home, NULL), 0); TEST(su_home_move(NULL, home), 0); TEST(su_home_move(home, h3->home), 0); TEST(su_home_move(h2->home, h3->home), 0); TEST(su_home_move(h1->home, h2->home), 0); su_home_preload(home, 1, 1024 + 2 * 8); TEST_1(c = su_zalloc(home, 64)); p0 = c; p1 = c + 1024; c0 = c; TEST_P(c = su_realloc(home, c0, 127), c0); TEST_1(c = c0 = su_zalloc(home, 1024 - 128)); TEST_1(p0 <= c); TEST_1(c < p1); TEST_P(c = su_realloc(home, c, 128), c0); TEST_P(c = su_realloc(home, c, 1023 - 128), c0); TEST_P(c = su_realloc(home, c, 1024 - 128), c0); TEST_1(c = su_realloc(home, c, 1024)); TEST_1(c = su_realloc(home, c, 2 * 1024)); TEST_P(c = su_realloc(home, p0, 126), p0); TEST_1(c = su_realloc(home, p0, 1024)); TEST_P(c = su_realloc(home, c, 0), NULL); su_home_check(home); su_home_deinit(home); su_home_check(h2->home); su_home_zap(h2->home); su_home_check(h0->home); su_home_zap(h0->home); { su_home_t h1[1]; memset(h1, 0, sizeof h1); TEST(su_home_init(h1), 0); TEST(su_home_threadsafe(h1), 0); TEST_1(su_home_ref(h1)); TEST_1(su_home_ref(h1)); TEST(su_home_destructor(h1, test_destructor), 0); TEST_1(!su_home_unref(h1)); TEST_1(!su_home_unref(h1)); TEST_1(su_home_unref(h1)); 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(); }
/** Create a new reference to an auth_status_t structure. * @relates auth_status_t */ auth_status_t *auth_status_ref(auth_status_t *as) { return (auth_status_t *)su_home_ref(as->as_home); }
/** Create a new reference to authentication module. */ auth_mod_t *auth_mod_ref(auth_mod_t *am) { return (auth_mod_t *)su_home_ref(am->am_home); }
void su_base_port_incref(su_port_t *self, char const *who) { su_home_ref(self->sup_home); PORT_REFCOUNT_DEBUG(("incref(%p) to %u by %s\n", self, su_home_refcount(self->sup_home), who)); }