[svn-commits] snuffy: branch snuffy/ao2_jabber_take2 r161217 - in /team/snuffy/ao2_jabber_t...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Dec 5 04:29:46 CST 2008


Author: snuffy
Date: Fri Dec  5 04:29:45 2008
New Revision: 161217

URL: http://svn.digium.com/view/asterisk?view=rev&rev=161217
Log:
put back ao2 jabber changes

Modified:
    team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c
    team/snuffy/ao2_jabber_take2/channels/chan_jingle.c
    team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h
    team/snuffy/ao2_jabber_take2/res/res_jabber.c

Modified: team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c (original)
+++ team/snuffy/ao2_jabber_take2/channels/chan_gtalk.c Fri Dec  5 04:29:45 2008
@@ -65,6 +65,7 @@
 #include "asterisk/astobj.h"
 #include "asterisk/abstract_jb.h"
 #include "asterisk/jabber.h"
+#include "asterisk/astobj2.h"
 
 #define GOOGLE_CONFIG "gtalk.conf"
 
@@ -234,6 +235,9 @@
 
 static void gtalk_member_destroy(struct gtalk *obj)
 {
+	//ao2_t_ref(obj->connection->buddies, -1, "die ref");
+	ao2_t_ref(obj->connection, -1, "die client ref");
+	ao2_t_ref(obj->buddy, -1, "die buddy ref");
 	ast_free(obj);
 }
 
@@ -880,14 +884,15 @@
 {
 	struct gtalk_pvt *tmp = NULL;
 	struct aji_resource *resources = NULL;
-	struct aji_buddy *buddy;
+	struct aji_buddy *buddy, tmp_buddy;
 	char idroster[200];
 	char *data, *exten = NULL;
 
 	ast_debug(1, "The client is %s for alloc\n", client->name);
 	if (!sid && !strchr(them, '/')) {	/* I started call! */
 		if (!strcasecmp(client->name, "guest")) {
-			buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, them);
+			ast_copy_string(tmp_buddy.name, them, sizeof(tmp_buddy.name));
+			buddy = ao2_t_find(client->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find buddy");
 			if (buddy)
 				resources = buddy->resources;
 		} else if (client->buddy)
@@ -1844,9 +1849,12 @@
 		}
 		var = var->next;
 	}
