Improve object destruction (bug #3286)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4747 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
eac6554b7c
commit
299b57eafc
2 changed files with 138 additions and 156 deletions
|
@ -1111,66 +1111,44 @@ static void update_peer(struct sip_peer *p, int expiry)
|
||||||
realtime_update_peer(p->name, &p->addr, p->username, expiry);
|
realtime_update_peer(p->name, &p->addr, p->username, expiry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int temponly);
|
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime);
|
||||||
|
|
||||||
static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
|
static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
|
||||||
{
|
{
|
||||||
struct ast_variable *var, *tmp=NULL;
|
|
||||||
char iabuf[80];
|
|
||||||
struct sip_peer *peer=NULL;
|
struct sip_peer *peer=NULL;
|
||||||
time_t nowtime, regseconds;
|
struct ast_variable *var;
|
||||||
int dynamic=0;
|
struct ast_variable *tmp;
|
||||||
|
|
||||||
if (sin)
|
|
||||||
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
|
|
||||||
if (peername)
|
if (peername)
|
||||||
var = ast_load_realtime("sipfriends", "name", peername, NULL);
|
var = ast_load_realtime("sipfriends", "name", peername, NULL);
|
||||||
else
|
else if (sin) {
|
||||||
|
char iabuf[80];
|
||||||
|
|
||||||
|
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
|
||||||
var = ast_load_realtime("sipfriends", "ipaddr", iabuf, NULL);
|
var = ast_load_realtime("sipfriends", "ipaddr", iabuf, NULL);
|
||||||
if (var) {
|
} else
|
||||||
/* Make sure it's not a user only... */
|
return NULL;
|
||||||
peer = build_peer(peername, var, 1);
|
|
||||||
if (peer) {
|
if (!var)
|
||||||
/* Add some finishing touches, addresses, etc */
|
return NULL;
|
||||||
ast_set_flag(peer, SIP_REALTIME);
|
|
||||||
tmp = var;
|
tmp = var;
|
||||||
while(tmp) {
|
while(tmp) {
|
||||||
if (!strcasecmp(tmp->name, "type")) {
|
if (strcasecmp(tmp->name, "type"))
|
||||||
if (strcasecmp(tmp->value, "friend") &&
|
continue;
|
||||||
strcasecmp(tmp->value, "peer")) {
|
|
||||||
/* Whoops, we weren't supposed to exist! */
|
if (!strcasecmp(tmp->value, "user")) {
|
||||||
sip_destroy_peer(peer);
|
ast_destroy_realtime(var);
|
||||||
peer = NULL;
|
return NULL;
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (!strcasecmp(tmp->name, "regseconds")) {
|
|
||||||
if (sscanf(tmp->value, "%li", ®seconds) != 1)
|
|
||||||
regseconds = 0;
|
|
||||||
} else if (!strcasecmp(tmp->name, "ipaddr")) {
|
|
||||||
inet_aton(tmp->value, &(peer->addr.sin_addr));
|
|
||||||
} else if (!strcasecmp(tmp->name, "port")) {
|
|
||||||
peer->addr.sin_port = htons(atoi(tmp->value));
|
|
||||||
} else if (!strcasecmp(tmp->name, "host")) {
|
|
||||||
if (!strcasecmp(tmp->value, "dynamic"))
|
|
||||||
dynamic = 1;
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
if (peer && dynamic) {
|
|
||||||
time(&nowtime);
|
|
||||||
if ((nowtime - regseconds) > 0) {
|
|
||||||
memset(&peer->addr, 0, sizeof(peer->addr));
|
|
||||||
if (option_debug)
|
|
||||||
ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast_destroy_realtime(var);
|
|
||||||
}
|
tmp = tmp->next;
|
||||||
if (peer) {
|
|
||||||
/* Destroy, so when our caller unrefs, it will disappear */
|
|
||||||
ASTOBJ_DESTROY(peer, sip_destroy_peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer = build_peer(peername, var, 1);
|
||||||
|
if (peer)
|
||||||
|
ast_set_flag(peer, SIP_REALTIME);
|
||||||
|
ast_destroy_realtime(var);
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1214,43 +1192,39 @@ static void sip_destroy_user(struct sip_user *user)
|
||||||
free(user);
|
free(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sip_user *build_user(const char *name, struct ast_variable *v);
|
static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime);
|
||||||
static struct sip_user *realtime_user(const char *username)
|
static struct sip_user *realtime_user(const char *username)
|
||||||
{
|
{
|
||||||
struct ast_variable *var;
|
struct ast_variable *var;
|
||||||
struct ast_variable *tmp;
|
struct ast_variable *tmp;
|
||||||
struct sip_user *user=NULL;
|
struct sip_user *user = NULL;
|
||||||
|
|
||||||
var = ast_load_realtime("sipfriends", "name", username, NULL);
|
var = ast_load_realtime("sipfriends", "name", username, NULL);
|
||||||
if (var) {
|
|
||||||
/* Make sure it's not a user only... */
|
if (!var)
|
||||||
user = build_user(username, var);
|
return NULL;
|
||||||
if (user) {
|
|
||||||
/* Move counter from s to r... */
|
tmp = var;
|
||||||
suserobjs--;
|
while (tmp) {
|
||||||
ruserobjs++;
|
if (strcasecmp(tmp->name, "type"))
|
||||||
/* Add some finishing touches, addresses, etc */
|
continue;
|
||||||
ast_set_flag(user, SIP_REALTIME);
|
|
||||||
tmp = var;
|
if (!strcasecmp(tmp->value, "peer")) {
|
||||||
while(tmp) {
|
ast_destroy_realtime(var);
|
||||||
if (!strcasecmp(tmp->name, "type")) {
|
return NULL;
|
||||||
if (strcasecmp(tmp->value, "friend") &&
|
|
||||||
strcasecmp(tmp->value, "user")) {
|
|
||||||
/* Whoops, we weren't supposed to exist! */
|
|
||||||
sip_destroy_user(user);
|
|
||||||
user = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast_destroy_realtime(var);
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user = build_user(username, var, 1);
|
||||||
if (user) {
|
if (user) {
|
||||||
/* Reference and destroy, so when our caller unrefs, we disappear */
|
/* Move counter from s to r... */
|
||||||
ASTOBJ_REF(user);
|
suserobjs--;
|
||||||
ASTOBJ_DESTROY(user, sip_destroy_user);
|
ruserobjs++;
|
||||||
|
/* Add some finishing touches, addresses, etc */
|
||||||
|
ast_set_flag(user, SIP_REALTIME);
|
||||||
}
|
}
|
||||||
|
ast_destroy_realtime(var);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,60 +1264,60 @@ static int create_addr(struct sip_pvt *r, char *opeer)
|
||||||
p = find_peer(peer, NULL);
|
p = find_peer(peer, NULL);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
found++;
|
found++;
|
||||||
ast_copy_flags(r, p, SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_DTMF | SIP_NAT | SIP_REINVITE | SIP_INSECURE);
|
ast_copy_flags(r, p, SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_DTMF | SIP_NAT | SIP_REINVITE | SIP_INSECURE);
|
||||||
r->capability = p->capability;
|
r->capability = p->capability;
|
||||||
if (r->rtp) {
|
if (r->rtp) {
|
||||||
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
||||||
ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
ast_rtp_setnat(r->rtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
||||||
|
}
|
||||||
|
if (r->vrtp) {
|
||||||
|
ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
||||||
|
ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
||||||
|
}
|
||||||
|
strncpy(r->peername, p->username, sizeof(r->peername)-1);
|
||||||
|
strncpy(r->authname, p->username, sizeof(r->authname)-1);
|
||||||
|
strncpy(r->peersecret, p->secret, sizeof(r->peersecret)-1);
|
||||||
|
strncpy(r->peermd5secret, p->md5secret, sizeof(r->peermd5secret)-1);
|
||||||
|
strncpy(r->username, p->username, sizeof(r->username)-1);
|
||||||
|
strncpy(r->tohost, p->tohost, sizeof(r->tohost)-1);
|
||||||
|
strncpy(r->fullcontact, p->fullcontact, sizeof(r->fullcontact)-1);
|
||||||
|
if (!r->initreq.headers && !ast_strlen_zero(p->fromdomain)) {
|
||||||
|
if ((callhost = strchr(r->callid, '@'))) {
|
||||||
|
strncpy(callhost + 1, p->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2);
|
||||||
}
|
}
|
||||||
if (r->vrtp) {
|
}
|
||||||
ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
if (ast_strlen_zero(r->tohost)) {
|
||||||
ast_rtp_setnat(r->vrtp, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
|
if (p->addr.sin_addr.s_addr)
|
||||||
}
|
ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->addr.sin_addr);
|
||||||
strncpy(r->peername, p->username, sizeof(r->peername)-1);
|
|
||||||
strncpy(r->authname, p->username, sizeof(r->authname)-1);
|
|
||||||
strncpy(r->peersecret, p->secret, sizeof(r->peersecret)-1);
|
|
||||||
strncpy(r->peermd5secret, p->md5secret, sizeof(r->peermd5secret)-1);
|
|
||||||
strncpy(r->username, p->username, sizeof(r->username)-1);
|
|
||||||
strncpy(r->tohost, p->tohost, sizeof(r->tohost)-1);
|
|
||||||
strncpy(r->fullcontact, p->fullcontact, sizeof(r->fullcontact)-1);
|
|
||||||
if (!r->initreq.headers && !ast_strlen_zero(p->fromdomain)) {
|
|
||||||
if ((callhost = strchr(r->callid, '@'))) {
|
|
||||||
strncpy(callhost + 1, p->fromdomain, sizeof(r->callid) - (callhost - r->callid) - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ast_strlen_zero(r->tohost)) {
|
|
||||||
if (p->addr.sin_addr.s_addr)
|
|
||||||
ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->addr.sin_addr);
|
|
||||||
else
|
|
||||||
ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->defaddr.sin_addr);
|
|
||||||
}
|
|
||||||
if (!ast_strlen_zero(p->fromdomain))
|
|
||||||
strncpy(r->fromdomain, p->fromdomain, sizeof(r->fromdomain)-1);
|
|
||||||
if (!ast_strlen_zero(p->fromuser))
|
|
||||||
strncpy(r->fromuser, p->fromuser, sizeof(r->fromuser)-1);
|
|
||||||
r->maxtime = p->maxms;
|
|
||||||
r->callgroup = p->callgroup;
|
|
||||||
r->pickupgroup = p->pickupgroup;
|
|
||||||
if (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833)
|
|
||||||
r->noncodeccapability |= AST_RTP_DTMF;
|
|
||||||
else
|
else
|
||||||
r->noncodeccapability &= ~AST_RTP_DTMF;
|
ast_inet_ntoa(r->tohost, sizeof(r->tohost), p->defaddr.sin_addr);
|
||||||
strncpy(r->context, p->context,sizeof(r->context)-1);
|
}
|
||||||
if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
|
if (!ast_strlen_zero(p->fromdomain))
|
||||||
(!p->maxms || ((p->lastms >= 0) && (p->lastms <= p->maxms)))) {
|
strncpy(r->fromdomain, p->fromdomain, sizeof(r->fromdomain)-1);
|
||||||
if (p->addr.sin_addr.s_addr) {
|
if (!ast_strlen_zero(p->fromuser))
|
||||||
r->sa.sin_addr = p->addr.sin_addr;
|
strncpy(r->fromuser, p->fromuser, sizeof(r->fromuser)-1);
|
||||||
r->sa.sin_port = p->addr.sin_port;
|
r->maxtime = p->maxms;
|
||||||
} else {
|
r->callgroup = p->callgroup;
|
||||||
r->sa.sin_addr = p->defaddr.sin_addr;
|
r->pickupgroup = p->pickupgroup;
|
||||||
r->sa.sin_port = p->defaddr.sin_port;
|
if (ast_test_flag(r, SIP_DTMF) == SIP_DTMF_RFC2833)
|
||||||
}
|
r->noncodeccapability |= AST_RTP_DTMF;
|
||||||
memcpy(&r->recv, &r->sa, sizeof(r->recv));
|
else
|
||||||
|
r->noncodeccapability &= ~AST_RTP_DTMF;
|
||||||
|
strncpy(r->context, p->context,sizeof(r->context)-1);
|
||||||
|
if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
|
||||||
|
(!p->maxms || ((p->lastms >= 0) && (p->lastms <= p->maxms)))) {
|
||||||
|
if (p->addr.sin_addr.s_addr) {
|
||||||
|
r->sa.sin_addr = p->addr.sin_addr;
|
||||||
|
r->sa.sin_port = p->addr.sin_port;
|
||||||
} else {
|
} else {
|
||||||
ASTOBJ_UNREF(p,sip_destroy_peer);
|
r->sa.sin_addr = p->defaddr.sin_addr;
|
||||||
|
r->sa.sin_port = p->defaddr.sin_port;
|
||||||
}
|
}
|
||||||
|
memcpy(&r->recv, &r->sa, sizeof(r->recv));
|
||||||
|
} else {
|
||||||
|
ASTOBJ_UNREF(p,sip_destroy_peer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!p && !found) {
|
if (!p && !found) {
|
||||||
hostn = peer;
|
hostn = peer;
|
||||||
|
@ -8644,7 +8618,7 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--- build_user: Initiate a SIP user structure from sip.conf ---*/
|
/*--- build_user: Initiate a SIP user structure from sip.conf ---*/
|
||||||
static struct sip_user *build_user(const char *name, struct ast_variable *v)
|
static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime)
|
||||||
{
|
{
|
||||||
struct sip_user *user;
|
struct sip_user *user;
|
||||||
int format;
|
int format;
|
||||||
|
@ -8778,15 +8752,16 @@ static struct sip_peer *temp_peer(char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--- build_peer: Build peer from config file ---*/
|
/*--- build_peer: Build peer from config file ---*/
|
||||||
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int temponly)
|
static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime)
|
||||||
{
|
{
|
||||||
struct sip_peer *peer = NULL;
|
struct sip_peer *peer = NULL;
|
||||||
struct ast_ha *oldha = NULL;
|
struct ast_ha *oldha = NULL;
|
||||||
int maskfound=0;
|
int maskfound=0;
|
||||||
int obproxyfound=0;
|
int obproxyfound=0;
|
||||||
int found=0;
|
int found=0;
|
||||||
|
time_t regseconds;
|
||||||
|
|
||||||
if (!temponly)
|
if (!realtime)
|
||||||
/* Note we do NOT use find_peer here, to avoid realtime recursion */
|
/* Note we do NOT use find_peer here, to avoid realtime recursion */
|
||||||
peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name);
|
peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name);
|
||||||
|
|
||||||
|
@ -8797,7 +8772,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
|
||||||
peer = malloc(sizeof(struct sip_peer));
|
peer = malloc(sizeof(struct sip_peer));
|
||||||
if (peer) {
|
if (peer) {
|
||||||
memset(peer, 0, sizeof(struct sip_peer));
|
memset(peer, 0, sizeof(struct sip_peer));
|
||||||
if (temponly)
|
if (realtime)
|
||||||
rpeerobjs++;
|
rpeerobjs++;
|
||||||
else
|
else
|
||||||
speerobjs++;
|
speerobjs++;
|
||||||
|
@ -8838,7 +8813,12 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmp(v->name, "name"))
|
if (realtime && !strcasecmp(v->name, "regseconds")) {
|
||||||
|
if (sscanf(v->value, "%li", ®seconds) != 1)
|
||||||
|
regseconds = 0;
|
||||||
|
} else if (realtime && !strcasecmp(v->name, "ipaddr")) {
|
||||||
|
inet_aton(v->value, &(peer->addr.sin_addr));
|
||||||
|
} else if (realtime && !strcasecmp(v->name, "name"))
|
||||||
strncpy(peer->name, v->value, sizeof(peer->name)-1);
|
strncpy(peer->name, v->value, sizeof(peer->name)-1);
|
||||||
else if (!strcasecmp(v->name, "secret"))
|
else if (!strcasecmp(v->name, "secret"))
|
||||||
strncpy(peer->secret, v->value, sizeof(peer->secret)-1);
|
strncpy(peer->secret, v->value, sizeof(peer->secret)-1);
|
||||||
|
@ -8880,7 +8860,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
|
||||||
ast_clear_flag(peer, SIP_DYNAMIC);
|
ast_clear_flag(peer, SIP_DYNAMIC);
|
||||||
if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
|
if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
|
||||||
if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
|
if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
|
||||||
ASTOBJ_DESTROY(peer, sip_destroy_peer);
|
ASTOBJ_UNREF(peer, sip_destroy_peer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8893,7 +8873,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
|
||||||
inet_aton("255.255.255.255", &peer->mask);
|
inet_aton("255.255.255.255", &peer->mask);
|
||||||
} else if (!strcasecmp(v->name, "defaultip")) {
|
} else if (!strcasecmp(v->name, "defaultip")) {
|
||||||
if (ast_get_ip(&peer->defaddr, v->value)) {
|
if (ast_get_ip(&peer->defaddr, v->value)) {
|
||||||
ASTOBJ_DESTROY(peer, sip_destroy_peer);
|
ASTOBJ_UNREF(peer, sip_destroy_peer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(v->name, "permit") ||
|
} else if (!strcasecmp(v->name, "permit") ||
|
||||||
|
@ -8903,7 +8883,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
|
||||||
maskfound++;
|
maskfound++;
|
||||||
inet_aton(v->value, &peer->mask);
|
inet_aton(v->value, &peer->mask);
|
||||||
} else if (!strcasecmp(v->name, "port")) {
|
} else if (!strcasecmp(v->name, "port")) {
|
||||||
if (ast_test_flag(peer, SIP_DYNAMIC))
|
if (!realtime && ast_test_flag(peer, SIP_DYNAMIC))
|
||||||
peer->defaddr.sin_port = htons(atoi(v->value));
|
peer->defaddr.sin_port = htons(atoi(v->value));
|
||||||
else
|
else
|
||||||
peer->addr.sin_port = htons(atoi(v->value));
|
peer->addr.sin_port = htons(atoi(v->value));
|
||||||
|
@ -8955,6 +8935,16 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
|
||||||
*/
|
*/
|
||||||
v=v->next;
|
v=v->next;
|
||||||
}
|
}
|
||||||
|
if (realtime && ast_test_flag(peer, SIP_DYNAMIC)) {
|
||||||
|
time_t nowtime;
|
||||||
|
|
||||||
|
time(&nowtime);
|
||||||
|
if ((nowtime - regseconds) > 0) {
|
||||||
|
memset(&peer->addr, 0, sizeof(peer->addr));
|
||||||
|
if (option_debug)
|
||||||
|
ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime);
|
||||||
|
}
|
||||||
|
}
|
||||||
ast_copy_flags(peer, &peerflags, mask.flags);
|
ast_copy_flags(peer, &peerflags, mask.flags);
|
||||||
if (!found && ast_test_flag(peer, SIP_DYNAMIC))
|
if (!found && ast_test_flag(peer, SIP_DYNAMIC))
|
||||||
reg_source_db(peer);
|
reg_source_db(peer);
|
||||||
|
@ -9200,7 +9190,7 @@ static int reload_config(void)
|
||||||
utype = ast_variable_retrieve(cfg, cat, "type");
|
utype = ast_variable_retrieve(cfg, cat, "type");
|
||||||
if (utype) {
|
if (utype) {
|
||||||
if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
|
if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
|
||||||
user = build_user(cat, ast_variable_browse(cfg, cat));
|
user = build_user(cat, ast_variable_browse(cfg, cat), 0);
|
||||||
if (user) {
|
if (user) {
|
||||||
ASTOBJ_CONTAINER_LINK(&userl,user);
|
ASTOBJ_CONTAINER_LINK(&userl,user);
|
||||||
ASTOBJ_UNREF(user, sip_destroy_user);
|
ASTOBJ_UNREF(user, sip_destroy_user);
|
||||||
|
|
|
@ -32,8 +32,7 @@ extern "C" {
|
||||||
#define ASTOBJ_DEFAULT_BUCKETS 256
|
#define ASTOBJ_DEFAULT_BUCKETS 256
|
||||||
#define ASTOBJ_DEFAULT_HASH ast_strhash
|
#define ASTOBJ_DEFAULT_HASH ast_strhash
|
||||||
|
|
||||||
#define ASTOBJ_FLAG_DELME (1 << 0) /* Object has been deleted, remove on last unref */
|
#define ASTOBJ_FLAG_MARKED (1 << 0) /* Object has been marked for future operation */
|
||||||
#define ASTOBJ_FLAG_MARKED (1 << 1) /* Object has been marked for possible deletion */
|
|
||||||
|
|
||||||
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
|
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
|
||||||
#define __builtin_expect(exp, c) (exp)
|
#define __builtin_expect(exp, c) (exp)
|
||||||
|
@ -81,13 +80,17 @@ extern "C" {
|
||||||
|
|
||||||
#define ASTOBJ_UNREF(object,destructor) \
|
#define ASTOBJ_UNREF(object,destructor) \
|
||||||
do { \
|
do { \
|
||||||
|
int newcount = 0; \
|
||||||
ASTOBJ_WRLOCK(object); \
|
ASTOBJ_WRLOCK(object); \
|
||||||
if (__builtin_expect((object)->refcount, 1)) \
|
if (__builtin_expect((object)->refcount, 1)) \
|
||||||
(object)->refcount--; \
|
newcount = --((object)->refcount); \
|
||||||
else \
|
else \
|
||||||
ast_log(LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \
|
ast_log(LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \
|
||||||
ASTOBJ_UNLOCK(object); \
|
ASTOBJ_UNLOCK(object); \
|
||||||
ASTOBJ_DESTROY(object,destructor); \
|
if (newcount == 0) { \
|
||||||
|
ast_mutex_destroy(&(object)->_lock); \
|
||||||
|
destructor((object)); \
|
||||||
|
} \
|
||||||
(object) = NULL; \
|
(object) = NULL; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
@ -105,18 +108,6 @@ extern "C" {
|
||||||
ASTOBJ_UNLOCK(object); \
|
ASTOBJ_UNLOCK(object); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define ASTOBJ_DESTROY(object,destructor) \
|
|
||||||
do { \
|
|
||||||
if (__builtin_expect((object)->refcount, 1)) { \
|
|
||||||
ASTOBJ_WRLOCK(object); \
|
|
||||||
(object)->objflags |= ASTOBJ_FLAG_DELME; \
|
|
||||||
ASTOBJ_UNLOCK(object); \
|
|
||||||
} else { \
|
|
||||||
ast_mutex_destroy(&(object)->_lock); \
|
|
||||||
destructor((object)); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define ASTOBJ_INIT(object) \
|
#define ASTOBJ_INIT(object) \
|
||||||
do { \
|
do { \
|
||||||
ast_mutex_init(&(object)->_lock); \
|
ast_mutex_init(&(object)->_lock); \
|
||||||
|
@ -190,7 +181,6 @@ extern "C" {
|
||||||
ASTOBJ_CONTAINER_WRLOCK(container); \
|
ASTOBJ_CONTAINER_WRLOCK(container); \
|
||||||
while((iterator = (container)->head)) { \
|
while((iterator = (container)->head)) { \
|
||||||
(container)->head = (iterator)->next[0]; \
|
(container)->head = (iterator)->next[0]; \
|
||||||
ASTOBJ_DESTROY(iterator,destructor); \
|
|
||||||
ASTOBJ_UNREF(iterator,destructor); \
|
ASTOBJ_UNREF(iterator,destructor); \
|
||||||
} \
|
} \
|
||||||
ASTOBJ_CONTAINER_UNLOCK(container); \
|
ASTOBJ_CONTAINER_UNLOCK(container); \
|
||||||
|
@ -203,6 +193,7 @@ extern "C" {
|
||||||
ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
|
ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
|
||||||
if (!(strcasecmp(iterator->name, (namestr)))) { \
|
if (!(strcasecmp(iterator->name, (namestr)))) { \
|
||||||
found = iterator; \
|
found = iterator; \
|
||||||
|
found->next[0] = NULL; \
|
||||||
ASTOBJ_CONTAINER_WRLOCK(container); \
|
ASTOBJ_CONTAINER_WRLOCK(container); \
|
||||||
if (prev) \
|
if (prev) \
|
||||||
prev->next[0] = next; \
|
prev->next[0] = next; \
|
||||||
|
@ -223,6 +214,7 @@ extern "C" {
|
||||||
ASTOBJ_RDLOCK(iterator); \
|
ASTOBJ_RDLOCK(iterator); \
|
||||||
if (!(comparefunc(iterator->field, (data)))) { \
|
if (!(comparefunc(iterator->field, (data)))) { \
|
||||||
found = iterator; \
|
found = iterator; \
|
||||||
|
found->next[0] = NULL; \
|
||||||
ASTOBJ_CONTAINER_WRLOCK(container); \
|
ASTOBJ_CONTAINER_WRLOCK(container); \
|
||||||
if (prev) \
|
if (prev) \
|
||||||
prev->next[0] = next; \
|
prev->next[0] = next; \
|
||||||
|
@ -249,7 +241,7 @@ extern "C" {
|
||||||
(container)->head = next; \
|
(container)->head = next; \
|
||||||
ASTOBJ_CONTAINER_UNLOCK(container); \
|
ASTOBJ_CONTAINER_UNLOCK(container); \
|
||||||
ASTOBJ_UNLOCK(iterator); \
|
ASTOBJ_UNLOCK(iterator); \
|
||||||
ASTOBJ_DESTROY(iterator,destructor); \
|
ASTOBJ_UNREF(iterator,destructor); \
|
||||||
continue; \
|
continue; \
|
||||||
} \
|
} \
|
||||||
ASTOBJ_UNLOCK(iterator); \
|
ASTOBJ_UNLOCK(iterator); \
|
||||||
|
|
Reference in a new issue