[asterisk-commits] murf: branch murf/bug11210 r89538 - /team/murf/bug11210/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Nov 23 18:04:55 CST 2007
Author: murf
Date: Fri Nov 23 18:04:55 2007
New Revision: 89538
URL: http://svn.digium.com/view/asterisk?view=rev&rev=89538
Log:
This brings the regl stuff back to ASTOBJ, one of my objectives. It's best it stays in the ASTOBJ world. There are no lookups done on by any key.
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=89538&r1=89537&r2=89538
==============================================================================
--- team/murf/bug11210/channels/chan_sip.c (original)
+++ team/murf/bug11210/channels/chan_sip.c Fri Nov 23 18:04:55 2007
@@ -130,6 +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"
@@ -1333,6 +1334,7 @@
* 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 */
@@ -1375,18 +1377,14 @@
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS
/*! \brief The user list: Users and friends */
-static struct ast_user_list {
- struct ao2_container *users;
-} userl;
+struct ao2_container *users;
/*! \brief The peer list: Peers and Friends */
-static struct ast_peer_list {
- struct ao2_container *peers;
-} peerl;
+struct ao2_container *peers;
/*! \brief The register list: Other SIP proxies we register with and place calls to */
static struct ast_register_list {
- struct ao2_container *registry;
+ ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
int recheck;
} regl;
@@ -1404,6 +1402,26 @@
* \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 peer passed here guaranteed to be set is the name field
+ */
+static int peer_iphash_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_ipcmp_cb(void *obj, void *arg, int flags)
{
struct sip_peer *peer = obj, *peer2 = arg;
@@ -1948,28 +1966,26 @@
*/
static void unref_peer(struct sip_peer *peer)
{
- ao2_unref(peer);
+ ao2_ref(peer,-1);
}
static void unref_user(struct sip_user *user)
{
- ao2_unref(user);
+ ao2_ref(user,-1);
}
static void *registry_unref(struct sip_registry *reg)
{
- /* 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);
+ ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1);
+ ASTOBJ_UNREF(reg, sip_registry_destroy);
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); */
- ao2_ref(reg,1);
- return reg; /* Add pointer to registry in packet */
+ 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 */
}
/*! \brief Interface structure with callbacks used to connect to UDPTL module*/
@@ -3229,7 +3245,7 @@
peer->expire = ast_sched_replace(peer->expire, sched,
global_rtautoclear * 1000, expire_register, (void *) peer);
}
- ao2_link(peerl->peers, peer);
+ ao2_link(peers, peer);
} else {
peer->is_realtime = 1;
}
@@ -3264,7 +3280,7 @@
ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
if (peer)
- p = ao2_find(peerl->peers, &tmp_peer, OBJ_POINTER);
+ p = ao2_find(peers, &tmp_peer, OBJ_POINTER);
else /* search by addr? */
p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
@@ -3322,7 +3338,7 @@
if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
suserobjs++;
- ao2_link(userl->users, user);
+ ao2_link(users, user);
} else {
/* Move counter from s to r... */
suserobjs--;
@@ -3343,7 +3359,7 @@
struct sip_user *u;
ast_copy_string(tmp.name, name, sizeof(tmp.name));
- u = ao2_find(userl->users, &tmp_user, OBJ_POINTER);
+ u = ao2_find(users, &tmp_user, OBJ_POINTER);
if (!u && realtime)
u = realtime_user(name);
@@ -5397,7 +5413,7 @@
reg->portno = portnum;
reg->callid_valid = FALSE;
reg->ocseq = INITIAL_CSEQ;
- ao2_link(regl->registry, reg);/* Add the new registry entry to the list */
+ ASTOBJ_CONTAINER_LINK(®l, reg);/* Add the new registry entry to the list */
registry_unref(reg); /* release the reference. The container has another reference */
return 0;
}
@@ -8700,7 +8716,7 @@
if (peer->selfdestruct ||
ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
- peer = ao2_find(peerl->peers, peer, OBJ_POINTER|OBJ_UNLINK); /* Remove from peer list */
+ peer = ao2_find(peers, peer, OBJ_POINTER|OBJ_UNLINK); /* Remove from peer list */
unref_peer(peer); /* Remove from memory */
}
@@ -9455,7 +9471,7 @@
/* Create peer if we have autocreate mode enabled */
peer = temp_peer(name);
if (peer) {
- ao2_link(peerl->peers, peer);
+ ao2_link(peers, peer);
sip_cancel_destroy(p);
switch (parse_register_contact(p, peer, req)) {
case PARSE_REGISTER_FAILED:
@@ -10673,9 +10689,9 @@
ast_cli(a->fd, FORMAT, "* User name", "In use", "Limit");
- i = ao2_iterator_init(userl->users, 0);
+ i = ao2_iterator_init(users, 0);
- while ((user = ao2_iterator_init(&i))) {
+ while ((user = ao2_iterator_next(&i))) {
if (user->call_limit)
snprintf(ilimits, sizeof(ilimits), "%d", user->call_limit);
else
@@ -10687,7 +10703,7 @@
ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
- i = ao2_iterator_init(peerl->peers, 0);
+ i = ao2_iterator_init(peers, 0);
while ((peer = ao2_iterator_next(&i))) {
if (peer->call_limit)
@@ -10802,7 +10818,7 @@
ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
- i = ao2_iterator_init(userl->users, 0);
+ i = ao2_iterator_init(users, 0);
while ((user = ao2_iterator_next(&i))) {
@@ -10923,7 +10939,7 @@
if (!s) /* Normal list */
ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
- i = ao2_iterator_init(peerl->peers, 0);
+ i = ao2_iterator_init(peers, 0);
while ((peer = ao2_iterator_next(&i))) {
char status[20] = "";
char srch[2000];
@@ -11016,6 +11032,33 @@
#undef FORMAT2
}
+static int user_dump_func(void *userobj, void *arg, int flags)
+{
+ struct sip_user *user = userobj;
+ int refc = ao2_ref(userobj,0);
+ int *fd = arg;
+ char s[1000];
+
+ snprintf(s,sizeof(s), "name: %s\nobjflags: %d\nrefcount: %d\n\n",
+ user->name, 0, refc);
+ ast_cli(*fd, s);
+ return 0;
+}
+
+static int peer_dump_func(void *userobj, void *arg, int flags)
+{
+ struct sip_peer *peer = userobj;
+ int refc = ao2_ref(userobj,0);
+ int *fd = arg;
+ char s[1000];
+
+ snprintf(s,sizeof(s), "name: %s\nobjflags: %d\nrefcount: %d\n\n",
+ peer->name, 0, refc);
+ ast_cli(*fd, s);
+ return 0;
+}
+
+
/*! \brief List all allocated SIP Objects (realtime or static) */
static char *sip_show_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
@@ -11035,9 +11078,9 @@
if (a->argc != 3)
return CLI_SHOWUSAGE;
ast_cli(a->fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs);
- ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &userl);
+ ao2_callback(users, 0, user_dump_func, &fd);
ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
- ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &peerl);
+ ao2_callback(users, 0, peer_dump_func, &fd);
ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs);
ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l);
return CLI_SUCCESS;
@@ -11198,8 +11241,8 @@
if (prunepeer) {
int pruned = 0;
- ao2_lock(peerl->peers); /* was WRLOCK */
- i = ao2_iterator_init(peerl->peers, 0);
+ ao2_lock(peers); /* was WRLOCK */
+ i = ao2_iterator_init(peers, 0);
while ((pi = ao2_iterator_next(&i))) {
if (name && regexec(®exbuf, pi->name, 0, NULL, 0)) {
continue;
@@ -11214,18 +11257,18 @@
ast_cli(a->fd, "%d peers pruned.\n", pruned);
} else
ast_cli(a->fd, "No peers found to prune.\n");
- ASTOBJ_CONTAINER_UNLOCK(&peerl);
+ ao2_unlock(peers);
}
if (pruneuser) {
int pruned = 0;
- ao2_lock(userl->users); /* was WRLOCK */
- i = ao2_iterator_init(userl->users, 0);
+ ao2_lock(users); /* was WRLOCK */
+ i = ao2_iterator_init(users, 0);
while ((ui = ao2_iterator_next(&i))) {
- if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) {
+ if (name && regexec(®exbuf, ui->name, 0, NULL, 0)) {
continue;
};
- if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
+ if (ast_test_flag(&ui->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
ASTOBJ_MARK(iterator);
pruned++;
}
@@ -11235,16 +11278,16 @@
ast_cli(a->fd, "%d users pruned.\n", pruned);
} else
ast_cli(a->fd, "No users found to prune.\n");
- ASTOBJ_CONTAINER_UNLOCK(&userl);
+ ao2_unlock(users);
}
} else {
if (prunepeer) {
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 ((peer = ao2_find(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);
- ao2_link(peerl->peers, peer);
+ ao2_link(peers, peer);
} else
ast_cli(a->fd, "Peer '%s' pruned.\n", name);
unref_peer(peer);
@@ -11254,10 +11297,10 @@
if (pruneuser) {
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 ((user = ao2_find(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);
- ao2_link(userl->users, user);
+ ao2_link(users, user);
} else
ast_cli(a->fd, "User '%s' pruned.\n", name);
unref_user(user);
@@ -11707,6 +11750,7 @@
if (a->argc != 3)
return CLI_SHOWUSAGE;
ast_cli(a->fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time");
+
ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do {
ASTOBJ_RDLOCK(iterator); /* was RDLOCK */
snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
@@ -11716,7 +11760,7 @@
} else
tmpdat[0] = '\0';
ast_cli(a->fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
- ao2_unlock(iterator);
+ ASTOBJ_UNLOCK(iterator);
counter++;
} while(0));
ast_cli(a->fd, "%d SIP registrations.\n", counter);
@@ -12091,20 +12135,29 @@
return c;
}
+static int peer_complete_func(void *obj, void *arg, int flags)
+{
+}
+
+
/*! \brief Do completion on peer name */
static char *complete_sip_peer(const char *word, int state, int flags2)
{
char *result = NULL;
int wordlen = strlen(word);
int which = 0;
-
- ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do {
+ struct ao2_iterator i = ao2_iterator_init(peers,0);
+ struct sip_peer *peer;
+
+ while ((peer = ao2_iterator_next(&i))) {
/* locking of the object is not required because only the name and flags are being compared */
- if (!strncasecmp(word, iterator->name, wordlen) &&
- (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) &&
+ if (!strncasecmp(word, peer->name, wordlen) &&
+ (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
++which > state)
result = ast_strdup(iterator->name);
- } while(0) );
+ if (result)
+ break;
+ }
return result;
}
@@ -18053,14 +18106,14 @@
/* This will also remove references to the registry */
iterator->call = sip_destroy(iterator->call);
}
- ao2_unlock(iterator);
+ ASTOBJ_UNLOCK(iterator);
} while(0));
/* Then, actually destroy users and registry */
- ao2_ref(userl->users, -1);
+ ao2_ref(users, -1);
ast_debug(4, "--------------- Done destroying user list\n");
- ao2_ref(regl->registry, -1);
+ ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy);
ast_debug(4, "--------------- Done destroying registry list\n");
ASTOBJ_CONTAINER_MARKALL(&peerl);
}
@@ -18461,7 +18514,7 @@
peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
if (peer) {
ast_device_state_changed("SIP/%s", peer->name);
- ao2_link(peerl->peers, peer);
+ ao2_link(peers, peer);
unref_peer(peer);
peer_count++;
}
@@ -18521,7 +18574,7 @@
if (is_user) {
user = build_user(cat, ast_variable_browse(cfg, cat), 0);
if (user) {
- ao2_link(userl->users, user);
+ ao2_link(users, user);
unref_user(user);
user_count++;
}
@@ -18529,7 +18582,7 @@
if (is_peer) {
peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
if (peer) {
- ao2_link(peerl->peers, peer);
+ ao2_link(peers, peer);
unref_peer(peer);
peer_count++;
}
@@ -19117,7 +19170,7 @@
ms += regspacing;
iterator->expire = ast_sched_replace(iterator->expire,
sched, ms, sip_reregister, iterator);
- ao2_unlock(iterator);
+ ASTOBJ_UNLOCK(iterator);
} while (0)
);
}
@@ -19207,9 +19260,9 @@
ast_verbose("SIP channel loading...\n");
/* 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? */
+ users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
+ peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
+ ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */
if (!(sched = sched_context_create())) {
ast_log(LOG_ERROR, "Unable to create scheduler context\n");
More information about the asterisk-commits
mailing list