-	if (member->connection && member->user)
-		member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
-	else {
+	if (member->connection && member->user) {
+		struct aji_buddy tmp_buddy;
+		ast_copy_string(tmp_buddy.name, member->user, sizeof(tmp_buddy.name));
+		member->buddy = ao2_t_find(member->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find buddy");
+		//ao2_t_ref(member->buddy, -1, "create etc");
+	} else {
 		ast_log(LOG_ERROR, "No Connection or Username!\n");
 	}
 	return 1;
@@ -1862,7 +1870,7 @@
 	struct ast_variable *var;
 	struct gtalk *member;
 	struct ast_codec_pref prefs;
-	struct aji_client_container *clients;
+	struct ao2_container *clients;
 	struct gtalk_candidate *global_candidates = NULL;
 	struct hostent *hp;
 	struct ast_hostent ahp;
@@ -1955,15 +1963,20 @@
 				ASTOBJ_UNLOCK(member);
 				clients = ast_aji_get_clients();
 				if (clients) {
-					ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
-						ASTOBJ_WRLOCK(iterator);
+					struct ao2_iterator iter;
+					struct aji_client *c;
+
+					iter = ao2_iterator_init(clients, 0);
+					while ((c =ao2_t_iterator_next(&iter,"iter clients"))) {
+						ao2_lock(c);
 						ASTOBJ_WRLOCK(member);
 						member->connection = NULL;
-						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
-						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
+						iks_filter_add_rule(c->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
+						iks_filter_add_rule(c->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
 						ASTOBJ_UNLOCK(member);
-						ASTOBJ_UNLOCK(iterator);
-					});
+						ao2_unlock(c);
+						ao2_ref(c, -1);
+					}
 					ASTOBJ_CONTAINER_LINK(&gtalk_list, member);
 					ASTOBJ_UNREF(member, gtalk_member_destroy);
 				} else {

Modified: team/snuffy/ao2_jabber_take2/channels/chan_jingle.c
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/channels/chan_jingle.c?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/channels/chan_jingle.c (original)
+++ team/snuffy/ao2_jabber_take2/channels/chan_jingle.c Fri Dec  5 04:29:45 2008
@@ -68,6 +68,7 @@
 #include "asterisk/abstract_jb.h"
 #include "asterisk/jabber.h"
 #include "asterisk/jingle.h"
+#include "asterisk/astobj2.h"
 
 #define JINGLE_CONFIG "jingle.conf"
 
@@ -741,13 +742,14 @@
 {
 	struct jingle_pvt *tmp = NULL;
 	struct aji_resource *resources = NULL;
-	struct aji_buddy *buddy;
+	struct aji_buddy *buddy,tmp_buddy;
 	char idroster[200];
 
 	ast_debug(1, "The client is %s for alloc\n", client->name);
 	if (!sid && !strchr(from, '/')) {	/* I started call! */
 		if (!strcasecmp(client->name, "guest")) {
-			buddy = ASTOBJ_CONTAINER_FIND(&client->connection->buddies, from);
+			ast_copy_string(tmp_buddy.name, from, sizeof(tmp_buddy.name));
+			buddy = ao2_t_find(client->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find client");
 			if (buddy)
 				resources = buddy->resources;
 		} else if (client->buddy)
@@ -1712,9 +1714,11 @@
 		}
 		var = var->next;
 	}
-	if (member->connection && member->user)
-		member->buddy = ASTOBJ_CONTAINER_FIND(&member->connection->buddies, member->user);
-	else {
+	if (member->connection && member->user) {
+		struct aji_buddy tmp_buddy;
+		ast_copy_string(tmp_buddy.name, member->user, sizeof(tmp_buddy.name));
+		member->buddy = ao2_t_find(member->connection->buddies, &tmp_buddy, NULL, OBJ_POINTER, "find buddy");
+	} else {
 		ast_log(LOG_ERROR, "No Connection or Username!\n");
 	}
 	return 1;
@@ -1731,7 +1735,7 @@
 	struct hostent *hp;
 	struct ast_hostent ahp;
 	struct ast_codec_pref prefs;
-	struct aji_client_container *clients;
+	struct ao2_container *clients;
 	struct jingle_candidate *global_candidates = NULL;
 	struct ast_flags config_flags = { 0 };
 
@@ -1739,7 +1743,7 @@
 	if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
 		return 0;
 	}
-
+ 	
 	/* Copy the default jb config over global_jbconf */
 	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
 
@@ -1818,15 +1822,20 @@
 				ASTOBJ_UNLOCK(member);
 				clients = ast_aji_get_clients();
 				if (clients) {
-					ASTOBJ_CONTAINER_TRAVERSE(clients, 1, {
-						ASTOBJ_WRLOCK(iterator);
+					struct ao2_iterator iter;
+					struct aji_client *c;
+					
+					iter = ao2_iterator_init(clients, 0);
+					while ((c = ao2_t_iterator_next(&iter,"client iter"))) {
+						ao2_lock(c);
 						ASTOBJ_WRLOCK(member);
 						member->connection = NULL;
-						iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS,	JINGLE_NS, IKS_RULE_DONE);
-						iks_filter_add_rule(iterator->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS,	JINGLE_DTMF_NS, IKS_RULE_DONE);
+						iks_filter_add_rule(c->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS,	JINGLE_NS, IKS_RULE_DONE);
+						iks_filter_add_rule(c->f, jingle_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS,	JINGLE_DTMF_NS, IKS_RULE_DONE);
 						ASTOBJ_UNLOCK(member);
-						ASTOBJ_UNLOCK(iterator);
-					});
+						ao2_unlock(c);
+						ao2_ref(c, -1);
+					}
 					ASTOBJ_CONTAINER_LINK(&jingle_list, member);
 				} else {
 					ASTOBJ_UNLOCK(member);

Modified: team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h (original)
+++ team/snuffy/ao2_jabber_take2/include/asterisk/jabber.h Fri Dec  5 04:29:45 2008
@@ -57,9 +57,10 @@
 #define IKS_NET_EXPIRED 12
 
 #include <iksemel.h>
+#define REF_DEBUG 1
 #include "asterisk/astobj.h"
+#include "asterisk/astobj2.h"
 #include "asterisk/linkedlists.h"
-
 /* 
  * As per RFC 3920 - section 3.1, the maximum length for a full Jabber ID 
  * is 3071 bytes.
@@ -122,23 +123,18 @@
 };
 
 struct aji_buddy {
-	ASTOBJ_COMPONENTS_FULL(struct aji_buddy, AJI_MAX_JIDLEN, 1);
+	char name[AJI_MAX_JIDLEN];
 	char channel[160];
 	struct aji_resource *resources;
 	enum aji_btype btype;
 	struct ast_flags flags;
+	char needdestroy;
+	int mark;
 };
 
-struct aji_buddy_container {
-	ASTOBJ_CONTAINER_COMPONENTS(struct aji_buddy);
-};
-
-struct aji_transport_container {
-	ASTOBJ_CONTAINER_COMPONENTS(struct aji_transport);
-};
 
 struct aji_client {
-	ASTOBJ_COMPONENTS(struct aji_client);
+	char name[80];
 	char password[160];
 	char user[AJI_MAX_JIDLEN];
 	char serverhost[AJI_MAX_RESJIDLEN];
@@ -169,16 +165,13 @@
 	int authorized;
 	struct ast_flags flags;
 	int component; /* 0 client,  1 component */
-	struct aji_buddy_container buddies;
+	struct ao2_container *buddies;
 	AST_LIST_HEAD(messages,aji_message) messages;
 	void *jingle;
 	pthread_t thread;
 	int priority;
 	enum ikshowtype status;
-};
-
-struct aji_client_container{
-	ASTOBJ_CONTAINER_COMPONENTS(struct aji_client);
+	int mark;
 };
 
 /* !Send XML stanza over the established XMPP connection */
@@ -196,6 +189,6 @@
 /*! Join existing Chat session */
 int ast_aji_join_chat(struct aji_client *client,char *room);
 struct aji_client *ast_aji_get_client(const char *name);
-struct aji_client_container *ast_aji_get_clients(void);
+struct ao2_container *ast_aji_get_clients(void);
 
 #endif

Modified: team/snuffy/ao2_jabber_take2/res/res_jabber.c
URL: http://svn.digium.com/view/asterisk/team/snuffy/ao2_jabber_take2/res/res_jabber.c?view=diff&rev=161217&r1=161216&r2=161217
==============================================================================
--- team/snuffy/ao2_jabber_take2/res/res_jabber.c (original)
+++ team/snuffy/ao2_jabber_take2/res/res_jabber.c Fri Dec  5 04:29:45 2008
@@ -55,7 +55,8 @@
 #include "asterisk/acl.h"
 #include "asterisk/utils.h"
 #include "asterisk/module.h"
-#include "asterisk/astobj.h"
+/*#include "asterisk/astobj.h"*/
+#include "asterisk/astobj2.h"
 #include "asterisk/astdb.h"
 #include "asterisk/manager.h"
 
@@ -71,9 +72,16 @@
 #define TRUE 1
 #endif
 
+#ifdef LOW_MEMORY
+static int hash_buddy_size = 20;
+static int hash_client_size = 20;
+#else
+static int hash_buddy_size = 256;
+static int hash_client_size = 256;
+#endif
 /*-- Forward declarations */
-static void aji_buddy_destroy(struct aji_buddy *obj);
-static void aji_client_destroy(struct aji_client *obj);
+static void aji_buddy_destroy(void *obj);
+static void aji_client_destroy(void *obj);
 static int aji_send_exec(struct ast_channel *chan, void *data);
 static int aji_status_exec(struct ast_channel *chan, void *data);
 static int aji_is_secure(struct aji_client *client);
@@ -132,12 +140,12 @@
 
 static char *app_ajisend = "JabberSend";
 
-static char *ajisend_synopsis = "JabberSend(Jabber,JID,Message)";
+static char *ajisend_synopsis = "JabberSend(Jabber,JID,message)";
 
 static char *ajisend_descrip =
-"JabberSend(Jabber,JID,Message)\n"
+"JabberSend(Jabber,ScreenName,Message)\n"
 "  Jabber   - Client or transport Asterisk uses to connect to Jabber\n" 
-"  JID      - XMPP/Jabber JID (Name) of recipient\n" 
+"  JID      - User Name to message.\n" 
 "  Message  - Message to be sent to the buddy\n";
 
 static char *app_ajistatus = "JabberStatus";
@@ -145,42 +153,168 @@
 static char *ajistatus_synopsis = "JabberStatus(Jabber,JID,Variable)";
 
 static char *ajistatus_descrip =
-"JabberStatus(Jabber,JID,Variable)\n"
-"  Jabber   - Client or transport Asterisk uses to connect to Jabber\n"
-"  JID      - User Name to retrieve status from.\n"
-"  Variable - Variable to store presence in will be 1-6.\n" 
+"JabberStatus(Jabber,ScreenName,Variable)\n"
+"  Jabber     - Client or transport Asterisk uses to connect to Jabber\n"
+"  JID        - User Name to retrieve status from.\n"
+"  Variable   - Variable to store presence in will be 1-6.\n" 
 "             In order, 1=Online, 2=Chatty, 3=Away, 4=XAway, 5=DND, 6=Offline\n" 
 "             If not in roster variable will be set to 7\n\n"
 "Note: This application is deprecated. Please use the JABBER_STATUS() function instead.\n";
 
-struct aji_client_container clients;
+struct ao2_container *clients;
 struct aji_capabilities *capabilities = NULL;
 
 /*! \brief Global flags, initialized to default values */
 static struct ast_flags globalflags = { AJI_AUTOREGISTER };
+
+#ifdef REF_DEBUG
+#define client_ref(arg1,arg2) client_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define client_unref(arg1,arg2) client_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define buddy_ref(arg1,arg2) buddy_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define buddy_unref(arg1,arg2) buddy_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static struct aji_buddy *buddy_ref_debug(struct aji_buddy *b, char *tag, char *file, int line, const char *func)
+{
+	if (b) {
+		_ao2_ref_debug(b, 1, tag, file, line,func);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+	}
+
+	return b;
+}
+
+static void buddy_unref_debug(struct aji_buddy *b, char *tag, char *file, int line, const char *func)
+{
+	if (b) {
+		_ao2_ref_debug(b, -1, tag, file, line, func);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+	}
+}
+
+static struct aji_client *client_ref_debug(struct aji_client *c, char *tag, char *file, int line, const char *func)
+{
+	if (c) {
+		_ao2_ref_debug(c, 1, tag, file, line, func);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+	}
+
+	return c;
+}
+
+static void client_unref_debug(struct aji_client *c, char *tag, char *file, int line, const char *func)
+{
+	if (c) {
+		_ao2_ref_debug(c, -1, tag, file, line, func);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+	}
+}
+#else
+static struct aji_buddy *buddy_ref(struct aji_buddy *b, char *tag)
+{
+	if (b) {
+		ao2_ref(b, 1);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+	}
+
+	return b;
+}
+
+static void buddy_unref(struct aji_buddy *b, char *tag)
+{
+	if (b) {
+		ao2_ref(b, -1);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+	}
+}
+
+static struct aji_client *client_ref(struct aji_client *c, char *tag)
+{
+	if (c) {
+		ao2_ref(c, 1);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to ref a NULL pointer\n");
+	}
+
+	return c;
+}
+
+static void client_unref(struct aji_client *c, char *tag)
+{
+	if (c) {
+		ao2_ref(c, -1);
+	} else {
+		ast_log(LOG_ERROR, "Attempt to unref a NULL pointer\n");
+	}
+}
+#endif
+
+static int client_cmp_cb(void *obj, void *arg, void *data, int flags)
+{
+	struct aji_client *client = obj, *client2 = arg;
+
+	return !strcasecmp(client->name, client2->name) ? CMP_MATCH : 0;
+}
+
+static int buddy_cmp_cb(void *obj, void *arg, void *data, int flags)
+{
+	struct aji_buddy *buddy = obj, *buddy2 = arg;
+
+	return !strcasecmp(buddy->name, buddy2->name) ? CMP_MATCH : 0;
+}
+
+static int buddy_hash_cb(const void *obj, const int flags)
+{
+	const struct aji_buddy *buddy = obj;
+	
+	return ast_str_hash(buddy->name);
+}
+
+static int client_hash_cb(const void *obj, const int flags)
+{
+	const struct aji_client *client = obj;
+	
+	return ast_str_hash(client->name);
+}
 
 /*!
  * \brief Deletes the aji_client data structure.
  * \param obj aji_client The structure we will delete.
  * \return void.
  */
-static void aji_client_destroy(struct aji_client *obj)
-{
+static void aji_client_destroy(void *obj)
+{
+	struct aji_client *c = obj;
 	struct aji_message *tmp;
-	ASTOBJ_CONTAINER_DESTROYALL(&obj->buddies, aji_buddy_destroy);
-	ASTOBJ_CONTAINER_DESTROY(&obj->buddies);
-	iks_filter_delete(obj->f);
-	iks_parser_delete(obj->p);
-	iks_stack_delete(obj->stack);
-	AST_LIST_LOCK(&obj->messages);
-	while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) {
+	struct aji_buddy *b;
+	struct ao2_iterator biter;
+	
+	biter = ao2_iterator_init(c->buddies, 0);
+
+	while( (b = ao2_t_iterator_next(&biter, "iterate thru buddies")) ) {
+		ao2_t_unlink(c->buddies, b, "Remove buddy from list");
+		buddy_unref(b, "unref buddy");
+	}
+	
+	iks_filter_delete(c->f);
+	iks_parser_delete(c->p);
+	iks_stack_delete(c->stack);
+	AST_LIST_LOCK(&c->messages);
+	while ((tmp = AST_LIST_REMOVE_HEAD(&c->messages, list))) {
 		if (tmp->from)
 			ast_free(tmp->from);
 		if (tmp->message)
 			ast_free(tmp->message);
 	}
-	AST_LIST_HEAD_DESTROY(&obj->messages);
-	ast_free(obj);
+	AST_LIST_HEAD_DESTROY(&c->messages);
+
+	ao2_lock(clients); /* required locking for removal? */
+	ao2_t_unlink(clients,obj,"Remove client from list");
+	ao2_unlock(clients);
 }
 
 /*!
@@ -188,17 +322,18 @@
  * \param obj aji_buddy The structure we will delete.
  * \return void.
  */
-static void aji_buddy_destroy(struct aji_buddy *obj)
-{
+static void aji_buddy_destroy(void *obj)
+{
+	struct aji_buddy *b = obj;
 	struct aji_resource *tmp;
 
-	while ((tmp = obj->resources)) {
-		obj->resources = obj->resources->next;
+	while ((tmp = b->resources)) {
+		b->resources = b->resources->next;
 		ast_free(tmp->description);
 		ast_free(tmp);
 	}
 
-	ast_free(obj);
+	ast_free(b);
 }
 
 /*!
@@ -343,6 +478,7 @@
 {
 	struct aji_client *client = NULL;
 	struct aji_buddy *buddy = NULL;
+	struct aji_buddy tmp_buddy;
 	struct aji_resource *r = NULL;
 	char *s = NULL;
 	int stat = 7;
@@ -362,7 +498,7 @@
 		ast_log(LOG_WARNING, "JabberStatus is deprecated.  Please use the JABBER_STATUS dialplan function in the future.\n");
 
 	if (!data) {
-		ast_log(LOG_ERROR, "Usage: JabberStatus(<sender>,<jid>[/<resource>],<varname>\n");
+		ast_log(LOG_ERROR, "Usage: JabberStatus(<sender>,<screenname>[/<resource>],<varname>\n");
 		return 0;
 	}
 	s = ast_strdupa(data);
@@ -375,22 +511,33 @@
 
 	AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
 
+/* I NEED A FUNCTION */
 	if (!(client = ast_aji_get_client(args.sender))) {
 		ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
 		return -1;
 	}
-	buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
+
+	ast_copy_string(tmp_buddy.name, jid.screenname, sizeof(tmp_buddy.name));
+	buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
+	
 	if (!buddy) {
 		ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
+		client_unref(client, "unref client");
 		return -1;
 	}
+
 	r = aji_find_resource(buddy, jid.resource);
+
 	if (!r && buddy->resources) 
 		r = buddy->resources;
 	if (!r)
 		ast_log(LOG_NOTICE, "Resource '%s' of buddy '%s' was not found\n", jid.resource, jid.screenname);
 	else
 		stat = r->status;
+
+	buddy_unref(buddy,"stat_exec");
+	client_unref(client, "unref client");
+/* END I NEED A FUNCTION */
 	snprintf(status, sizeof(status), "%d", stat);
 	pbx_builtin_setvar_helper(chan, args.variable, status);
 	return 0;
@@ -400,6 +547,7 @@
 {
 	struct aji_client *client = NULL;
 	struct aji_buddy *buddy = NULL;
+	struct aji_buddy tmp_buddy;
 	struct aji_resource *r = NULL;
 	int stat = 7;
 	AST_DECLARE_APP_ARGS(args,
@@ -412,25 +560,28 @@
 	);
 
 	if (!data) {
-		ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<jid>[/<resource>])\n");
+		ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<screenname>[/<resource>])\n");
 		return 0;
 	}
 	AST_STANDARD_APP_ARGS(args, data);
 
 	if (args.argc != 2) {
-		ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments: sender and jid.\n");
+		ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments.\n");
 		return -1;
 	}
 
 	AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
 
+/* I NEED A FUNCTION */
 	if (!(client = ast_aji_get_client(args.sender))) {
 		ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
 		return -1;
 	}
-	buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
+	ast_copy_string(tmp_buddy.name, jid.screenname, sizeof(tmp_buddy.name));
+	buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
 	if (!buddy) {
 		ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
+		client_unref(client, "unref client");
 		return -1;
 	}
 	r = aji_find_resource(buddy, jid.resource);
@@ -440,6 +591,9 @@
 		ast_log(LOG_NOTICE, "Resource %s of buddy %s was not found.\n", jid.resource, jid.screenname);
 	else
 		stat = r->status;
+	buddy_unref(buddy,"stat_read");
+	client_unref(client, "unref client");
+/* END I NEED A FUNCTION */
 	snprintf(buf, buflen, "%d", stat);
 	return 0;
 }
@@ -491,6 +645,8 @@
 	}
 	if (strchr(args.recipient, '@') && !ast_strlen_zero(args.message))
 		ast_aji_send_chat(client, args.recipient, args.message);
+	
+	client_unref(client, "unref client");
 	return 0;
 }
 
@@ -774,7 +930,8 @@
  */
 static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
+	client_ref(client,"log_hook");
 
 	if (!ast_strlen_zero(xmpp))
 		manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp);
@@ -784,15 +941,14 @@
 			ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp);
 		else {
 			if( strlen(xmpp) == 1) {
-				if(option_debug > 2  && xmpp[0] == ' ') {
-					ast_verbose("\nJABBER: Keep alive packet\n");
-				}
+				if(option_debug > 2  && xmpp[0] == ' ')
+				ast_verbose("\nJABBER: Keep alive packet\n");
 			} else
 				ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp);
 		}
 
 	}
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	client_unref(client,"log_hook");
 }
 
 /*!
@@ -855,19 +1011,21 @@
  */
 static int aji_act_hook(void *data, int type, iks *node)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
 	ikspak *pak = NULL;
 	iks *auth = NULL;
 	int features = 0;
 
