[asterisk-commits] russell: branch russell/iax_refcount r79626 - in /team/russell/iax_refcount: ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Aug 15 16:45:55 CDT 2007
Author: russell
Date: Wed Aug 15 16:45:54 2007
New Revision: 79626
URL: http://svn.digium.com/view/asterisk?view=rev&rev=79626
Log:
Convert iax2_peer handling to astobj2
Modified:
team/russell/iax_refcount/channels/chan_iax2.c
team/russell/iax_refcount/include/asterisk/strings.h
Modified: team/russell/iax_refcount/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/iax_refcount/channels/chan_iax2.c?view=diff&rev=79626&r1=79625&r2=79626
==============================================================================
--- team/russell/iax_refcount/channels/chan_iax2.c (original)
+++ team/russell/iax_refcount/channels/chan_iax2.c Wed Aug 15 16:45:54 2007
@@ -94,6 +94,7 @@
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
+#include "asterisk/astobj2.h"
#include "iax2.h"
#include "iax2-parser.h"
@@ -358,10 +359,6 @@
int smoothing; /*!< Sample over how many units to determine historic ms */
struct ast_ha *ha;
-
- unsigned int ref_count;
-
- AST_LIST_ENTRY(iax2_peer) entry;
};
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
@@ -637,7 +634,12 @@
static AST_LIST_HEAD_STATIC(users, iax2_user);
-static AST_LIST_HEAD_STATIC(peers, iax2_peer);
+#ifdef LOW_MEMORY
+#define MAX_PEER_BUCKETS 17
+#else
+#define MAX_PEER_BUCKETS 563
+#endif
+static ao2_container *peers;
static struct ast_firmware_list {
struct iax_firmware *wares;
@@ -678,7 +680,6 @@
static void reg_source_db(struct iax2_peer *p);
static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
-static void destroy_peer(struct iax2_peer *peer);
static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
#define IAX_IOSTATE_IDLE 0
@@ -1045,35 +1046,19 @@
return csub;
}
-static void ref_peer(struct iax2_peer *peer)
-{
- ast_atomic_fetchadd_int((int *) &peer->ref_count, +1);
-}
-
-static struct iax2_peer *unref_peer(struct iax2_peer *peer)
-{
- unsigned int destroy = 0;
-
- /* "Realtime" peers marked with the TEMPONLY flag are objects with only a
- * single reference. Once the reference gets released, destroy it. */
- if (ast_test_flag(peer, IAX_TEMPONLY)) {
- destroy_peer(peer);
- return NULL;
- }
-
- AST_LIST_LOCK(&peers);
- /* If we hold the last reference to this peer and it has been marked for deletion,
- * then ensure it has been removed from the peer list and then destroy it. */
- if (ast_atomic_dec_and_test((int *) &peer->ref_count) && ast_test_flag(peer, IAX_DELME)) {
- AST_LIST_REMOVE(&peers, peer, entry);
- destroy = 1;
- }
- AST_LIST_UNLOCK(&peers);
-
- if (destroy)
- destroy_peer(peer);
-
- return NULL;
+static int peer_hash_cb(const void *obj, const int flags)
+{
+ const struct iax2_peer *peer = obj;
+
+ return ast_str_hash(peer->name);
+}
+
+static int peer_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct iax2_peer *peer = obj;
+ const char *name = arg;
+
+ return strcasecmp(peer->name, name);
}
/*!
@@ -1084,19 +1069,12 @@
{
struct iax2_peer *peer = NULL;
- /* Grab peer from linked list */
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry) {
- if (!strcasecmp(peer->name, name)) {
- ref_peer(peer);
- break;
- }
- }
- AST_LIST_UNLOCK(&peers);
+ peer = ao2_find(peers, (void *) name, OBJ_NODATA);
/* Now go for realtime if applicable */
if(!peer && realtime)
peer = realtime_peer(name, NULL);
+
return peer;
}
@@ -1104,22 +1082,25 @@
{
struct iax2_peer *peer = NULL;
int res = 0;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry) {
+ ao2_iterator i;
+
+ i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_iterator_next(&i))) {
if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
(peer->addr.sin_port == sin.sin_port)) {
ast_copy_string(host, peer->name, len);
+ ao2_ref(peer, -1);
res = 1;
break;
}
- }
- AST_LIST_UNLOCK(&peers);
+ ao2_ref(peer, -1);
+ }
+
if (!peer) {
peer = realtime_peer(NULL, &sin);
if (peer) {
ast_copy_string(host, peer->name, len);
- unref_peer(peer);
+ ao2_ref(peer, -1);
res = 1;
}
}
@@ -2017,7 +1998,7 @@
} else {
ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
}
- unref_peer(peer);
+ ao2_ref(peer, -1);
} else {
ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
}
@@ -2144,7 +2125,7 @@
ast_cli(fd, "%s\n",status);
ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
ast_cli(fd,"\n");
- unref_peer(peer);
+ ao2_ref(peer, -1);
} else {
ast_cli(fd,"Peer %s not found.\n", argv[3]);
ast_cli(fd,"\n");
@@ -2156,20 +2137,23 @@
static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
{
int which = 0;
- struct iax2_peer *p = NULL;
+ struct iax2_peer *peer;
char *res = NULL;
int wordlen = strlen(word);
+ ao2_iterator i;
/* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
- if (pos == 3) {
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, p, entry) {
- if (!strncasecmp(p->name, word, wordlen) && ++which > state) {
- res = ast_strdup(p->name);
- break;
- }
- }
- AST_LIST_UNLOCK(&peers);
+ if (pos != 3)
+ return NULL;
+
+ i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_iterator_next(&i))) {
+ if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
+ res = ast_strdup(peer->name);
+ ao2_ref(peer, -1);
+ break;
+ }
+ ao2_ref(peer, -1);
}
return res;
@@ -2583,7 +2567,7 @@
if (strcasecmp(tmp->value, "friend") &&
strcasecmp(tmp->value, "peer")) {
/* Whoops, we weren't supposed to exist! */
- destroy_peer(peer);
+ ao2_ref(peer, -1);
peer = NULL;
break;
}
@@ -2611,10 +2595,7 @@
ast_sched_del(sched, peer->expire);
peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
}
- peer->ref_count = 1;
- AST_LIST_LOCK(&peers);
- AST_LIST_INSERT_HEAD(&peers, peer, entry);
- AST_LIST_UNLOCK(&peers);
+ ao2_link(peers, peer);
if (ast_test_flag(peer, IAX_DYNAMIC))
reg_source_db(peer);
} else {
@@ -2791,7 +2772,7 @@
res = 0;
return_unref:
- unref_peer(peer);
+ ao2_ref(peer, -1);
return res;
}
@@ -3364,18 +3345,20 @@
static int iax2_getpeertrunk(struct sockaddr_in sin)
{
- struct iax2_peer *peer = NULL;
+ struct iax2_peer *peer;
int res = 0;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry) {
+ ao2_iterator i;
+
+ i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_iterator_next(&i))) {
if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
(peer->addr.sin_port == sin.sin_port)) {
res = ast_test_flag(peer, IAX_TRUNK);
+ ao2_ref(peer, -1);
break;
}
- }
- AST_LIST_UNLOCK(&peers);
+ ao2_ref(peer, -1);
+ }
return res;
}
@@ -4151,6 +4134,7 @@
int online_peers = 0;
int offline_peers = 0;
int unmonitored_peers = 0;
+ ao2_iterator i;
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
@@ -4199,8 +4183,9 @@
else
ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry) {
+ i = ao2_iterator_init(peers, 0);
+ for (peer = ao2_iterator_next(&i); peer;
+ ao2_ref(peer, -1), peer = ao2_iterator_next(&i)) {
char nm[20];
char status[20];
char srch[2000];
@@ -4249,7 +4234,6 @@
peer->encmethods ? "(E)" : " ", status, term);
total_peers++;
}
- AST_LIST_UNLOCK(&peers);
if (s)
astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
@@ -5190,7 +5174,7 @@
res = 0;
return_unref:
- unref_peer(p);
+ ao2_ref(p, -1);
return res;
}
@@ -5279,8 +5263,8 @@
/* Normal password authentication */
res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
} else {
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry) {
+ ao2_iterator i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_iterator_next(&i))) {
if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
/* No peer specified at our end, or this is the peer */
&& (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
@@ -5289,11 +5273,11 @@
/* No specified host, or this is our host */
) {
res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
+ ao2_ref(peer, -1);
if (!res)
break;
}
}
- AST_LIST_UNLOCK(&peers);
if (!peer) {
/* We checked our list and didn't find one. It's unlikely, but possible,
that we're trying to authenticate *to* a realtime peer */
@@ -5302,11 +5286,11 @@
if ((peer = realtime_peer(peer_name, NULL))) {
ast_mutex_lock(&iaxsl[callno]);
if (!(p = iaxs[callno])) {
- unref_peer(peer);
+ ao2_ref(peer, -1);
return -1;
}
res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
- unref_peer(peer);
+ ao2_ref(peer, -1);
}
if (!peer) {
ast_mutex_lock(&iaxsl[callno]);
@@ -5610,43 +5594,33 @@
static void __expire_registry(void *data)
{
char *name = data;
- struct iax2_peer *p = NULL;
-
- /* Go through and grab this peer... and if it needs to be removed... then do it */
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) {
- if (!strcasecmp(p->name, name)) {
- ref_peer(p);
- p->expire = -1;
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&peers);
-
- /* Peer is already gone for whatever reason */
- if (!p)
+ struct iax2_peer *peer = NULL;
+
+ peer = ao2_find(peers, name, OBJ_NODATA);
+ if (!peer)
return;
- ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
- if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
- realtime_update_peer(p->name, &p->addr, 0);
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name);
+ peer->expire = -1;
+
+ ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
+ if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
+ realtime_update_peer(peer->name, &peer->addr, 0);
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
/* Reset the address */
- memset(&p->addr, 0, sizeof(p->addr));
+ memset(&peer->addr, 0, sizeof(peer->addr));
/* Reset expiry value */
- p->expiry = min_reg_expire;
- if (!ast_test_flag(p, IAX_TEMPONLY))
- ast_db_del("IAX/Registry", p->name);
- register_peer_exten(p, 0);
- ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
+ peer->expiry = min_reg_expire;
+ if (!ast_test_flag(peer, IAX_TEMPONLY))
+ ast_db_del("IAX/Registry", peer->name);
+ register_peer_exten(peer, 0);
+ ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
if (iax2_regfunk)
- iax2_regfunk(p->name, 0);
-
- if (ast_test_flag(p, IAX_RTAUTOCLEAR))
- ast_set_flag(p, IAX_DELME);
+ iax2_regfunk(peer->name, 0);
+
+ if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
+ ao2_unlink(peers, peer);
- unref_peer(p);
+ ao2_ref(peer, -1);
}
static int expire_registry(void *data)
@@ -5815,7 +5789,7 @@
res = 0;
return_unref:
- unref_peer(p);
+ ao2_ref(p, -1);
return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
}
@@ -5852,7 +5826,7 @@
iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
return_unref:
- unref_peer(p);
+ ao2_ref(p, -1);
return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
}
@@ -8276,6 +8250,15 @@
return 0;
}
+static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
+{
+ struct iax2_peer *peer = obj;
+
+ iax2_poke_peer(peer, 0);
+
+ return 0;
+}
+
static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
{
if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
@@ -8666,7 +8649,31 @@
}
}
-
+static void peer_destructor(void *obj)
+{
+ struct iax2_peer *peer = obj;
+
+ ast_free_ha(peer->ha);
+
+ /* Delete it, it needs to disappear */
+ if (peer->expire > -1)
+ ast_sched_del(sched, peer->expire);
+ if (peer->pokeexpire > -1)
+ ast_sched_del(sched, peer->pokeexpire);
+ if (peer->callno > 0) {
+ ast_mutex_lock(&iaxsl[peer->callno]);
+ iax2_destroy(peer->callno);
+ ast_mutex_unlock(&iaxsl[peer->callno]);
+ }
+
+ register_peer_exten(peer, 0);
+
+ if (peer->dnsmgr)
+ ast_dnsmgr_release(peer->dnsmgr);
+
+ ast_string_field_free_pools(peer);
+}
+
/*! \brief Create peer structure based on configuration */
static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
{
@@ -8676,37 +8683,29 @@
int found=0;
int firstpass=1;
- AST_LIST_LOCK(&peers);
if (!temponly) {
- AST_LIST_TRAVERSE(&peers, peer, entry) {
- if (!strcmp(peer->name, name)) {
- if (!ast_test_flag(peer, IAX_DELME))
- firstpass = 0;
- break;
- }
- }
- } else
- peer = NULL;
+ peer = ao2_find(peers, (void *) name, OBJ_NODATA);
+ if (!ast_test_flag(peer, IAX_DELME))
+ firstpass = 0;
+ }
+
if (peer) {
found++;
if (firstpass) {
oldha = peer->ha;
peer->ha = NULL;
}
- AST_LIST_REMOVE(&peers, peer, entry);
- AST_LIST_UNLOCK(&peers);
- } else {
- AST_LIST_UNLOCK(&peers);
- if ((peer = ast_calloc(1, sizeof(*peer)))) {
- peer->expire = -1;
- peer->pokeexpire = -1;
- peer->sockfd = defaultsockfd;
- if (ast_string_field_init(peer, 32)) {
- free(peer);
- peer = NULL;
- }
- }
- }
+ ao2_unlink(peers, peer);
+ } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
+ peer->expire = -1;
+ peer->pokeexpire = -1;
+ peer->sockfd = defaultsockfd;
+ if (ast_string_field_init(peer, 32)) {
+ ao2_ref(peer, -1);
+ peer = NULL;
+ }
+ }
+
if (peer) {
if (firstpass) {
ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
@@ -8792,7 +8791,7 @@
ast_clear_flag(peer, IAX_DYNAMIC);
if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
ast_string_field_free_pools(peer);
- free(peer);
+ ao2_ref(peer, -1);
return NULL;
}
if (!peer->addr.sin_port)
@@ -8803,7 +8802,7 @@
} else if (!strcasecmp(v->name, "defaultip")) {
if (ast_get_ip(&peer->defaddr, v->value)) {
ast_string_field_free_pools(peer);
- free(peer);
+ ao2_ref(peer, -1);
return NULL;
}
} else if (!strcasecmp(v->name, "sourceaddress")) {
@@ -9129,10 +9128,18 @@
return user;
}
+static int peer_delme_cb(void *obj, void *arg, int flags)
+{
+ struct iax2_peer *peer = obj;
+
+ ast_set_flag(peer, IAX_DELME);
+
+ return 0;
+}
+
static void delete_users(void)
{
struct iax2_user *user;
- struct iax2_peer *peer;
struct iax2_registry *reg;
AST_LIST_LOCK(&users);
@@ -9158,10 +9165,7 @@
}
AST_LIST_UNLOCK(®istrations);
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry)
- ast_set_flag(peer, IAX_DELME);
- AST_LIST_UNLOCK(&peers);
+ ao2_callback(peers, 0, peer_delme_cb, NULL);
}
static void destroy_user(struct iax2_user *user)
@@ -9192,46 +9196,18 @@
}
-static void destroy_peer(struct iax2_peer *peer)
-{
- ast_free_ha(peer->ha);
-
- /* Delete it, it needs to disappear */
- if (peer->expire > -1)
- ast_sched_del(sched, peer->expire);
- if (peer->pokeexpire > -1)
- ast_sched_del(sched, peer->pokeexpire);
- if (peer->callno > 0) {
- ast_mutex_lock(&iaxsl[peer->callno]);
- iax2_destroy(peer->callno);
- ast_mutex_unlock(&iaxsl[peer->callno]);
- }
-
- register_peer_exten(peer, 0);
-
- if (peer->dnsmgr)
- ast_dnsmgr_release(peer->dnsmgr);
-
- ast_string_field_free_pools(peer);
-
- free(peer);
-}
-
+/* Prune peers who still are supposed to be deleted */
static void prune_peers(void)
{
- /* Prune peers who still are supposed to be deleted */
- struct iax2_peer *peer = NULL;
-
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) {
- /* Just remove the peer from the list. If it is still in the list, then
- * someone still has a reference to it. When they release the reference,
- * the peer will get destroyed. */
+ struct iax2_peer *peer;
+ ao2_iterator i;
+
+ i = ao2_iterator_init(peers, 0);
+ while ((peer = ao2_iterator_next(&i))) {
if (ast_test_flag(peer, IAX_DELME))
- AST_LIST_REMOVE_CURRENT(&peers, entry);
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&peers);
+ ao2_unlink(peers, peer);
+ ao2_ref(peer, -1);
+ }
}
static void set_timing(void)
@@ -9541,11 +9517,9 @@
}
peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
if (peer) {
- AST_LIST_LOCK(&peers);
- AST_LIST_INSERT_HEAD(&peers, peer, entry);
- AST_LIST_UNLOCK(&peers);
if (ast_test_flag(peer, IAX_DYNAMIC))
reg_source_db(peer);
+ ao2_link(peers, peer);
}
}
if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
@@ -9589,11 +9563,9 @@
if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
if (peer) {
- AST_LIST_LOCK(&peers);
- AST_LIST_INSERT_HEAD(&peers, peer, entry);
- AST_LIST_UNLOCK(&peers);
if (ast_test_flag(peer, IAX_DYNAMIC))
reg_source_db(peer);
+ ao2_link(peers, peer);
}
} else if (strcasecmp(utype, "user")) {
ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
@@ -9612,7 +9584,6 @@
{
char *config = "iax.conf";
struct iax2_registry *reg;
- struct iax2_peer *peer;
strcpy(accountcode, "");
strcpy(language, "");
@@ -9633,10 +9604,7 @@
iax2_do_register(reg);
AST_LIST_UNLOCK(®istrations);
/* Qualify hosts, too */
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry)
- iax2_poke_peer(peer, 0);
- AST_LIST_UNLOCK(&peers);
+ ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
reload_firmware();
iax_provision_reload();
@@ -10051,7 +10019,7 @@
}
}
- unref_peer(peer);
+ ao2_ref(peer, -1);
return 0;
}
@@ -10112,7 +10080,7 @@
res = AST_DEVICE_UNKNOWN;
}
- unref_peer(p);
+ ao2_ref(p, -1);
return res;
}
@@ -10425,6 +10393,8 @@
for (x = 0; x < IAX_MAX_CALLS; x++)
ast_mutex_destroy(&iaxsl[x]);
+ ao2_ref(peers, -1);
+
return 0;
}
@@ -10434,6 +10404,15 @@
return __unload_module();
}
+static int peer_set_sock_cb(void *obj, void *arg, int flags)
+{
+ struct iax2_peer *peer = obj;
+
+ if (peer->sockfd < 0)
+ peer->sockfd = defaultsockfd;
+
+ return 0;
+}
/*! \brief Load IAX2 module, load configuraiton ---*/
static int load_module(void)
@@ -10442,8 +10421,11 @@
int res = 0;
int x;
struct iax2_registry *reg = NULL;
- struct iax2_peer *peer = NULL;
-
+
+ peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
+ if (!peers)
+ return AST_MODULE_LOAD_FAILURE;
+
ast_custom_function_register(&iaxpeer_function);
iax_set_output(iax_debug_output);
@@ -10527,13 +10509,9 @@
iax2_do_register(reg);
AST_LIST_UNLOCK(®istrations);
- AST_LIST_LOCK(&peers);
- AST_LIST_TRAVERSE(&peers, peer, entry) {
- if (peer->sockfd < 0)
- peer->sockfd = defaultsockfd;
- iax2_poke_peer(peer, 0);
- }
- AST_LIST_UNLOCK(&peers);
+ ao2_callback(peers, 0, peer_set_sock_cb, NULL);
+ ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
+
reload_firmware();
iax_provision_reload();
return res;
Modified: team/russell/iax_refcount/include/asterisk/strings.h
URL: http://svn.digium.com/view/asterisk/team/russell/iax_refcount/include/asterisk/strings.h?view=diff&rev=79626&r1=79625&r2=79626
==============================================================================
--- team/russell/iax_refcount/include/asterisk/strings.h (original)
+++ team/russell/iax_refcount/include/asterisk/strings.h Wed Aug 15 16:45:54 2007
@@ -256,4 +256,22 @@
(ra)->ptr; \
})
+/*!
+ * \brief Compute a hash value on a string
+ *
+ * This famous hash algorithm was written by Dan Bernstein and is
+ * commonly used.
+ *
+ * http://www.cse.yorku.ca/~oz/hash.html
+ */
+static force_inline int ast_str_hash(const char *str)
+{
+ int hash = 0;
+
+ while (*str)
+ hash = hash * 33 ^ *str++;
+
+ return hash;
+}
+
#endif /* _ASTERISK_STRINGS_H */
More information about the asterisk-commits
mailing list