Merge up to current sofia-sip darcs.
Thu Nov 15 08:40:38 EST 2007 Pekka.Pessi@nokia.com * htable2.h: fixed usize_t/size_t confusion Fri Nov 16 06:38:51 EST 2007 Youness Alaoui <youness.alaoui@collabora.co.uk> * Added #include <stdio.h> Fri Nov 16 10:27:58 EST 2007 Pekka.Pessi@nokia.com * auth_client.c: allow multiple challenges in auc_credentials() or auc_all_credentials() Fri Nov 16 10:29:00 EST 2007 Pekka.Pessi@nokia.com * nua/test_proxy.[hc], nua/test_register.c: test support of multiple realms. Fri Nov 16 11:17:09 EST 2007 Pekka.Pessi@nokia.com * sofia-sip/su_alloc.h, su_alloc.c: added su_home_lock(), su_home_trylock(), su_home_unlock() Added test in torture_su_alloc.c. Using in su_pthread_port.c. Fri Nov 16 12:29:55 EST 2007 Pekka.Pessi@nokia.com * test_register.c, test_proxy.c: use realm "test-proxy" during normal tests Fri Nov 16 12:34:00 EST 2007 Pekka.Pessi@nokia.com * nua_register.c: sf.net bug #1816647: Outbound contact does not make it to dialogs Now use Contact from first registration instead of Contact generated from transport. Mon Nov 19 12:00:06 EST 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * su_alloc.c: silenced warnings on Sun CC git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6338 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
8675abfa1c
commit
b7c6c0e483
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "sofia-sip/bnf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define ws bnf_ws
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ int ca_credentials(auth_client_t *ca,
|
|||
|
||||
if ((scheme != NULL && strcasecmp(scheme, ca->ca_scheme)) ||
|
||||
(realm != NULL && strcmp(realm, ca->ca_realm)))
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
old_user = ca->ca_user, old_pass = ca->ca_pass;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "sofia-sip/auth_common.h"
|
||||
#include "sofia-sip/msg_header.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "iptsec_debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1426,6 +1426,7 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,
|
|||
int sips_uri = remote_uri && remote_uri->url_type == url_sips;
|
||||
|
||||
nua_registration_t const *nr, *public = NULL, *any = NULL;
|
||||
nua_registration_t const *registered = NULL;
|
||||
nua_registration_t const *namewise = NULL, *sipswise = NULL;
|
||||
|
||||
int ip4 = remote_uri && host_is_ip4_address(remote_uri->url_host);
|
||||
|
@ -1444,11 +1445,15 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,
|
|||
continue;
|
||||
if (sips_uri ? nr->nr_secure : !nr->nr_secure)
|
||||
return (nua_registration_t *)nr;
|
||||
if (!registered && nr->nr_aor)
|
||||
registered = nr;
|
||||
if (!public && nr->nr_public)
|
||||
public = nr;
|
||||
if (!any)
|
||||
any = nr;
|
||||
}
|
||||
if (registered)
|
||||
return (nua_registration_t *)registered;
|
||||
if (public)
|
||||
return (nua_registration_t *)public;
|
||||
if (any)
|
||||
|
@ -1456,8 +1461,11 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!sips_aor && aor)
|
||||
if (!sips_aor && aor) {
|
||||
alt_aor = memcpy(_alt_aor, aor, sizeof _alt_aor);
|
||||
alt_aor->a_url->url_type = url_sips;
|
||||
alt_aor->a_url->url_scheme = "sips";
|
||||
}
|
||||
|
||||
for (nr = list; nr; nr = nr->nr_next) {
|
||||
if (!nr->nr_ready || !nr->nr_contact)
|
||||
|
@ -1468,11 +1476,12 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,
|
|||
if (!namewise && alt_aor && url_cmp(nr->nr_aor->a_url, aor->a_url) == 0)
|
||||
namewise = nr;
|
||||
}
|
||||
else {
|
||||
if (!sipswise && ((sips_aor || sips_uri) ?
|
||||
nr->nr_secure : !nr->nr_secure))
|
||||
sipswise = nr;
|
||||
}
|
||||
|
||||
if (!sipswise && ((sips_aor || sips_uri) ?
|
||||
nr->nr_secure : !nr->nr_secure))
|
||||
sipswise = nr;
|
||||
if (!registered)
|
||||
registered = nr;
|
||||
if (!public && nr->nr_public)
|
||||
public = nr;
|
||||
if (!any)
|
||||
|
@ -1483,7 +1492,9 @@ nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,
|
|||
return (nua_registration_t *)namewise;
|
||||
if (sipswise)
|
||||
return (nua_registration_t *)sipswise;
|
||||
|
||||
if (registered)
|
||||
return (nua_registration_t *)registered;
|
||||
|
||||
/* XXX -
|
||||
should we do some policing whether sips_aor or sips_uri can be used
|
||||
with sip contact?
|
||||
|
@ -1594,7 +1605,7 @@ int nua_registration_add_contact_to_request(nua_handle_t *nh,
|
|||
*
|
||||
* @param nh
|
||||
* @param msg response message
|
||||
* @param sip response headers
|
||||
* @param sip headers in response message
|
||||
* @param record_route record-route from request
|
||||
* @param remote_contact Contact from request
|
||||
*/
|
||||
|
|
|
@ -457,8 +457,14 @@ int test_basic_call_2(struct context *ctx)
|
|||
TEST_S(sip->sip_content_type->c_type, "application/sdp");
|
||||
TEST_1(sip->sip_payload); /* there is sdp in 200 OK */
|
||||
TEST_1(sip->sip_contact);
|
||||
#if nomore
|
||||
/* Test that B does not use application-specific contact */
|
||||
TEST_1(!sip->sip_contact->m_url->url_user);
|
||||
#else
|
||||
/* sf.net bug #1816647: Outbound contact does not make it to dialogs */
|
||||
/* Now we use first registered contact if aor does not match */
|
||||
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
||||
#endif
|
||||
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
|
||||
TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
|
||||
TEST_1(!is_answer_recv(e->data->e_tags)); /* but it is ignored */
|
||||
|
@ -989,6 +995,9 @@ int change_uri_in_ack(CONDITION_PARAMS)
|
|||
}
|
||||
|
||||
/* Test changing from/to within dialog */
|
||||
/* Test that a proper Contact gets selected in response
|
||||
* regardless of the To URI.
|
||||
*/
|
||||
int test_basic_call_5(struct context *ctx)
|
||||
{
|
||||
BEGIN();
|
||||
|
@ -1004,13 +1013,15 @@ int test_basic_call_5(struct context *ctx)
|
|||
a_call->sdp = "m=audio 5008 RTP/AVP 8";
|
||||
b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
|
||||
|
||||
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
|
||||
TEST_1(a_call->nh = nua_handle(a->nua, a_call,
|
||||
SIPTAG_TO_STR("<sips:b@x.org>"),
|
||||
TAG_END()));
|
||||
|
||||
TEST_1(!nua_handle_has_active_call(a_call->nh));
|
||||
TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
|
||||
|
||||
INVITE(a, a_call, a_call->nh,
|
||||
TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
|
||||
NUTAG_URL(b->contact->m_url),
|
||||
SOATAG_USER_SDP_STR(a_call->sdp),
|
||||
NUTAG_AUTOACK(0),
|
||||
TAG_END());
|
||||
|
@ -1032,6 +1043,7 @@ int test_basic_call_5(struct context *ctx)
|
|||
TEST(e->data->e_status, 200);
|
||||
TEST_1(sip = sip_object(e->data->e_msg));
|
||||
TEST_1(sip->sip_contact);
|
||||
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
||||
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
|
||||
TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
|
||||
TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
|
||||
|
|
|
@ -134,7 +134,7 @@ struct domain {
|
|||
struct {
|
||||
sip_time_t min_expires, expires, max_expires;
|
||||
int outbound_tcp; /**< Use inbound TCP connection as outbound */
|
||||
int authorize;
|
||||
char const *authorize; /**< Authorization realm to use */
|
||||
} prefs;
|
||||
|
||||
tagi_t *tags;
|
||||
|
@ -216,6 +216,7 @@ struct proxy_tr
|
|||
|
||||
auth_mod_t *am; /* Authentication module */
|
||||
auth_status_t *as; /* Authentication status */
|
||||
char const *realm; /* Authentication realm to use */
|
||||
unsigned use_auth; /* Authentication method (401/407) to use */
|
||||
|
||||
unsigned rr:1;
|
||||
|
@ -473,20 +474,33 @@ void test_proxy_domain_get_outbound(struct domain *d,
|
|||
}
|
||||
}
|
||||
|
||||
void test_proxy_domain_set_authorize(struct domain *d, int authorize)
|
||||
int test_proxy_domain_set_authorize(struct domain *d,
|
||||
char const *realm)
|
||||
{
|
||||
if (d) {
|
||||
d->prefs.authorize = authorize;
|
||||
if (realm) {
|
||||
realm = su_strdup(d->home, realm);
|
||||
if (!realm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
d->prefs.authorize = realm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void test_proxy_domain_get_authorize(struct domain *d,
|
||||
int *return_authorize)
|
||||
int test_proxy_domain_get_authorize(struct domain *d,
|
||||
char const **return_realm)
|
||||
{
|
||||
if (d) {
|
||||
if (return_authorize)
|
||||
*return_authorize = d->prefs.authorize;
|
||||
if (return_realm) {
|
||||
*return_realm = d->prefs.authorize;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int test_proxy_close_tports(struct proxy *p)
|
||||
|
@ -533,7 +547,7 @@ struct domain *test_proxy_add_domain(struct proxy *p,
|
|||
d->prefs.expires = 3600;
|
||||
d->prefs.max_expires = 36000;
|
||||
d->prefs.outbound_tcp = 0;
|
||||
d->prefs.authorize = 0;
|
||||
d->prefs.authorize = NULL;
|
||||
|
||||
if (d->uri && d->tags &&
|
||||
!su_task_execute(su_clone_task(p->clone), _domain_init, d, &init)) {
|
||||
|
@ -795,6 +809,7 @@ static int originating_transaction(struct proxy_tr *t)
|
|||
|
||||
if (o && o->auth && o->prefs.authorize) {
|
||||
t->am = o->auth;
|
||||
t->realm = o->prefs.authorize;
|
||||
t->use_auth = 407;
|
||||
}
|
||||
|
||||
|
@ -966,6 +981,7 @@ static int challenge_transaction(struct proxy_tr *t)
|
|||
|
||||
as->as_method = sip->sip_request->rq_method_name;
|
||||
as->as_source = msg_addrinfo(t->msg);
|
||||
as->as_realm = t->realm;
|
||||
|
||||
as->as_user_uri = sip->sip_from->a_url;
|
||||
as->as_display = sip->sip_from->a_display;
|
||||
|
@ -1110,6 +1126,8 @@ int process_register(struct proxy_tr *t)
|
|||
|
||||
if (t->domain->auth) {
|
||||
t->am = t->domain->auth, t->use_auth = 401;
|
||||
if (t->domain->prefs.authorize)
|
||||
t->realm = t->domain->prefs.authorize;
|
||||
if (challenge_transaction(t))
|
||||
return t->status;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,9 @@ void test_proxy_get_session_timer(struct proxy *p,
|
|||
sip_time_t *return_session_expires,
|
||||
sip_time_t *return_min_se);
|
||||
|
||||
void test_proxy_domain_set_authorize(struct domain *d, int authorize);
|
||||
void test_proxy_domain_get_authorize(struct domain *d, int *return_authorize);
|
||||
int test_proxy_domain_set_authorize(struct domain *, char const *realm);
|
||||
int test_proxy_domain_get_authorize(struct domain *,
|
||||
char const **return_realm);
|
||||
|
||||
void test_proxy_domain_set_outbound(struct domain *d,
|
||||
int use_outbound);
|
||||
|
|
|
@ -426,7 +426,7 @@ int test_register_c(struct context *ctx)
|
|||
printf("TEST NUA-2.3.3: REGISTER c\n");
|
||||
|
||||
test_proxy_domain_set_expiration(ctx->c.domain, 600, 3600, 36000);
|
||||
test_proxy_domain_set_authorize(ctx->c.domain, 2);
|
||||
test_proxy_domain_set_authorize(ctx->c.domain, "test-proxy-0");
|
||||
|
||||
TEST_1(c_reg->nh = nua_handle(c->nua, c_reg, TAG_END()));
|
||||
|
||||
|
@ -453,7 +453,7 @@ int test_register_c(struct context *ctx)
|
|||
free_events_in_list(ctx, c->events);
|
||||
|
||||
AUTHENTICATE(c, c_reg, c_reg->nh,
|
||||
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END());
|
||||
NUTAG_AUTH("Digest:\"test-proxy-0\":charlie:secret"), TAG_END());
|
||||
run_abc_until(ctx, -1, save_events, -1, save_events,
|
||||
-1, save_until_final_response);
|
||||
|
||||
|
@ -778,6 +778,23 @@ int test_connectivity(struct context *ctx)
|
|||
|
||||
free_events_in_list(ctx, c->events);
|
||||
|
||||
/* Sneakily change the realm */
|
||||
|
||||
TEST(test_proxy_domain_set_authorize(ctx->c.domain, "test-proxy"), 0);
|
||||
|
||||
AUTHENTICATE(c, c_call, c_call->nh,
|
||||
NUTAG_AUTH("Digest:\"test-proxy-0\":charlie:secret"),
|
||||
TAG_END());
|
||||
|
||||
run_abc_until(ctx, -1, NULL, -1, NULL, -1, save_until_final_response);
|
||||
|
||||
/* Client events: nua_options(), nua_r_options */
|
||||
TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_r_options);
|
||||
TEST(e->data->e_status, 407);
|
||||
TEST_1(!e->next);
|
||||
|
||||
free_events_in_list(ctx, c->events);
|
||||
|
||||
AUTHENTICATE(c, c_call, c_call->nh,
|
||||
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"),
|
||||
TAG_END());
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "sofia-sip/sip_parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "sofia-sip/sip_parser.h"
|
||||
#include "sofia-sip/sip_extra.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "sofia-sip/sip_parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "sofia-sip/sip_parser.h"
|
||||
#include "sofia-sip/msg_mime_protos.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "sofia-sip/sip_parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "sofia-sip/sip_parser.h"
|
||||
#include "sofia-sip/sip_extra.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
#include "sofia-sip/sip_parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <sofia-sip/su_tagarg.h>
|
||||
#include <sofia-sip/su_strlst.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <sofia-sip/hostdomain.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -138,13 +138,13 @@ HTABLE2_SCOPE int prefix##_remove(type *, entrytype const)
|
|||
HTABLE2_SCOPE \
|
||||
int prefix##_resize(void *realloc_arg, \
|
||||
type pr[1], \
|
||||
usize_t new_size) \
|
||||
size_t new_size) \
|
||||
{ \
|
||||
entrytype *new_hash; \
|
||||
entrytype *old_hash = pr->pr##table; \
|
||||
usize_t old_size; \
|
||||
usize_t i, j, i0; \
|
||||
usize_t again = 0, used = 0, collisions = 0; \
|
||||
size_t old_size; \
|
||||
size_t i, j, i0; \
|
||||
size_t again = 0, used = 0, collisions = 0; \
|
||||
\
|
||||
(void)realloc_arg; \
|
||||
\
|
||||
|
@ -256,7 +256,7 @@ entrytype *prefix##_insert(type *pr, entrytype e) \
|
|||
HTABLE2_SCOPE \
|
||||
int prefix##_remove(type *pr, entrytype const e) \
|
||||
{ \
|
||||
usize_t i, j, k, size = pr->pr##size; \
|
||||
size_t i, j, k, size = pr->pr##size; \
|
||||
entrytype *htable = pr->pr##table; \
|
||||
\
|
||||
/* Search for entry */ \
|
||||
|
|
|
@ -107,6 +107,10 @@ SU_DLL int su_home_mutex_lock(su_home_t *home);
|
|||
|
||||
SU_DLL int su_home_mutex_unlock(su_home_t *home);
|
||||
|
||||
SU_DLL int su_home_lock(su_home_t *home);
|
||||
SU_DLL int su_home_trylock(su_home_t *home);
|
||||
SU_DLL int su_home_unlock(su_home_t *home);
|
||||
|
||||
SU_DLL void *su_alloc(su_home_t *h, isize_t size)
|
||||
__attribute__((__malloc__));
|
||||
SU_DLL void *su_zalloc(su_home_t *h, isize_t size)
|
||||
|
|
|
@ -186,6 +186,7 @@
|
|||
#include "sofia-sip/su_alloc_stat.h"
|
||||
#include "sofia-sip/su_errno.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <memory.h>
|
||||
|
@ -193,17 +194,18 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
void (*su_home_locker)(void *mutex);
|
||||
void (*su_home_unlocker)(void *mutex);
|
||||
int (*_su_home_locker)(void *mutex);
|
||||
int (*_su_home_unlocker)(void *mutex);
|
||||
|
||||
void (*su_home_mutex_locker)(void *mutex);
|
||||
void (*su_home_mutex_unlocker)(void *mutex);
|
||||
int (*_su_home_mutex_locker)(void *mutex);
|
||||
int (*_su_home_mutex_trylocker)(void *mutex);
|
||||
int (*_su_home_mutex_unlocker)(void *mutex);
|
||||
|
||||
void (*su_home_destroy_mutexes)(void *mutex);
|
||||
void (*_su_home_destroy_mutexes)(void *mutex);
|
||||
|
||||
#define MEMLOCK(h) \
|
||||
(((h) && (h)->suh_lock ? su_home_locker((h)->suh_lock) : (void)0), (h)->suh_blocks)
|
||||
#define UNLOCK(h) (((h) && (h)->suh_lock ? su_home_unlocker((h)->suh_lock) : (void)0), NULL)
|
||||
((void)((h) && (h)->suh_lock ? _su_home_locker((h)->suh_lock) : 0), (h)->suh_blocks)
|
||||
#define UNLOCK(h) ((void)((h) && (h)->suh_lock ? _su_home_unlocker((h)->suh_lock) : 0), NULL)
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define MEMCHECK 0
|
||||
|
@ -987,7 +989,7 @@ void _su_home_deinit(su_home_t *home)
|
|||
home->suh_blocks = NULL;
|
||||
|
||||
if (home->suh_lock)
|
||||
su_home_destroy_mutexes(home->suh_lock);
|
||||
_su_home_destroy_mutexes(home->suh_lock);
|
||||
}
|
||||
|
||||
home->suh_lock = NULL;
|
||||
|
@ -1462,42 +1464,108 @@ int su_home_is_threadsafe(su_home_t const *home)
|
|||
return home && home->suh_lock;
|
||||
}
|
||||
|
||||
/** Obtain exclusive lock on home (if home is threadsafe). */
|
||||
/** Increase refcount and obtain exclusive lock on home.
|
||||
*
|
||||
* @note The #su_home_t structure must be created with su_home_new() or
|
||||
* su_home_clone(), or initialized with su_home_init() before using this
|
||||
* function.
|
||||
*
|
||||
* In order to enable actual locking, use su_home_threadsafe(), too.
|
||||
* Otherwise the su_home_mutex_lock() will just increase the reference
|
||||
* count.
|
||||
*/
|
||||
int su_home_mutex_lock(su_home_t *home)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (home == NULL)
|
||||
return su_seterrno(EFAULT);
|
||||
|
||||
if (home->suh_lock) {
|
||||
su_home_ref(home);
|
||||
su_home_mutex_locker(home->suh_lock);
|
||||
}
|
||||
else if (home->suh_blocks) {
|
||||
if (!su_home_ref(home))
|
||||
return -1;
|
||||
}
|
||||
if (home->suh_blocks == NULL || !su_home_ref(home))
|
||||
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;
|
||||
}
|
||||
|
||||
/** Release exclusive lock on home (if home is threadsafe) */
|
||||
/** Release exclusive lock on home and decrease refcount (if home is threadsafe) */
|
||||
int su_home_mutex_unlock(su_home_t *home)
|
||||
{
|
||||
if (home == NULL)
|
||||
return su_seterrno(EFAULT);
|
||||
|
||||
if (home->suh_lock) {
|
||||
su_home_mutex_unlocker(home->suh_lock);
|
||||
su_home_unref(home);
|
||||
}
|
||||
else if (home->suh_blocks) {
|
||||
su_home_unref(home);
|
||||
int error = _su_home_mutex_unlocker(home->suh_lock);
|
||||
if (error)
|
||||
return su_seterrno(error);
|
||||
}
|
||||
|
||||
if (home->suh_blocks == NULL)
|
||||
return su_seterrno(EINVAL), -1; /* Uninitialized home */
|
||||
|
||||
su_home_unref(home);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Obtain exclusive lock on home without increasing refcount.
|
||||
*
|
||||
* @return 0 if successful, -1 if not threadsafe, error code otherwise.
|
||||
*
|
||||
*/
|
||||
int su_home_lock(su_home_t *home)
|
||||
{
|
||||
if (home == NULL)
|
||||
return EFAULT;
|
||||
|
||||
if (home->suh_lock == NULL)
|
||||
return -1; /* No-op */
|
||||
|
||||
return _su_home_mutex_locker(home->suh_lock);
|
||||
}
|
||||
|
||||
|
||||
/** Try to obtain exclusive lock on home without increasing refcount.
|
||||
*
|
||||
* @return 0 if successful, -1 if not threadsafe,
|
||||
* EBUSY if already locked, error code otherwise.
|
||||
*
|
||||
*/
|
||||
int su_home_trylock(su_home_t *home)
|
||||
{
|
||||
if (home == NULL)
|
||||
return EFAULT;
|
||||
|
||||
if (home->suh_lock == NULL)
|
||||
return -1; /* No-op */
|
||||
|
||||
return _su_home_mutex_trylocker(home->suh_lock);
|
||||
}
|
||||
|
||||
|
||||
/** Release exclusive lock on home.
|
||||
*
|
||||
* @return 0 if successful, -1 if not threadsafe, error code otherwise.
|
||||
*/
|
||||
int su_home_unlock(su_home_t *home)
|
||||
{
|
||||
if (home == NULL)
|
||||
return EFAULT;
|
||||
|
||||
if (home->suh_lock == NULL)
|
||||
return -1; /* No-op */
|
||||
|
||||
return _su_home_mutex_unlocker(home->suh_lock);
|
||||
}
|
||||
|
||||
|
||||
/** Initialize statistics structure */
|
||||
void su_home_init_stats(su_home_t *home)
|
||||
{
|
||||
|
|
|
@ -41,25 +41,32 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void (*su_home_locker)(void *mutex);
|
||||
extern void (*su_home_unlocker)(void *mutex);
|
||||
extern int (*_su_home_locker)(void *mutex);
|
||||
extern int (*_su_home_unlocker)(void *mutex);
|
||||
|
||||
extern void (*su_home_mutex_locker)(void *mutex);
|
||||
extern void (*su_home_mutex_unlocker)(void *mutex);
|
||||
extern int (*_su_home_mutex_locker)(void *mutex);
|
||||
extern int (*_su_home_mutex_trylocker)(void *mutex);
|
||||
extern int (*_su_home_mutex_unlocker)(void *mutex);
|
||||
|
||||
extern void (*su_home_destroy_mutexes)(void *mutex);
|
||||
extern void (*_su_home_destroy_mutexes)(void *mutex);
|
||||
|
||||
/** Mutex */
|
||||
static void mutex_locker(void *_mutex)
|
||||
static int mutex_locker(void *_mutex)
|
||||
{
|
||||
pthread_mutex_t *mutex = _mutex;
|
||||
pthread_mutex_lock(mutex + 1);
|
||||
return pthread_mutex_lock(mutex + 1);
|
||||
}
|
||||
|
||||
static void mutex_unlocker(void *_mutex)
|
||||
int mutex_trylocker(void *_mutex)
|
||||
{
|
||||
pthread_mutex_t *mutex = _mutex;
|
||||
pthread_mutex_unlock(mutex + 1);
|
||||
return pthread_mutex_trylock(mutex + 1);
|
||||
}
|
||||
|
||||
static int mutex_unlocker(void *_mutex)
|
||||
{
|
||||
pthread_mutex_t *mutex = _mutex;
|
||||
return pthread_mutex_unlock(mutex + 1);
|
||||
}
|
||||
|
||||
static void mutex_destroy(void *_mutex)
|
||||
|
@ -69,7 +76,6 @@ static void mutex_destroy(void *_mutex)
|
|||
pthread_mutex_destroy(mutex + 1);
|
||||
free(_mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -100,13 +106,14 @@ int su_home_threadsafe(su_home_t *home)
|
|||
#endif
|
||||
|
||||
#if SU_HAVE_PTHREADS
|
||||
if (!su_home_unlocker) {
|
||||
if (!_su_home_unlocker) {
|
||||
/* Avoid linking pthread library just for memory management */
|
||||
su_home_mutex_locker = mutex_locker;
|
||||
su_home_mutex_unlocker = mutex_unlocker;
|
||||
su_home_locker = (void (*)(void *))pthread_mutex_lock;
|
||||
su_home_unlocker = (void (*)(void *))pthread_mutex_unlock;
|
||||
su_home_destroy_mutexes = mutex_destroy;
|
||||
_su_home_mutex_locker = mutex_locker;
|
||||
_su_home_mutex_trylocker = mutex_trylocker;
|
||||
_su_home_mutex_unlocker = mutex_unlocker;
|
||||
_su_home_locker = (int (*)(void *))pthread_mutex_lock;
|
||||
_su_home_unlocker = (int (*)(void *))pthread_mutex_unlock;
|
||||
_su_home_destroy_mutexes = mutex_destroy;
|
||||
}
|
||||
|
||||
mutex = calloc(1, 2 * (sizeof *mutex));
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <sofia-sip/su_log.h>
|
||||
#include <sofia-sip/su_errno.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
|
|
@ -97,7 +97,7 @@ void su_pthread_port_lock(su_port_t *self, char const *who)
|
|||
PORT_LOCK_DEBUG(("%p at %s locking(%p)...",
|
||||
(void *)pthread_self(), who, self));
|
||||
|
||||
su_home_mutex_lock(self->sup_base->sup_home);
|
||||
su_home_lock(self->sup_base->sup_home);
|
||||
|
||||
PORT_LOCK_DEBUG((" ...%p at %s locked(%p)...",
|
||||
(void *)pthread_self(), who, self));
|
||||
|
@ -105,7 +105,7 @@ void su_pthread_port_lock(su_port_t *self, char const *who)
|
|||
|
||||
void su_pthread_port_unlock(su_port_t *self, char const *who)
|
||||
{
|
||||
su_home_mutex_unlock(self->sup_base->sup_home);
|
||||
su_home_unlock(self->sup_base->sup_home);
|
||||
|
||||
PORT_LOCK_DEBUG((" ...%p at %s unlocked(%p)\n",
|
||||
(void *)pthread_self(), who, self));
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "sofia-sip/su_config.h"
|
||||
#include "sofia-sip/su_strlst.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <memory.h>
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <sofia-sip/su_alloc.h>
|
||||
#include <sofia-sip/su_errno.h>
|
||||
#include <sofia-sip/su_strlst.h>
|
||||
#include <sofia-sip/su_alloc_stat.h>
|
||||
|
||||
|
@ -194,6 +195,42 @@ static int test_alloc(void)
|
|||
END();
|
||||
}
|
||||
|
||||
static int test_lock(void)
|
||||
{
|
||||
su_home_t home[1] = { SU_HOME_INIT(home) };
|
||||
|
||||
BEGIN();
|
||||
|
||||
TEST(su_home_mutex_lock(home), -1);
|
||||
TEST(su_home_mutex_unlock(home), -1);
|
||||
|
||||
TEST(su_home_lock(home), -1);
|
||||
TEST(su_home_trylock(home), -1);
|
||||
TEST(su_home_unlock(home), -1);
|
||||
|
||||
TEST(su_home_init(home), 0);
|
||||
|
||||
TEST(su_home_mutex_lock(home), 0);
|
||||
TEST(su_home_trylock(home), -1);
|
||||
TEST(su_home_mutex_unlock(home), 0);
|
||||
TEST(su_home_trylock(home), -1);
|
||||
|
||||
TEST(su_home_threadsafe(home), 0);
|
||||
|
||||
TEST(su_home_mutex_lock(home), 0);
|
||||
TEST(su_home_trylock(home), EBUSY);
|
||||
TEST(su_home_mutex_unlock(home), 0);
|
||||
|
||||
TEST(su_home_lock(home), 0);
|
||||
TEST(su_home_trylock(home), EBUSY);
|
||||
TEST(su_home_unlock(home), 0);
|
||||
|
||||
TEST(su_home_trylock(home), 0);
|
||||
TEST(su_home_unlock(home), 0);
|
||||
|
||||
END();
|
||||
}
|
||||
|
||||
static int test_strdupcat(void)
|
||||
{
|
||||
su_home_t home[1] = { SU_HOME_INIT(home) };
|
||||
|
@ -708,6 +745,7 @@ int main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
retval |= test_alloc();
|
||||
retval |= test_lock();
|
||||
retval |= test_strdupcat();
|
||||
retval |= test_sprintf("%s.%s", "foo", "bar");
|
||||
retval |= test_strlst();
|
||||
|
@ -716,4 +754,3 @@ int main(int argc, char *argv[])
|
|||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <sofia-sip/string0.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
|
Loading…
Reference in New Issue