+	client_ref(client,"act_hook");
+
 	if(!node) {
 		ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */
-		ASTOBJ_UNREF(client, aji_client_destroy);
+		client_unref(client, "act_hook_packet");
 		return IKS_HOOK;
 	}
 
 	if (client->state == AJI_DISCONNECTING) {
-		ASTOBJ_UNREF(client, aji_client_destroy);
+		client_unref(client, "act_hook_disc");
 		return IKS_HOOK;
 	}
 
@@ -879,12 +1037,12 @@
 			if (client->usetls && !aji_is_secure(client)) {
 #ifndef HAVE_OPENSSL
 				ast_log(LOG_ERROR, "OpenSSL not installed. You need to install OpenSSL on this system, or disable the TLS option in your configuration file\n");
-				ASTOBJ_UNREF(client, aji_client_destroy);
+				client_unref(client,"act_hook_no_openssl_tls");
 				return IKS_HOOK;
 #else
 				if (aji_start_tls(client) == IKS_NET_TLSFAIL) {
 					ast_log(LOG_ERROR, "Could not start TLS\n");
-					ASTOBJ_UNREF(client, aji_client_destroy);
+					client_unref(client,"act_hook_openssl_tls");
 					return IKS_HOOK;		
 				}
 #endif
@@ -908,6 +1066,7 @@
 #ifdef HAVE_OPENSSL
 			if (client->stream_flags & TRY_SECURE) {
 				if (!strcmp("proceed", iks_name(node))) {
+					client_unref(client,"try_sec");
 					return aji_tls_handshake(client);
 				}
 			}
@@ -952,7 +1111,7 @@
 
 						ret = aji_start_sasl(client, features, client->jid->user, client->password);
 						if (ret != IKS_OK) {
-							ASTOBJ_UNREF(client, aji_client_destroy);
+							client_unref(client, "act_hook_not_ok");
 							return IKS_HOOK;
 						}
 						break;
@@ -967,12 +1126,12 @@
 			break;
 		case IKS_NODE_ERROR: 
 				ast_log(LOG_ERROR, "JABBER: Node Error\n");
-				ASTOBJ_UNREF(client, aji_client_destroy);
+				client_unref(client, "act_hook_node_error");
 				return IKS_HOOK;
 				break;
 		case IKS_NODE_STOP: 
 				ast_log(LOG_WARNING, "JABBER: Disconnected\n");
-				ASTOBJ_UNREF(client, aji_client_destroy);
+				client_unref(client, "act_hook_discon_error");
 				return IKS_HOOK;
 				break;
 		}
