soc.2009.vulture: 364de04f: Reference-counting for buddy-list nodes.

gdick at soc.pidgin.im gdick at soc.pidgin.im
Sat Jun 20 16:30:46 EDT 2009


-----------------------------------------------------------------
Revision: 364de04f0e591ac5889b8378191e992abfcc9c05
Ancestor: e519f7add76fc35b031588f955db58711f41d72c
Author: gdick at soc.pidgin.im
Date: 2009-06-19T14:43:31
Branch: im.pidgin.soc.2009.vulture
URL: http://d.pidgin.im/viewmtn/revision/info/364de04f0e591ac5889b8378191e992abfcc9c05

Modified files:
        vulture/purpleblist.c vulture/purpleblist.h
        vulture/purplemain.c vulture/vultureblist.c
        vulture/vultureblist.h

ChangeLog: 

Reference-counting for buddy-list nodes.

-------------- next part --------------
============================================================
--- vulture/purpleblist.c	6334927d73097fbbd9f112746e4e535ae1ad7322
+++ vulture/purpleblist.c	8a621aeccdfb079faf9c6c469169a0e99d2d81ed
@@ -51,9 +51,9 @@ void PurpleBlistNewNode(PurpleBlistNode 
 
 	lpvbn->szNodeText = NULL;
 	lpvbn->hti = NULL;
+	lpvbn->lRefCount = 1;
+	lpvbn->lpvbnParent = NULL;
 	InitializeCriticalSection(&lpvbn->cs);
-
-	PurpleBlistUpdateNode(NULL, lpblistnode);
 }
 
 
