/** * Create a message. * * @relatesalso msg_s * * @param mc message class * @param flags message control flags */ msg_t *msg_create(msg_mclass_t const *mc, int flags) { msg_t *msg = su_home_new(sizeof(*msg) + mc->mc_msize); if (msg) { if ((flags & MSG_FLG_THRDSAFE) && su_home_threadsafe(msg->m_home) < 0) { su_home_unref(msg->m_home); return NULL; } msg->m_refs++; msg->m_tail = &msg->m_chain; msg->m_addrinfo.ai_addrlen = sizeof(msg->m_addr); msg->m_addrinfo.ai_addr = &msg->m_addr->su_sa; msg->m_maxsize = 0; flags &= MSG_FLG_USERMASK; msg->m_class = mc; msg->m_oflags = flags; msg->m_object = (void *)(msg + 1); msg->m_object->msg_size = mc->mc_msize; msg->m_object->msg_flags = mc->mc_flags | flags; msg->m_object->msg_common->h_class = (void *)mc; } return msg; }
nth_engine_t *nth_engine_create(su_root_t *root, tag_type_t tag, tag_value_t value, ...) { nth_engine_t *he; ta_list ta; if ((he = su_home_new(sizeof(*he)))) { he->he_root = root; he->he_mflags = MSG_DO_CANONIC; he->he_mclass = http_default_mclass(); he->he_expires = 32000; ta_start(ta, tag, value); if (hc_htable_resize(he->he_home, he->he_clients, 0) < 0 || he_create_tports(he, ta_args(ta)) < 0 || he_timer_init(he) < 0 || nth_engine_set_params(he, ta_tags(ta)) < 0) { nth_engine_destroy(he), he = NULL; } ta_end(ta); } return he; }
static apt_bool_t mrcp_unirtsp_session_create(rtsp_server_t *rtsp_server, rtsp_server_session_t *rtsp_session) { mrcp_unirtsp_agent_t *agent = rtsp_server_object_get(rtsp_server); const apt_str_t *session_id; mrcp_unirtsp_session_t *session; mrcp_session_t* mrcp_session = agent->sig_agent->create_server_session(agent->sig_agent); if(!mrcp_session) { return FALSE; } session_id = rtsp_server_session_id_get(rtsp_session); if(session_id) { mrcp_session->id = *session_id; } mrcp_session->response_vtable = &session_response_vtable; mrcp_session->event_vtable = NULL; session = apr_palloc(mrcp_session->pool,sizeof(mrcp_unirtsp_session_t)); session->mrcp_session = mrcp_session; mrcp_session->obj = session; session->home = su_home_new(sizeof(*session->home)); rtsp_server_session_object_set(rtsp_session,session); session->rtsp_session = rtsp_session; return TRUE; }
static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *mrcp_session, const mrcp_sig_settings_t *settings) { mrcp_unirtsp_agent_t *agent = mrcp_session->signaling_agent->obj; mrcp_unirtsp_session_t *session; mrcp_session->request_vtable = &session_request_vtable; session = apr_palloc(mrcp_session->pool,sizeof(mrcp_unirtsp_session_t)); session->home = su_home_new(sizeof(*session->home)); session->rtsp_settings = settings; session->mrcp_message = NULL; session->mrcp_session = mrcp_session; mrcp_session->obj = session; session->rtsp_session = rtsp_client_session_create( agent->rtsp_client, session->rtsp_settings->server_ip, session->rtsp_settings->server_port, session->rtsp_settings->resource_location); if(!session->rtsp_session) { su_home_unref(session->home); return FALSE; } rtsp_client_session_object_set(session->rtsp_session,session); return TRUE; }
/* SDP Initialization */ int janus_sdp_init() { home = su_home_new(sizeof(su_home_t)); if(su_home_init(home) < 0) { JANUS_PRINT("Ops, error setting up sofia-sdp?\n"); return -1; } return 0; }
/* SDP Initialization */ int janus_sdp_init(void) { home = su_home_new(sizeof(su_home_t)); if(su_home_init(home) < 0) { JANUS_LOG(LOG_FATAL, "Ops, error setting up sofia-sdp?\n"); return -1; } return 0; }
static void ssc_media_init (SscMedia *object) { SscMedia *self = SSC_MEDIA (object); self->sm_home = su_home_new(sizeof (*self->sm_home)); g_debug("%s:%d", __func__, __LINE__); }
static void etsi_setup(void) { nua = s2_nua_setup("ETSI", NUTAG_OUTBOUND("no-options-keepalive, no-validate"), TAG_END()); soa = soa_create(NULL, s2base->root, NULL); fail_if(!soa); soa_set_params(soa, SOATAG_USER_SDP_STR("m=audio 5008 RTP/AVP 8 0" CRLF "m=video 5010 RTP/AVP 34" CRLF), TAG_END()); d1 = su_home_new(sizeof *d1); fail_if(!d1); d2 = su_home_new(sizeof *d2); fail_if(!d2); }
static tls_t *tls_create(int type) { tls_t *tls = su_home_new(sizeof(*tls)); if (tls) tls->type = type == tls_master ? tls_master : tls_slave; return tls; }
/**Allocate an authentication module instance. * * The function auth_mod_alloc() allocates an authentication module object. * */ auth_mod_t *auth_mod_alloc(auth_scheme_t *scheme, tag_type_t tag, tag_value_t value, ...) { auth_mod_t *am = NULL; if ((am = su_home_new(scheme->asch_size))) { am->am_scheme = scheme; su_home_destructor(am->am_home, auth_call_scheme_destructor); } return am; }
void s2_dialog_setup(void) { nua = s2_nua_setup("simple", SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"), NUTAG_OUTBOUND("no-options-keepalive, no-validate"), TAG_END()); dialog = su_home_new(sizeof *dialog); fail_if(!dialog); s2_register_setup(); }
/** Create a resolver cache object. * * @param n initial size of cache */ sres_cache_t *sres_cache_new(int n) { sres_cache_t *cache = su_home_new(sizeof *cache); if (cache) { su_home_threadsafe(cache->cache_home); if (sres_htable_resize(cache->cache_home, cache->cache_hash, n) < 0 || sres_heap_resize(cache->cache_home, &cache->cache_heap, 0) < 0) su_home_unref(cache->cache_home), cache = NULL; } return cache; }
/** Create a port using epoll() or poll(). */ su_port_t *su_poll_port_create(void) { su_port_t *self = su_home_new(sizeof *self); if (!self) return self; if (su_home_destructor(su_port_home(self), su_poll_port_deinit) < 0) return su_home_unref(su_port_home(self)), NULL; self->sup_multishot = SU_ENABLE_MULTISHOT_POLL; if (su_socket_port_init(self->sup_base, su_poll_port_vtable) < 0) return su_home_unref(su_port_home(self)), NULL; return self; }
static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session, mrcp_sig_settings_t *settings) { mrcp_sofia_agent_t *sofia_agent = mrcp_sofia_agent_get(session); mrcp_sofia_session_t *sofia_session; session->request_vtable = &session_request_vtable; if(!sofia_agent->nua) { return FALSE; } sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t)); sofia_session->mutex = NULL; sofia_session->home = su_home_new(sizeof(*sofia_session->home)); sofia_session->session = session; sofia_session->sip_settings = settings; sofia_session->terminate_requested = FALSE; sofia_session->descriptor = NULL; session->obj = sofia_session; if(settings->user_name && settings->user_name != '\0') { sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s@%s:%hu", settings->user_name, settings->server_ip, settings->server_port); } else { sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s:%hu", settings->server_ip, settings->server_port); } sofia_session->nh = nua_handle( sofia_agent->nua, sofia_session, SIPTAG_TO_STR(sofia_session->sip_to_str), SIPTAG_FROM_STR(sofia_agent->sip_from_str), SIPTAG_CONTACT_STR(sofia_agent->sip_contact_str), TAG_IF(settings->feature_tags,SIPTAG_ACCEPT_CONTACT_STR(settings->feature_tags)), TAG_END()); sofia_session->nua_state = nua_callstate_init; apr_thread_mutex_create(&sofia_session->mutex,APR_THREAD_MUTEX_DEFAULT,session->pool); return TRUE; }
END_TEST START_TEST(subscribe_6_1_4) { nua_handle_t *nh; struct message *response; struct event *notify, *event; S2_CASE("6.1.4", "Subscription terminated by notifier, re-established", "NUA sends SUBSCRIBE, waits for NOTIFY, " "gets NOTIFY terminating the subscription,"); nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END()); nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END()); notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END()); s2_free_event(notify); fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL, SIPTAG_EVENT_STR(event_type), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=deactivated"), TAG_END())); event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event); fail_unless(s2_check_substate(event, nua_substate_embryonic)); s2_free_event(event); response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY); fail_if(!response); s2_sip_free_message(response); su_home_unref((void *)dialog), dialog = su_home_new(sizeof *dialog); fail_if(!dialog); s2_nua_fast_forward(5, s2base->root); /* nua re-establishes the subscription */ notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END()); s2_free_event(notify); /* Unsubscribe with nua_subscribe() Expires: 0 */ nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END()); notify = subscription_by_nua(nh, nua_substate_active, TAG_END()); s2_free_event(notify); nua_handle_destroy(nh); }
nua_t *s2_nua_setup(char const *label, tag_type_t tag, tag_value_t value, ...) { ta_list ta; s2_setup(label); s2 = su_home_new(sizeof *s2); s2_dns_setup(s2base->root); s2_setup_logs(0); s2_sip_setup("example.org", NULL, TAG_END()); assert(s2sip->contact); s2_dns_domain("example.org", 1, "s2", 1, s2sip->udp.contact->m_url, "s2", 1, s2sip->tcp.contact->m_url, NULL); /* enable/disable multithreading */ su_root_threading(s2base->root, s2_nua_thread); ta_start(ta, tag, value); s2->nua = nua_create(s2base->root, s2_nua_callback, s2, SIPTAG_FROM_STR("Alice <sip:[email protected]>"), /* NUTAG_PROXY((url_string_t *)s2sip->contact->m_url), */ /* Use internal DNS server */ NUTAG_PROXY("sip:example.org"), /* Force sresolv to use localhost and s2dns as DNS server */ #if HAVE_WIN32 SRESTAG_RESOLV_CONF("NUL"), #else SRESTAG_RESOLV_CONF("/dev/null"), #endif ta_tags(ta)); ta_end(ta); return s2->nua; }
static mrcp_sofia_session_t* mrcp_sofia_session_create(mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh) { mrcp_sofia_session_t *sofia_session; mrcp_session_t* session = sofia_agent->sig_agent->create_server_session(sofia_agent->sig_agent); if(!session) { return NULL; } session->response_vtable = &session_response_vtable; session->event_vtable = NULL; sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t)); sofia_session->home = su_home_new(sizeof(*sofia_session->home)); sofia_session->session = session; session->obj = sofia_session; nua_handle_bind(nh, sofia_session); sofia_session->nh = nh; return sofia_session; }
static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session) { mrcp_sofia_agent_t *sofia_agent = session->signaling_agent->obj; mrcp_sofia_session_t *sofia_session; session->request_vtable = &session_request_vtable; sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t)); sofia_session->home = su_home_new(sizeof(*sofia_session->home)); sofia_session->session = session; sofia_session->terminate_requested = FALSE; session->obj = sofia_session; sofia_session->nh = nua_handle( sofia_agent->nua, sofia_session, SIPTAG_TO_STR(sofia_agent->sip_to_str), SIPTAG_FROM_STR(sofia_agent->sip_from_str), SIPTAG_CONTACT_STR(sofia_agent->sip_contact_str), TAG_END()); return TRUE; }
static void invite_setup(void) { dialog = su_home_new(sizeof *dialog); fail_unless(dialog != NULL); s2_nta_setup("NTA", NULL, TAG_END()); fail_unless(s2sip->udp.contact != NULL); s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL, NTATAG_UA(1), TAG_END()); leg = nta_leg_tcreate(s2->nta, NULL, NULL, SIPTAG_FROM_STR("<sip:[email protected]>"), SIPTAG_TO_STR("<sip:test2.3.1.example.org>"), TAG_END()); fail_unless(leg != NULL); }
/** Create a port using /dev/poll or poll(). */ su_port_t *su_devpoll_port_create(void) { su_port_t *self; int devpoll = open("/dev/poll", O_RDWR); if (devpoll == -1) { /* Fallback to poll() */ SU_DEBUG_3(("%s(): open(\"%s\") => %u: %s\n", "su_devpoll_port_create", "/dev/poll", errno, strerror(errno))); return su_poll_port_create(); } self = su_home_new(sizeof *self); if (!self) { close(devpoll); return self; } if (su_home_destructor(su_port_home(self), su_devpoll_port_deinit) < 0 || !(self->sup_indices = su_zalloc(su_port_home(self), (sizeof self->sup_indices[0]) * (self->sup_size_indices = 64)))) { su_home_unref(su_port_home(self)); close(devpoll); return NULL; } self->sup_devpoll = devpoll; self->sup_multishot = SU_ENABLE_MULTISHOT_POLL; if (su_socket_port_init(self->sup_base, su_devpoll_port_vtable) < 0) return su_home_unref(su_port_home(self)), NULL; SU_DEBUG_9(("%s(%p): devpoll_create() => %u: %s\n", "su_port_create", (void *)self, self->sup_devpoll, "OK")); return self; }
/**Clone a su_home_t object. * * Clone a secondary home object used to collect multiple memoryf * allocations under one handle. The memory is freed either when the cloned * home is destroyed or when the parent home is destroyed. * * An independent * home object is created if NULL is passed as @a parent argument. * * @param parent a parent object (may be NULL) * @param size size of home object * * The memory home object allocated with su_home_clone() can be freed with * su_home_unref(). * * @return * This function returns a pointer to an su_home_t object, or NULL upon * an error. */ void *su_home_clone(su_home_t *parent, isize_t size) { su_home_t *home; assert(size >= sizeof (*home)); if (size < sizeof (*home)) return (void)(errno = EINVAL), NULL; else if (size > INT_MAX) return (void)(errno = ENOMEM), NULL; if (parent) { su_block_t *sub = MEMLOCK(parent); home = sub_alloc(parent, sub, size, (enum sub_zero)2); UNLOCK(parent); } else { home = su_home_new(size); } return home; }
/** * Create an su_home_t object. * * Creates a home object. A home object is used to collect multiple memory * allocations, so that they all can be freed by calling su_home_unref(). * * @return This function returns a pointer to an #su_home_t object, or * NULL upon an error. */ su_home_t *su_home_create(void) { return su_home_new(sizeof(su_home_t)); }
server_t *server_create(url_t const *url, tag_type_t tag, tag_value_t value, ...) { server_t *srv; msg_mclass_t const *mclass = NULL; tp_name_t tpn[1] = {{ NULL }}; su_root_t *root = NULL; http_server_t const *server = NULL; int persistent = 0; char const *server_str = SERVER_VERSION; ta_list ta; ta_start(ta, tag, value); tl_gets(ta_args(ta), NTHTAG_ROOT_REF(root), NTHTAG_MCLASS_REF(mclass), TPTAG_REUSE_REF(persistent), HTTPTAG_SERVER_REF(server), HTTPTAG_SERVER_STR_REF(server_str), TAG_END()); if (!root || !url || (url->url_type != url_http && url->url_type != url_https) || !(srv = su_home_new(sizeof(*srv)))) { ta_end(ta); return NULL; } tpn->tpn_proto = url_tport_default((enum url_type_e)url->url_type); tpn->tpn_canon = url->url_host; tpn->tpn_host = url->url_host; tpn->tpn_port = url_port(url); srv->srv_tports = tport_tcreate(srv, nth_server_class, root, TPTAG_IDLE(600000), TPTAG_TIMEOUT(300000), ta_tags(ta)); srv->srv_persistent = persistent; srv->srv_max_bodylen = 1 << 30; /* 1 GB */ if (tport_tbind(srv->srv_tports, tpn, http_tports, TAG_END()) >= 0 || tport_tbind(srv->srv_tports, tpn, http_no_tls_tports, TAG_END()) >= 0) { srv->srv_root = root; srv->srv_mclass = mclass ? mclass : http_default_mclass(); srv->srv_mflags = MSG_DO_CANONIC; if (server) srv->srv_server = http_server_dup(srv->srv_home, server); else srv->srv_server = http_server_make(srv->srv_home, server_str); tport_get_params(srv->srv_tports, TPTAG_QUEUESIZE_REF(srv->srv_queuesize), TAG_END()); } else { SU_DEBUG_1(("nth_server_create: cannot bind transports " URL_FORMAT_STRING "\n", URL_PRINT_ARGS(url))); server_destroy(srv), srv = NULL; } ta_end(ta); return srv; }
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) { int exitcode = 0; int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1; int family = 0, multiple = 0; char const *dnsserver = NULL; char const *string; url_t *uri = NULL; char const *host; char const *port; char *transport = NULL, tport[32]; int argc; char *argv_[25] = { 0 }; char *mycmd = NULL; char **argv; struct dig dig[1] = {{ NULL }}; su_home_t *home = NULL; int xml = 0; home = su_home_new(sizeof(*home)); argv = argv_; argv++; if (!cmd) { {usage(1);} } mycmd = strdup(cmd); argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv_) / sizeof(argv_[0])) - 1); argv = argv_; if (!argv[1]) { {usage(1);} } if (!strcasecmp(argv[1], "xml")) { switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "xml", "true"); argv++; xml++; } argv[0] = "sofia_dig"; //if (su_init() != 0) //return -1; while (argv[1] && argv[1][0] == '-') { if (strcmp(argv[1], "-v") == 0) o_verbatim++; else if (strcmp(argv[1], "-6") == 0) dig->ip6 = ++family; else if (strcmp(argv[1], "-4") == 0) dig->ip4 = ++family; else if (strncmp(argv[1], "-p", 2) == 0) { char const *proto; if (argv[1][2] == '=') proto = argv[1] + 3; else if (argv[1][2]) proto = argv[1] + 2; else proto = argv++[2]; if (proto == NULL) {usage(2);} if (prepare_transport(dig, proto) < 0) { goto fail; } } else if (strcmp(argv[1], "--udp") == 0) prepare_transport(dig, "udp"); else if (strcmp(argv[1], "--tcp") == 0) prepare_transport(dig, "tcp"); else if (strcmp(argv[1], "--tls") == 0) prepare_transport(dig, "tls"); else if (strcmp(argv[1], "--sctp") == 0) prepare_transport(dig, "sctp"); else if (strcmp(argv[1], "--tls-sctp") == 0) prepare_transport(dig, "tls-sctp"); else if (strcmp(argv[1], "--tls-udp") == 0) prepare_transport(dig, "tls-udp"); else if (strcmp(argv[1], "--no-sctp") == 0) o_sctp = 0, o_tls_sctp = 0; else if (strcmp(argv[1], "--help") == 0) {usage(0);} else if (strcmp(argv[1], "-h") == 0) {usage(0);} else if (strcmp(argv[1], "-?") == 0) {usage(0);} else if (strcmp(argv++[1], "-") == 0) break; else {usage(2);} argv++; } if (xml) { stream->write_function(stream, "%s", "<routes>\n"); } else { stream->write_function(stream, "%10s\t%10s\t%10s\t%10s\t%10s\n", "Preference", "Weight", "Transport", "Port", "Address"); stream->write_function(stream, "================================================================================\n"); } if (!family) dig->ip4 = 1, dig->ip6 = 2; if (argv[1] && argv[1][0] == '@') dnsserver = argv++[1] + 1; if (!argv[1]) {usage(2);} multiple = argv[1] && argv[2]; if (!count_transports(dig, NULL, NULL)) { prepare_transport(dig, "udp"); prepare_transport(dig, "tcp"); if (o_sctp) prepare_transport(dig, "sctp"); prepare_transport(dig, "tls"); if (o_tls_sctp) prepare_transport(dig, "tls-sctp"); } dig->sres = sres_resolver_new(getenv("SRESOLV_CONF")); if (!dig->sres) {usage(1);} for (; (string = argv[1]); argv++) { if (multiple) stream->write_function(stream, "%s", string); uri = url_hdup(home, (void *)string); if (uri && uri->url_type == url_unknown) url_sanitize(uri); if (uri && uri->url_type == url_any) continue; if (!uri || (uri->url_type != url_sip && uri->url_type != url_sips)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid uri\n", string); exitcode = 1; continue; } port = url_port(uri); if (port && !port[0]) port = NULL; if (url_param(uri->url_params, "transport=", tport, sizeof tport) > 0) transport = tport; host = uri->url_host; if (host_is_ip_address(host)) { if (transport) { print_result(host, port, transport, 1.0, 1, stream); } else if (uri->url_type == url_sips) { print_result(host, port, "tls", 1.0, 1, stream); } else { print_result(host, port, "udp", 1.0, 1, stream); print_result(host, port, "tcp", 1.0, 2, stream); } continue; } if (!host_is_domain(host)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid host\n", string); exitcode = 1; continue; } dig->sips = uri->url_type == url_sips; dig->preference = 1; if (!port && !transport && dig_naptr(dig, host, 1.0, stream)) continue /* resolved naptr */; else if (!port && dig_all_srvs(dig, transport, host, 1.0, stream)) continue /* resolved srv */; else if (dig_addr(dig, transport, host, port, 1.0, stream)) continue /* resolved a/aaaa */; stream->write_function(stream, "-ERR: %s: not found\n", string); exitcode = 1; } if (xml) { stream->write_function(stream, "%s", "</routes>\n"); } fail: su_home_unref(home); sres_resolver_unref(dig->sres); switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; }
/** 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(); }