@@ -985,7 +1144,8 @@
 				sprintf(secret, "%s%s", pak->id, client->password);
 				ast_sha1_hash(shasum, secret);
 				handshake = NULL;
-				if (asprintf(&handshake, "<handshake>%s</handshake>", shasum) >= 0) {
+				asprintf(&handshake, "<handshake>%s</handshake>", shasum);
+				if (handshake) {
 					aji_send_raw(client, handshake);
 					ast_free(handshake);
 					handshake = NULL;
@@ -1004,12 +1164,12 @@
 
 		case IKS_NODE_ERROR:
 			ast_log(LOG_ERROR, "JABBER: Node Error\n");
-			ASTOBJ_UNREF(client, aji_client_destroy);
+			client_unref(client, "act_hook_node_error");
 			return IKS_HOOK;
 
 		case IKS_NODE_STOP:
 			ast_log(LOG_WARNING, "JABBER: Disconnected\n");
-			ASTOBJ_UNREF(client, aji_client_destroy);
+			client_unref(client, "act_hook_discon_error");
 			return IKS_HOOK;
 		}
 	}
@@ -1044,20 +1204,21 @@
 	if (node)
 		iks_delete(node);
 
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	client_unref(client, "end_act_hook");
 	return IKS_OK;
 }
 /*!
- * \brief Unknown
+ * \brief Uknown
  * \param data void
  * \param pak ikspak
  * \return IKS_FILTER_EAT.
 */
 static int aji_register_approve_handler(void *data, ikspak *pak)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
 	iks *iq = NULL, *presence = NULL, *x = NULL;
 