@@ -81,7 +81,9 @@ void PurpleBlistUpdateNode(PurpleBuddyLi
 	{
 		const char *szNodeText;
 
+		if(lpvbn->lpvbnParent) VultureBListNodeRelease(lpvbn->lpvbnParent);
 		lpvbn->lpvbnParent = lpblistnode->parent ? (VULTURE_BLIST_NODE*)lpblistnode->parent->ui_data : NULL;
+		if(lpvbn->lpvbnParent) VultureBListNodeAddRef(lpvbn->lpvbnParent);
 
 		switch(lpblistnode->type)
 		{
@@ -107,13 +109,15 @@ void PurpleBlistUpdateNode(PurpleBuddyLi
 
 		if(lpvbn->szNodeText) g_free(lpvbn->szNodeText);
 		lpvbn->szNodeText = szNodeText ? VultureUTF8ToTCHAR(szNodeText) : NULL;
+
+		/* TODO: We should probably be less willing to give up. */
+		if(lpvbn->szNodeText)
+		{
+			VultureBListNodeAddRef(lpvbn);
+			VulturePostUIMessage(g_hwndMain, VUIMSG_UPDATEBLISTNODE, lpvbn);
+		}
 	}
 	LeaveCriticalSection(&lpvbn->cs);
-
-
-	/* TODO: We should probably be less willing to give up. */
-	if(lpvbn->szNodeText)
-		VulturePostUIMessage(g_hwndMain, VUIMSG_UPDATEBLISTNODE, lpvbn);
 }
 
 
@@ -160,3 +164,41 @@ static BOOL ShouldShowNode(PurpleBlistNo
 
 	return FALSE;
 }
+
+
+/**
+ * Callback for when a buddy-list is removed from the core's list.
+ *
+ * @param	lpbuddylist	Buddy-list. Unused.
+ * @param	lpblistnode	Buddy-list node.
+ */
+void PurpleBlistRemoveNode(PurpleBuddyList *lpbuddylist, PurpleBlistNode *lpblistnode)
+{
+	UNREFERENCED_PARAMETER(lpbuddylist);
+
+	if(!lpblistnode)
+		return;
+
+	VultureBListNodeRelease((VULTURE_BLIST_NODE*)lpblistnode->ui_data);
+}
+
+
+/**
+ * Releases a reference to a VULTURE_BLIST_NODE and frees the node if there are
+ * no outstanding references.
+ *
+ * @param	lpvblnode	Node to release.
+ */
+void VultureBListNodeRelease(VULTURE_BLIST_NODE *lpvblnode)
+{
+	if(InterlockedDecrement(&lpvblnode->lRefCount) == 0)
+	{
+		/* Released last reference. Free object. */
+
+		if(lpvblnode->lpvbnParent) VultureBListNodeRelease(lpvblnode->lpvbnParent);
+		if(lpvblnode->szNodeText) g_free(lpvblnode->szNodeText);
+		DeleteCriticalSection(&lpvblnode->cs);
+
+		g_free(lpvblnode);
+	}
+}
============================================================
--- vulture/purpleblist.h	2ff4a612f09bc65fc9326c233080f9e74d9dd97b
+++ vulture/purpleblist.h	abe0a563ec78440945f1d95893f867b2134afb72
@@ -25,11 +25,29 @@
 #define _VULTURE_PURPLEBLIST_H_
 
 
+#include <windows.h>
+#include <commctrl.h>
+
 #include "purple.h"
 
 
+typedef struct _VULTURE_BLIST_NODE
+{
+	LPTSTR				szNodeText;
+	HTREEITEM			hti;
+	struct _VULTURE_BLIST_NODE	*lpvbnParent;
+	LONG				lRefCount;
+	CRITICAL_SECTION		cs;
+} VULTURE_BLIST_NODE;
+
+
 void PurpleBlistNewNode(PurpleBlistNode *lpblistnode);
 void PurpleBlistUpdateNode(PurpleBuddyList *lpbuddylist, PurpleBlistNode *lpblistnode);
+void PurpleBlistRemoveNode(PurpleBuddyList *lpbuddylist, PurpleBlistNode *lpblistnode);
+void VultureBListNodeRelease(VULTURE_BLIST_NODE *lpvblnode);
 
 
+static INLINE void VultureBListNodeAddRef(VULTURE_BLIST_NODE *lpvblnode) { InterlockedIncrement(&lpvblnode->lRefCount); }
+
+
 #endif
============================================================
--- vulture/purplemain.c	8f535b86254b27654616cbcce9f28a9bdf90f05d
+++ vulture/purplemain.c	8c70805ad11da62e4abcc102160ffb566741e046
@@ -175,7 +175,7 @@ static void InitUI(void)
 {
 	static PurpleBlistUiOps s_blistuiops =
 	{
-		NULL, PurpleBlistNewNode, NULL, PurpleBlistUpdateNode, NULL, NULL, NULL,
+		NULL, PurpleBlistNewNode, NULL, PurpleBlistUpdateNode, PurpleBlistRemoveNode, NULL, NULL,
 		NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL
 	};
============================================================
--- vulture/vultureblist.c	6fb0ed72925e6bab795504ea97433758306001d6
+++ vulture/vultureblist.c	fb9f46a7d0659bf2ad2d2a041a49e09a02846ad8
@@ -28,6 +28,7 @@
 #include "resource.h"
 #include "purple.h"
 #include "vultureblist.h"
+#include "purpleblist.h"
 #include "purplequeue.h"
 #include "purplestatus.h"
 #include "acctmanager.h"
@@ -241,6 +242,11 @@ static LRESULT CALLBACK MainWndProc(HWND
 							{
 								TreeView_DeleteItem(hwndBlistTree, lpvbn->hti);
 								lpvbn->hti = NULL;
+
+								/* Release the reference belonging to the pointer
+								 * cached in the tree-item.
+								 */
+								VultureBListNodeRelease(lpvbn);
 							}
 						}
 
@@ -250,10 +256,13 @@ static LRESULT CALLBACK MainWndProc(HWND
 						{
 							TVINSERTSTRUCT tvis;
 
+							/* We cache this in the tree-view. */
+							VultureBListNodeAddRef(lpvbn);
+
 							tvis.hParent = lpvbn->lpvbnParent ? lpvbn->lpvbnParent->hti : TVI_ROOT;
 							tvis.hInsertAfter = TVI_SORT;
 							tvis.itemex.mask = TVIF_PARAM;
-							tvis.itemex.lParam = lParam;
+							tvis.itemex.lParam = (LPARAM)lpvbn;
 
 							lpvbn->hti = TreeView_InsertItem(hwndBlistTree, &tvis);
 						}
@@ -265,6 +274,9 @@ static LRESULT CALLBACK MainWndProc(HWND
 						TreeView_SetItem(hwndBlistTree, &tvitem);
 					}
 					LeaveCriticalSection(&lpvbn->cs);
+
+					/* Release the reference for this call. */
+					VultureBListNodeRelease(lpvbn);
 				}
 
 				break;
============================================================
--- vulture/vultureblist.h	aab4c2eb4b9d1a0420a8d1b295c54b24af1f56dc
+++ vulture/vultureblist.h	79de054c320b98101b3000cfca9c785a427243e1
@@ -23,20 +23,9 @@
 #ifndef _VULTURE_VULTUREBLIST_H_
 #define _VULTURE_VULTUREBLIST_H_
 
-
 #include <windows.h>
-#include <commctrl.h>
 
 
-typedef struct _VULTURE_BLIST_NODE
-{
-	LPTSTR				szNodeText;
-	HTREEITEM			hti;
-	struct _VULTURE_BLIST_NODE	*lpvbnParent;
-	CRITICAL_SECTION		cs;
-} VULTURE_BLIST_NODE;
-
-
 extern HWND g_hwndMain;
 GList *g_lpglistConvContainers;
 


More information about the Commits mailing list