[asterisk-commits] murf: branch murf/bug11210 r89317 - /team/murf/bug11210/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Nov 15 18:18:24 CST 2007
Author: murf
Date: Thu Nov 15 18:18:23 2007
New Revision: 89317
URL: http://svn.digium.com/view/asterisk?view=rev&rev=89317
Log:
about halfway on updating chan_sip. Don't expect this to compile
Modified:
team/murf/bug11210/channels/chan_sip.c
Modified: team/murf/bug11210/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_sip.c?view=diff&rev=89317&r1=89316&r2=89317
==============================================================================
--- team/murf/bug11210/channels/chan_sip.c (original)
+++ team/murf/bug11210/channels/chan_sip.c Thu Nov 15 18:18:23 2007
@@ -130,7 +130,7 @@
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
-#include "asterisk/astobj.h"
+#include "asterisk/astobj2.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
@@ -1198,7 +1198,7 @@
/*! \brief Structure for SIP user data. User's place calls to us */
struct sip_user {
/* Users who can access various contexts */
- ASTOBJ_COMPONENTS(struct sip_user);
+ char name[80];
char secret[80]; /*!< Password */
char md5secret[80]; /*!< Password in md5 */
char context[AST_MAX_CONTEXT]; /*!< Default context for incoming calls */
@@ -1248,8 +1248,7 @@
/*! \brief Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host) */
/* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
struct sip_peer {
- ASTOBJ_COMPONENTS(struct sip_peer); /*!< name, refcount, objflags, object pointers */
- /*!< peer->name is the unique name of this object */
+ char name[80]; /*!< peer->name is the unique name of this object */
char secret[80]; /*!< Password */
char md5secret[80]; /*!< Password in MD5 */
struct sip_auth *auth; /*!< Realm authentication list */
@@ -1333,7 +1332,6 @@
* as the dialoglist is also manipulated by other threads.
*/
struct sip_registry {
- ASTOBJ_COMPONENTS_FULL(struct sip_registry,1,1);
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(callid); /*!< Global Call-ID */
AST_STRING_FIELD(realm); /*!< Authorization realm */
@@ -1365,23 +1363,91 @@
char lastmsg[256]; /*!< Last Message sent/received */
};
-/* --- Linked lists of various objects --------*/
+/* --- Hash tables of various objects --------*/
+
+#ifdef LOW_MEMORY
+#define MAX_PEER_BUCKETS 17
+#else
+#define MAX_PEER_BUCKETS 563
+#endif
+
+#define MAX_USER_BUCKETS MAX_PEER_BUCKETS
/*! \brief The user list: Users and friends */
static struct ast_user_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_user);
+ struct ao2_container *users;
} userl;
/*! \brief The peer list: Peers and Friends */
static struct ast_peer_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_peer);
+ struct ao2_container *peers;
} peerl;
/*! \brief The register list: Other SIP proxies we register with and place calls to */
static struct ast_register_list {
- ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
+ struct ao2_container *registry;
int recheck;
} regl;
+
+/*!
+ * \note The only member of the peer passed here guaranteed to be set is the name field
+ */
+static int peer_hash_cb(const void *obj, const int flags)
+{
+ const struct sip_peer *peer = obj;
+
+ return ast_str_hash(peer->name);
+}
+
+/*!
+ * \note The only member of the peer passed here guaranteed to be set is the name field
+ */
+static int peer_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct sip_peer *peer = obj, *peer2 = arg;
+
+ return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
+}
+
+/*!
+ * \note The only member of the user passed here guaranteed to be set is the name field
+ */
+static int user_hash_cb(const void *obj, const int flags)
+{
+ const struct sip_user *user = obj;
+
+ return ast_str_hash(user->name);
+}
+
+/*!
+ * \note The only member of the user passed here guaranteed to be set is the name field
+ */
+static int user_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct sip_user *user = obj, *user2 = arg;
+
+ return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
+}
+
+/*!
+ * \note The only member of the user passed here guaranteed to be set is the name field
+ */
+static int reg_hash_cb(const void *obj, const int flags)
+{
+ const struct sip_registry *reg = obj;
+
+ return ast_str_hash(reg->name);
+}
+
+/*!
+ * \note The only member of the user passed here guaranteed to be set is the name field
+ */
+static int reg_cmp_cb(void *obj, void *arg, int flags)
+{
+ struct sip_registry *reg = obj, *reg2 = arg;
+
+ return !strcasecmp(reg->name, reg2->name) ? CMP_MATCH : 0;
+}
static int temp_pvt_init(void *);
static void temp_pvt_cleanup(void *);
@@ -1881,26 +1947,28 @@
*/
static void unref_peer(struct sip_peer *peer)
{
- ASTOBJ_UNREF(peer, sip_destroy_peer);
+ ao2_unref(peer);
}
static void unref_user(struct sip_user *user)
{
- ASTOBJ_UNREF(user, sip_destroy_user);
+ ao2_unref(user);
}
static void *registry_unref(struct sip_registry *reg)
{
- ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1);
- ASTOBJ_UNREF(reg, sip_registry_destroy);
+ /* ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1); */
+ /* AO2 DOES'NT SUPPLY A FUNC TO GET THE OBJECT ACCESS COUNT */
+ ao2_unref(reg);
return NULL;
}
/*! \brief Add object reference to SIP registry */
static struct sip_registry *registry_addref(struct sip_registry *reg)
{
- ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1);
- return ASTOBJ_REF(reg); /* Add pointer to registry in packet */
+ /* ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1); */
+ ao2_ref(reg,1);
+ return reg; /* Add pointer to registry in packet */
}
/*! \brief Interface structure with callbacks used to connect to UDPTL module*/
@@ -3160,7 +3228,7 @@
peer->expire = ast_sched_replace(peer->expire, sched,
global_rtautoclear * 1000, expire_register, (void *) peer);
}
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
+ ao2_link(peerl->peers, peer);
} else {
peer->is_realtime = 1;
}
@@ -3190,10 +3258,13 @@
static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
{
struct sip_peer *p = NULL;
-
+ struct sip_peer tmp_peer;
+
+ ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
+
if (peer)
- p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
- else
+ p = ao2_find(peerl->peers, &tmp_peer, OBJ_POINTER);
+ else /* search by addr? */
p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
if (!p && realtime)
@@ -3250,7 +3321,7 @@
if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
suserobjs++;
- ASTOBJ_CONTAINER_LINK(&userl,user);
+ ao2_link(userl->users, user);
} else {
/* Move counter from s to r... */
suserobjs--;
@@ -3267,7 +3338,12 @@
* realtime storage (defined in extconfig.conf) */
static struct sip_user *find_user(const char *name, int realtime)
{
- struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name);
+ struct sip_user tmp;
+ struct sip_user *u;
+
+ ast_copy_string(tmp.name, name, sizeof(tmp.name));
+ u = ao2_find(userl->users, &tmp_user, OBJ_POINTER);
+
if (!u && realtime)
u = realtime_user(name);
return u;
@@ -5291,7 +5367,7 @@
return -1;
}
}
- if (!(reg = ast_calloc(1, sizeof(*reg)))) {
+ if (!(reg = ao2_alloc(sizeof(*reg), sip_registry_destroy))) {
ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
return -1;
}
@@ -5303,7 +5379,6 @@
}
regobjs++;
- ASTOBJ_INIT(reg);
ast_string_field_set(reg, callback, callback);
if (!ast_strlen_zero(username))
ast_string_field_set(reg, username, username);
@@ -5320,8 +5395,8 @@
reg->portno = portnum;
reg->callid_valid = FALSE;
reg->ocseq = INITIAL_CSEQ;
- ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */
- registry_unref(reg); /* release the reference given by ASTOBJ_INIT. The container has another reference */
+ ao2_link(regl->registry, reg);/* Add the new registry entry to the list */
+ registry_unref(reg); /* release the reference. The container has another reference */
return 0;
}
@@ -8597,7 +8672,7 @@
if (peer->selfdestruct ||
ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
- peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */
+ peer = ao2_find(peerl->peers, peer, OBJ_POINTER|OBJ_UNLINK); /* Remove from peer list */
unref_peer(peer); /* Remove from memory */
}
@@ -9176,9 +9251,9 @@
{
struct sip_peer *peer = userdata;
- ASTOBJ_RDLOCK(peer);
+ ao2_lock(peer);
sip_send_mwi_to_peer(peer, event, 0);
- ASTOBJ_UNLOCK(peer);
+ ao2_unlock(peer);
}
/*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem
@@ -9352,7 +9427,7 @@
/* Create peer if we have autocreate mode enabled */
peer = temp_peer(name);
if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
+ ao2_link(peerl->peers, peer);
sip_cancel_destroy(p);
switch (parse_register_contact(p, peer, req)) {
case PARSE_REGISTER_FAILED:
@@ -10287,7 +10362,8 @@
/* copy channel vars */
p->chanvars = copy_vars(peer->chanvars);
if (authpeer) {
- (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
+ ao2_ref(peer,1);
+ (*authpeer) = peer; /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
}
if (!ast_strlen_zero(peer->username)) {
@@ -10545,7 +10621,10 @@
char ilimits[40];
char iused[40];
int showall = FALSE;
-
+ struct ao2_iterator i;
+ struct sip_user *user;
+ struct sip_peer *peer;
+
switch (cmd) {
case CLI_INIT:
e->command = "sip show inuse";
@@ -10565,31 +10644,32 @@
showall = TRUE;
ast_cli(a->fd, FORMAT, "* User name", "In use", "Limit");
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->call_limit)
- snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
+
+ i = ao2_iterator_init(userl->users, 0);
+
+ while ((user = ao2_iterator_init(&i))) {
+ if (user->call_limit)
+ snprintf(ilimits, sizeof(ilimits), "%d", user->call_limit);
else
ast_copy_string(ilimits, "N/A", sizeof(ilimits));
- snprintf(iused, sizeof(iused), "%d", iterator->inUse);
- if (showall || iterator->call_limit)
- ast_cli(a->fd, FORMAT2, iterator->name, iused, ilimits);
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
+ snprintf(iused, sizeof(iused), "%d", user->inUse);
+ if (showall || user->call_limit)
+ ast_cli(a->fd, FORMAT2, user->name, iused, ilimits);
+ }
ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (iterator->call_limit)
- snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit);
+ i = ao2_iterator_init(peerl->peers, 0);
+
+ while ((peer = ao2_iterator_next(&i))) {
+ if (peer->call_limit)
+ snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
else
ast_copy_string(ilimits, "N/A", sizeof(ilimits));
- snprintf(iused, sizeof(iused), "%d/%d/%d", iterator->inUse, iterator->inRinging, iterator->onHold);
- if (showall || iterator->call_limit)
- ast_cli(a->fd, FORMAT2, iterator->name, iused, ilimits);
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
+ snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold);
+ if (showall || peer->call_limit)
+ ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
+ }
return CLI_SUCCESS;
#undef FORMAT
@@ -10661,7 +10741,9 @@
{
regex_t regexbuf;
int havepattern = FALSE;
-
+ struct sip_user *user;
+ struct ao2_iterator i;
+
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
switch (cmd) {
@@ -10691,11 +10773,13 @@
}
ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
+
+ i = ao2_iterator_init(userl->users, 0);
+
+ while ((user = ao2_iterator_next(&i))) {
if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
+ ao2_unlock(iterator);
continue;
}
@@ -10705,9 +10789,7 @@
iterator->context,
cli_yesno(iterator->ha != NULL),
nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT)));
- ASTOBJ_UNLOCK(iterator);
- } while (0)
- );
+ }
if (havepattern)
regfree(®exbuf);
@@ -10771,7 +10853,9 @@
{
regex_t regexbuf;
int havepattern = FALSE;
-
+ struct sip_peer *peer;
+ struct ao2_iterator i;
+
/* the last argument is left-aligned, so we don't need a size anyways */
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n"
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
@@ -10811,52 +10895,51 @@
if (!s) /* Normal list */
ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
+ i = ao2_iterator_init(peerl->peers, 0);
+ while ((peer = ao2_iterator_next(&i))) {
char status[20] = "";
char srch[2000];
char pstatus;
- ASTOBJ_RDLOCK(iterator);
-
- if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
+ if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
+ ao2_unlock(peer);
continue;
}
- if (!ast_strlen_zero(iterator->username) && !s)
- snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username);
+ if (!ast_strlen_zero(peer->username) && !s)
+ snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
else
- ast_copy_string(name, iterator->name, sizeof(name));
+ ast_copy_string(name, peer->name, sizeof(name));
- pstatus = peer_status(iterator, status, sizeof(status));
+ pstatus = peer_status(peer, status, sizeof(status));
if (pstatus == 1)
peers_mon_online++;
else if (pstatus == 0)
peers_mon_offline++;
else {
- if (iterator->addr.sin_port == 0)
+ if (peer->addr.sin_port == 0)
peers_unmon_offline++;
else
peers_unmon_online++;
}
snprintf(srch, sizeof(srch), FORMAT, name,
- iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
- iterator->host_dynamic ? " D " : " ", /* Dynamic or not? */
- ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
- iterator->ha ? " A " : " ", /* permit/deny */
- ntohs(iterator->addr.sin_port), status,
- realtimepeers ? (iterator->is_realtime ? "Cached RT":"") : "");
+ peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
+ peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
+ ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
+ peer->ha ? " A " : " ", /* permit/deny */
+ ntohs(peer->addr.sin_port), status,
+ realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
if (!s) {/* Normal CLI list */
ast_cli(fd, FORMAT, name,
- iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)",
- iterator->host_dynamic ? " D " : " ", /* Dynamic or not? */
- ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
- iterator->ha ? " A " : " ", /* permit/deny */
+ peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
+ peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
+ ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
+ peer->ha ? " A " : " ", /* permit/deny */
- ntohs(iterator->addr.sin_port), status,
- realtimepeers ? (iterator->is_realtime ? "Cached RT":"") : "");
+ ntohs(peer->addr.sin_port), status,
+ realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
} else { /* Manager format */
/* The names here need to be the same as other channels */
astman_append(s,
@@ -10874,22 +10957,20 @@
"Status: %s\r\n"
"RealtimeDevice: %s\r\n\r\n",
idtext,
- iterator->name,
- iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-",
- ntohs(iterator->addr.sin_port),
- iterator->host_dynamic ? "yes" : "no", /* Dynamic or not? */
- ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
- ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
- ast_test_flag(&iterator->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */
- iterator->ha ? "yes" : "no", /* permit/deny */
+ peer->name,
+ peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
+ ntohs(peer->addr.sin_port),
+ peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */
+ ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
+ ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
+ ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */
+ peer->ha ? "yes" : "no", /* permit/deny */
status,
- realtimepeers ? (iterator->is_realtime ? "yes":"no") : "no");
- }
-
- ASTOBJ_UNLOCK(iterator);
+ realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
+ }
total_peers++;
- } while(0) );
+ }
if (!s)
ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
@@ -11004,14 +11085,15 @@
/*! \brief Remove temporary realtime objects from memory (CLI) */
static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct sip_peer *peer;
- struct sip_user *user;
+ struct sip_peer *peer, *pi;
+ struct sip_user *user, *ui;
int pruneuser = FALSE;
int prunepeer = FALSE;
int multi = FALSE;
char *name = NULL;
regex_t regexbuf;
-
+ struct ao2_iterator i;
+
if (cmd == CLI_INIT) {
e->command = "sip prune realtime [peer|user|all] [all|like]";
e->usage =
@@ -11086,42 +11168,38 @@
if (multi) {
if (prunepeer) {
int pruned = 0;
-
- ASTOBJ_CONTAINER_WRLOCK(&peerl);
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_RDLOCK(iterator);
+
+ ao2_lock(peerl->peers); /* was WRLOCK */
+ i = ao2_iterator_init(peerl->peers, 0);
+ while ((pi = ao2_iterator_next(&i))) {
+ if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) {
+ continue;
+ };
+ if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
+ ASTOBJ_MARK(pi);
+ pruned++;
+ }
+ }
+ if (pruned) {
+ ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
+ ast_cli(a->fd, "%d peers pruned.\n", pruned);
+ } else
+ ast_cli(a->fd, "No peers found to prune.\n");
+ ASTOBJ_CONTAINER_UNLOCK(&peerl);
+ }
+ if (pruneuser) {
+ int pruned = 0;
+
+ ao2_lock(userl->users); /* was WRLOCK */
+ i = ao2_iterator_init(userl->users, 0);
+ while ((ui = ao2_iterator_next(&i))) {
if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
continue;
};
if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ASTOBJ_MARK(iterator);
pruned++;
}
- ASTOBJ_UNLOCK(iterator);
- } while (0) );
- if (pruned) {
- ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer);
- ast_cli(a->fd, "%d peers pruned.\n", pruned);
- } else
- ast_cli(a->fd, "No peers found to prune.\n");
- ASTOBJ_CONTAINER_UNLOCK(&peerl);
- }
- if (pruneuser) {
- int pruned = 0;
-
- ASTOBJ_CONTAINER_WRLOCK(&userl);
- ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do {
- ASTOBJ_RDLOCK(iterator);
- if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) {
- ASTOBJ_UNLOCK(iterator);
- continue;
- };
- if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
- ASTOBJ_MARK(iterator);
- pruned++;
- }
- ASTOBJ_UNLOCK(iterator);
} while (0) );
if (pruned) {
ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user);
@@ -11132,10 +11210,12 @@
}
} else {
if (prunepeer) {
- if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) {
+ struct sip_peer tmp;
+ ast_copy_string(tmp.name, name, sizeof(tmp.name));
+ if ((peer = ao2_find(peerl->peers, &tmp, OBJ_POINTER|OBJ_UNLINK))) {
if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
- ASTOBJ_CONTAINER_LINK(&peerl, peer);
+ ao2_link(peerl->peers, peer);
} else
ast_cli(a->fd, "Peer '%s' pruned.\n", name);
unref_peer(peer);
@@ -11143,10 +11223,12 @@
ast_cli(a->fd, "Peer '%s' not found.\n", name);
}
if (pruneuser) {
- if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) {
+ struct sip_user tmp;
+ ast_copy_string(tmp.name, name, sizeof(tmp.name));
+ if ((user = ao2_find(userl->users, &tmp, OBJ_POINTER|OBJ_UNLINK))) {
if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ast_cli(a->fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name);
- ASTOBJ_CONTAINER_LINK(&userl, user);
+ ao2_link(userl->users, user);
} else
ast_cli(a->fd, "User '%s' pruned.\n", name);
unref_user(user);
@@ -11597,7 +11679,7 @@
return CLI_SHOWUSAGE;
ast_cli(a->fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do {
- ASTOBJ_RDLOCK(iterator);
+ ASTOBJ_RDLOCK(iterator); /* was RDLOCK */
snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
if (iterator->regtime.tv_sec) {
ast_localtime(&iterator->regtime, &tm, NULL);
@@ -11605,7 +11687,7 @@
} else
tmpdat[0] = '\0';
ast_cli(a->fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
- ASTOBJ_UNLOCK(iterator);
+ ao2_unlock(iterator);
counter++;
} while(0));
ast_cli(a->fd, "%d SIP registrations.\n", counter);
@@ -12005,12 +12087,12 @@
int which = 0;
ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
- ASTOBJ_WRLOCK(iterator);
+ ASTOBJ_WRLOCK(iterator); /* was WRLOCK */
if (!strncasecmp(word, iterator->name, wordlen) &&
(!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
++which > state && iterator->expire > 0)
result = ast_strdup(iterator->name);
- ASTOBJ_UNLOCK(iterator);
+ ao2_unlock(iterator);
} while(0) );
return result;
}
@@ -16067,9 +16149,9 @@
if (p->subscribed == MWI_NOTIFICATION) {
transmit_response(p, "200 OK", req);
if (p->relatedpeer) { /* Send first notification */
- ASTOBJ_WRLOCK(p->relatedpeer);
+ ASTOBJ_WRLOCK(p->relatedpeer); /* was WRLOCK */
sip_send_mwi_to_peer(p->relatedpeer, NULL, 0);
- ASTOBJ_UNLOCK(p->relatedpeer);
+ ao2_unlock(p->relatedpeer);
}
} else {
struct sip_pvt *p_old;
@@ -17348,11 +17430,10 @@
struct ast_flags mask[2] = {{(0)}};
- if (!(user = ast_calloc(1, sizeof(*user))))
+ if (!(user = ao2_alloc(sizeof(*user), sip_destroy_user)))
return NULL;
suserobjs++;
- ASTOBJ_INIT(user);
ast_copy_string(user->name, name, sizeof(user->name));
oldha = user->ha;
user->ha = NULL;
@@ -17498,11 +17579,10 @@
{
struct sip_peer *peer;
- if (!(peer = ast_calloc(1, sizeof(*peer))))
+ if (!(peer = ao2_alloc(sizeof(*peer), sip_destroy_peer)))
return NULL;
apeerobjs++;
- ASTOBJ_INIT(peer);
set_peer_defaults(peer);
ast_copy_string(peer->name, name, sizeof(peer->name));
@@ -17566,7 +17646,7 @@
if (!(peer->objflags & ASTOBJ_FLAG_MARKED))
firstpass = 0;
} else {
- if (!(peer = ast_calloc(1, sizeof(*peer))))
+ if (!(peer = ao2_alloc(sizeof(*peer),sip_destroy_peer)))
return NULL;
if (realtime) {
@@ -17574,7 +17654,6 @@
ast_debug(3,"-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
} else
speerobjs++;
- ASTOBJ_INIT(peer);
}
/* Note that our peer HAS had its reference count incrased */
if (firstpass) {
@@ -17870,20 +17949,20 @@
/* First, destroy all outstanding registry calls */
/* This is needed, since otherwise active registry entries will not be destroyed */
ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do {
- ASTOBJ_RDLOCK(iterator);
+ ASTOBJ_RDLOCK(iterator); /* was RDLOCK */
if (iterator->call) {
ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
/* This will also remove references to the registry */
iterator->call = sip_destroy(iterator->call);
}
- ASTOBJ_UNLOCK(iterator);
+ ao2_unlock(iterator);
} while(0));
/* Then, actually destroy users and registry */
- ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user);
+ ao2_ref(userl->users, -1);
ast_debug(4, "--------------- Done destroying user list\n");
- ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
+ ao2_ref(regl->registry, -1);
ast_debug(4, "--------------- Done destroying registry list\n");
ASTOBJ_CONTAINER_MARKALL(&peerl);
}
@@ -18284,7 +18363,7 @@
peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
if (peer) {
ast_device_state_changed("SIP/%s", peer->name);
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
+ ao2_link(peerl->peers, peer);
unref_peer(peer);
peer_count++;
}
@@ -18344,7 +18423,7 @@
if (is_user) {
user = build_user(cat, ast_variable_browse(cfg, cat), 0);
if (user) {
- ASTOBJ_CONTAINER_LINK(&userl,user);
+ ao2_link(userl->users, user);
unref_user(user);
user_count++;
}
@@ -18352,7 +18431,7 @@
if (is_peer) {
peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
if (peer) {
- ASTOBJ_CONTAINER_LINK(&peerl,peer);
+ ao2_link(peerl->peers, peer);
unref_peer(peer);
peer_count++;
}
@@ -18911,11 +18990,11 @@
return;
ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
- ASTOBJ_WRLOCK(iterator);
+ ASTOBJ_WRLOCK(iterator); /* was WRLOCK */
ms += 100;
iterator->pokeexpire = ast_sched_replace(iterator->pokeexpire,
sched, ms, sip_poke_peer_s, iterator);
- ASTOBJ_UNLOCK(iterator);
+ ao2_unlock(iterator);
} while (0)
);
}
@@ -18932,11 +19011,11 @@
regspacing = 100;
ms = regspacing;
ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do {
- ASTOBJ_WRLOCK(iterator);
+ ASTOBJ_WRLOCK(iterator); /* was WRLOCK */
ms += regspacing;
iterator->expire = ast_sched_replace(iterator->expire,
sched, ms, sip_reregister, iterator);
- ASTOBJ_UNLOCK(iterator);
+ ao2_unlock(iterator);
} while (0)
);
}
@@ -19024,9 +19103,11 @@
static int load_module(void)
{
ast_verbose("SIP channel loading...\n");
- ASTOBJ_CONTAINER_INIT(&userl); /* User object list */
- ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */
- ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */
+ /* the fact that ao2_containers can't resize automatically is a major worry! */
+ /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
+ userl->users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
+ userl->peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
+ regl->registry = ao2_container_alloc(MAX_REG_BUCKETS, reg_hash_cb, reg_cmp_cb); /* if we never search for a particular element in the registry, why on earth are they being tracked? */
if (!(sched = sched_context_create())) {
ast_log(LOG_ERROR, "Unable to create scheduler context\n");
More information about the asterisk-commits
mailing list