+	client_ref(client,"arpv_hand");
 	iq = iks_new("iq");
 	presence = iks_new("presence");
 	x = iks_new("x");
@@ -1087,29 +1248,29 @@
 	iks_delete(presence);
 	iks_delete(x);
 	
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	client_unref(client, "aprv_hand");
 	return IKS_FILTER_EAT;
 }
 /*!
- * \brief register handler for incoming querys (IQ's)
+ * \brief register query
  * \param data incoming aji_client request
  * \param pak ikspak
  * \return IKS_FILTER_EAT.
 */
 static int aji_register_query_handler(void *data, ikspak *pak)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
 	struct aji_buddy *buddy = NULL; 
+	struct aji_buddy tmp_buddy; 
 	char *node = NULL;
-	iks *iq = NULL, *query = NULL;
-
-	client = (struct aji_client *) data;
-
-	buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
+
+	client_ref(client,"qry_hand");
+	ast_copy_string(tmp_buddy.name, pak->from->partial,sizeof(tmp_buddy.name));
+	buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find Buddy");
 	if (!buddy) {
-		iks  *error = NULL, *notacceptable = NULL;
-
-		ast_log(LOG_ERROR, "Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
+		iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL;
+
+		ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
 		iq = iks_new("iq");
 		query = iks_new("query");
 		error = iks_new("error");
@@ -1131,10 +1292,12 @@
 			ast_log(LOG_ERROR, "Out of memory.\n");
 		}
 
+		iks_delete(iq);
+		iks_delete(query);
 		iks_delete(error);
 		iks_delete(notacceptable);
 	} else 	if (!(node = iks_find_attrib(pak->query, "node"))) {
-		iks *instructions = NULL;
+		iks *iq = NULL, *query = NULL, *instructions = NULL;
 		char *explain = "Welcome to Asterisk - the Open Source PBX.\n";
 		iq = iks_new("iq");
 		query = iks_new("query");
@@ -1153,11 +1316,12 @@
 			ast_log(LOG_ERROR, "Out of memory.\n");
 		}
 
