[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(&regl, 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), &regl);
 	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(&regexbuf, 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(&regexbuf, iterator->name, 0, NULL, 0)) {
+				if (name && regexec(&regexbuf, 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(&regl, 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(&regl, 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(&regl); /* 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