+		iks_delete(iq);
+		iks_delete(query);
 		iks_delete(instructions);
 	}
-	iks_delete(iq);
-	iks_delete(query);
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	buddy_unref(buddy, "qry_hand");
+	client_unref(client, "qry_hand");
 	return IKS_FILTER_EAT;
 }
 
@@ -1169,8 +1333,10 @@
 */
 static int aji_ditems_handler(void *data, ikspak *pak)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
 	char *node = NULL;
+
+	client_ref(client,"itm_hand");
 
 	if (!(node = iks_find_attrib(pak->query, "node"))) {
 		iks *iq = NULL, *query = NULL, *item = NULL;
@@ -1252,7 +1418,7 @@
 		iks_delete(feature);
 	}
 
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	client_unref(client, "itm_hand");
 	return IKS_FILTER_EAT;
 
 }
@@ -1264,15 +1430,20 @@
 */
 static int aji_client_info_handler(void *data, ikspak *pak)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
 	struct aji_resource *resource = NULL;
-	struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
-
+	struct aji_buddy *buddy = NULL;
+	struct aji_buddy tmp_buddy;
+	
+	client_ref(client, "info_hand");
+	ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+	buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
 	resource = aji_find_resource(buddy, pak->from->resource);
+
 	if (pak->subtype == IKS_TYPE_RESULT) {
 		if (!resource) {
-			ast_log(LOG_NOTICE, "JABBER: Received client info from %s when not requested.\n", pak->from->full);
-			ASTOBJ_UNREF(client, aji_client_destroy);
+			ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
+			client_unref(client, "info_hand");
 			return IKS_FILTER_EAT;
 		}
 		if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
@@ -1313,7 +1484,8 @@
 	} else if (pak->subtype == IKS_TYPE_ERROR) {
 		ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
 	}
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	buddy_unref(buddy,"info_hand");
+	client_unref(client, "info_hand");
 	return IKS_FILTER_EAT;
 }
 /*!
@@ -1324,20 +1496,28 @@
 */
 static int aji_dinfo_handler(void *data, ikspak *pak)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
+	struct aji_resource *resource = NULL;
+	struct aji_buddy *buddy = NULL;
+	struct aji_buddy tmp_buddy;
 	char *node = NULL;
-	struct aji_resource *resource = NULL;
-	struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
-
+	
+	client_ref(client, "dinfo_hand");
+	ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+	buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
 	resource = aji_find_resource(buddy, pak->from->resource);
+	
 	if (pak->subtype == IKS_TYPE_ERROR) {
 		ast_log(LOG_WARNING, "Recieved error from a client, turn on jabber debug!\n");
+		buddy_unref(buddy, "dinfo_hand");
+		client_unref(client, "dinfo_hand");
 		return IKS_FILTER_EAT;
 	}
 	if (pak->subtype == IKS_TYPE_RESULT) {
 		if (!resource) {
 			ast_log(LOG_NOTICE,"JABBER: Received client info from %s when not requested.\n", pak->from->full);
-			ASTOBJ_UNREF(client, aji_client_destroy);
+			buddy_unref(buddy, "dinfo_hand");
+			client_unref(client, "dinfo_hand");
 			return IKS_FILTER_EAT;
 		}
 		if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
@@ -1453,7 +1633,8 @@
 		iks_delete(feature);
 	}
 
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	buddy_unref(buddy, "dinfo_hand");
+	client_unref(client, "dinfo_hand");
 	return IKS_FILTER_EAT;
 }
 
@@ -1516,14 +1697,16 @@
 static void aji_handle_presence(struct aji_client *client, ikspak *pak)
 {
 	int status, priority;
-	struct aji_buddy *buddy;
+	struct aji_buddy tmp_buddy, *buddy;
 	struct aji_resource *tmp = NULL, *last = NULL, *found = NULL;
 	char *ver, *node, *descrip, *type;
 	
 	if(client->state != AJI_CONNECTED)
 		aji_create_buddy(pak->from->partial, client);
 
-	buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
+	ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+	buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find Buddy");
+
 	if (!buddy && pak->from->partial) {
 		/* allow our jid to be used to log in with another resource */
 		if (!strcmp((const char *)pak->from->partial, (const char *)client->jid->partial))
@@ -1532,16 +1715,19 @@
 			ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial);
 		return;
 	}
+
 	type = iks_find_attrib(pak->x, "type");
+
 	if(client->component && type &&!strcasecmp("probe", type)) {
 		aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), client->status, client->statusmessage);
 		ast_verbose("what i was looking for \n");
 	}
-	ASTOBJ_WRLOCK(buddy);
+
 	status = (pak->show) ? pak->show : 6;
 	priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0");
 	tmp = buddy->resources;
 	descrip = ast_strdup(iks_find_cdata(pak->x,"status"));
+	ao2_lock(buddy);
 
 	while (tmp && pak->from->resource) {
 		if (!strcasecmp(tmp->resource, pak->from->resource)) {
@@ -1650,8 +1836,8 @@
 			buddy->resources = found;
 	}
 	
-	ASTOBJ_UNLOCK(buddy);
-	ASTOBJ_UNREF(buddy, aji_buddy_destroy);
+	ao2_unlock(buddy);
+	buddy_unref(buddy, "hld_pres");
 
 	node = iks_find_attrib(iks_find(pak->x, "c"), "node");
 	ver = iks_find_attrib(iks_find(pak->x, "c"), "ver");
@@ -1735,6 +1921,7 @@
 {
 	iks *presence = NULL, *status = NULL;
 	struct aji_buddy* buddy = NULL;
+	struct aji_buddy tmp_buddy;
 
 	switch (pak->subtype) { 
 	case IKS_TYPE_SUBSCRIBE:
@@ -1758,14 +1945,15 @@
 		if (client->component)
 			aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), client->status, client->statusmessage);
 	case IKS_TYPE_SUBSCRIBED:
-		buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
+		ast_copy_string(tmp_buddy.name, pak->from->partial, sizeof(tmp_buddy.name));
+		buddy = ao2_t_find(client->buddies, &tmp_buddy, NULL, OBJ_POINTER, "Find buddy");
 		if (!buddy && pak->from->partial) {
 			aji_create_buddy(pak->from->partial, client);
+		} else {
+				buddy_unref(buddy,"hand_sub");
 		}
 	default:
-		if (option_verbose > 4) {
-			ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %i\n", pak->subtype);
-		}
+			ast_verb(3, "JABBER: This is a subcription of type %i\n", pak->subtype);
 	}
 }
 
@@ -1896,11 +2084,13 @@
  */
 static void *aji_recv_loop(void *data)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
 	int res = IKS_HOOK;
 
+	client_ref(client,"recv_loop");
+
 	while(res != IKS_OK) {
-		ast_debug(3, "JABBER: Connecting.\n");
+		ast_verb(4, "JABBER: Connecting.\n");
 		res = aji_reconnect(client);
 		sleep(4);
 	}
@@ -1938,7 +2128,7 @@
 		} else if (res == IKS_NET_RWERR)
 			ast_log(LOG_WARNING, "JABBER: socket read error\n");
 	} while (client);
-	ASTOBJ_UNREF(client, aji_client_destroy);
+	client_unref(client, "recv_loop");
 	return 0;
 }
 
@@ -2053,11 +2243,13 @@
  * \brief goes through roster and prunes users not needed in list, or adds them accordingly.
  * \param client the configured XMPP client we use to connect to a XMPP server
  * \return void.
- * \note The messages here should be configurable.
  */
 static void aji_pruneregister(struct aji_client *client)
 {
 	int res = 0;
+	struct ao2_iterator biter;
+	struct aji_buddy *b = NULL;
+
 	iks *removeiq = iks_new("iq");
 	iks *removequery = iks_new("query");
 	iks *removeitem = iks_new("item");
@@ -2069,30 +2261,33 @@
 
 	iks_insert_node(removeiq, removequery);
 	iks_insert_node(removequery, removeitem);
-	ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
-		ASTOBJ_RDLOCK(iterator);
+	biter = ao2_iterator_init(client->buddies, 0);
+
+	while ((b = ao2_t_iterator_next(&biter, "Iter through buddies"))) {
+		ao2_lock(b);
 		/* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never
 		 * be called at the same time */
-		if (ast_test_flag(&iterator->flags, AJI_AUTOPRUNE)) { /* If autoprune is set on jabber.conf */
-			res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name,
-								 "GoodBye. Your status is no longer needed by Asterisk the Open Source PBX"
+		if (ast_test_flag(&b->flags, AJI_AUTOPRUNE)) {
+			res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, b->name,
+								 "GoodBye your status is no longer needed by Asterisk the Open Source PBX"
 								 " so I am no longer subscribing to your presence.\n"));
-			res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name,
-								 "GoodBye.  You are no longer in the Asterisk config file so I am removing"
+			res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, b->name,
+								 "GoodBye you are no longer in the asterisk config file so I am removing"
 								 " your access to my presence.\n"));
 			iks_insert_attrib(removeiq, "from", client->jid->full); 
 			iks_insert_attrib(removeiq, "type", "set"); 
 			iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster");
-			iks_insert_attrib(removeitem, "jid", iterator->name);
+			iks_insert_attrib(removeitem, "jid", b->name);
 			iks_insert_attrib(removeitem, "subscription", "remove");
 			res = ast_aji_send(client, removeiq);
-		} else if (ast_test_flag(&iterator->flags, AJI_AUTOREGISTER)) {
-			res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name, 
-								 "Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
-			ast_clear_flag(&iterator->flags, AJI_AUTOREGISTER);
-		}
-		ASTOBJ_UNLOCK(iterator);
-	});
+		} else if (ast_test_flag(&b->flags, AJI_AUTOREGISTER)) {
+			res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, b->name, 
+								 "Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
+			ast_clear_flag(&b->flags, AJI_AUTOREGISTER);
+		}
+		ao2_unlock(b);
+		buddy_unref(b,"iter list");
+	}
 
  safeout:
 	iks_delete(removeiq);
@@ -2100,7 +2295,6 @@
 	iks_delete(removeitem);
 	iks_delete(send);
 	
-	ASTOBJ_CONTAINER_PRUNE_MARKED(&client->buddies, aji_buddy_destroy);
 }
 
 /*!
@@ -2111,42 +2305,46 @@
  */
 static int aji_filter_roster(void *data, ikspak *pak)
 {
-	struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
+	struct aji_client *client = (struct aji_client *) data;
+	struct aji_buddy *buddy = NULL, *b = NULL;
+	struct ao2_iterator biter;
 	int flag = 0;
 	iks *x = NULL;
-	struct aji_buddy *buddy;
-	
+
+	client_ref(client, "filter_ros");
 	client->state = AJI_CONNECTED;
-	ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
-		ASTOBJ_RDLOCK(iterator);
+	biter= ao2_iterator_init(client->buddies, 0);
+	while ((b = ao2_t_iterator_next(&biter, "iterate through buddies"))) {
+		ao2_lock(b);
 		x = iks_child(pak->query);
 		flag = 0;
 		while (x) {
 			if (!iks_strcmp(iks_name(x), "item")) {
-				if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) {
+				if (!strcasecmp(b->name, iks_find_attrib(x, "jid"))) {
 					flag = 1;
-					ast_clear_flag(&iterator->flags, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
+					ast_clear_flag(&b->flags, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
 				}
 			}
 			x = iks_next(x);
 		}
-		if (!flag)
-			ast_copy_flags(&iterator->flags, &client->flags, AJI_AUTOREGISTER);
+		if (!flag) {
+			ast_copy_flags(&b->flags, &client->flags, AJI_AUTOREGISTER);
+		}
 		iks_delete(x);
-		
-		ASTOBJ_UNLOCK(iterator);
-	});
+		ao2_unlock(b);
+		buddy_unref(b, "filter_ros");
+	}
 
 	x = iks_child(pak->query);
 	while (x) {
 		flag = 0;
 		if (iks_strcmp(iks_name(x), "item") == 0) {
-			ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
-				ASTOBJ_RDLOCK(iterator);
-				if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid")))
+			biter = ao2_iterator_init(client->buddies, 0);
+			while ((b = ao2_t_iterator_next(&biter,"iter through buddies"))) {
+				if (!strcasecmp(b->name, iks_find_attrib(x, "jid")))
 					flag = 1;
-				ASTOBJ_UNLOCK(iterator);
-			});
+				buddy_unref(b, "filter_ros");
+			}
 
 			if (flag) {
 				/* found buddy, don't create a new one */
@@ -2154,28 +2352,26 @@

[... 659 lines stripped ...]



More information about the svn-commits mailing list