[PATCH] Allow use of gcache'd strings in hashtables
Chris Shoemaker
c.shoemaker at cox.net
Thu Feb 10 17:12:58 EST 2005
* allow the use of gcache'd strings in ghashtables without leaking
- Introduce functions gnc_string_cache_remove() and
gnc_string_cache_insert()
* add comment warning about dangerous macro SAFE_STRCMP_REAL
* fix qofbook's leaking of strings in ghashtable by using new
gnc_string_cache_* functions
Index: src/engine/gnc-engine-util.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-engine-util.c,v
retrieving revision 1.29.4.3
diff -u -r1.29.4.3 gnc-engine-util.c
--- src/engine/gnc-engine-util.c 3 May 2004 06:17:02 -0000 1.29.4.3
+++ src/engine/gnc-engine-util.c 10 Feb 2005 05:06:51 -0000
@@ -221,6 +221,7 @@
static GCache * gnc_string_cache = NULL;
+/* maybe better to make this function static */
GCache*
gnc_engine_get_string_cache(void)
{
@@ -241,5 +242,15 @@
gnc_string_cache = NULL;
}
+void gnc_string_cache_remove(gpointer key)
+{
+ g_cache_remove(gnc_engine_get_string_cache(), key);
+}
+
+gpointer gnc_string_cache_insert(gpointer key)
+{
+ return g_cache_insert(gnc_engine_get_string_cache(), key);
+}
+
/************************* END OF FILE ******************************\
\********************************************************************/
Index: src/engine/gnc-engine-util.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-engine-util.h,v
retrieving revision 1.32.4.5
diff -u -r1.32.4.5 gnc-engine-util.h
--- src/engine/gnc-engine-util.h 7 Jul 2004 04:10:29 -0000 1.32.4.5
+++ src/engine/gnc-engine-util.h 10 Feb 2005 05:06:51 -0000
@@ -38,6 +38,12 @@
/** Macros *****************************************************/
+/* CAS: Notice that this macro does nothing if pointer args are equal.
+ Otherwise, it returns an integer. Actually, perhaps these macro
+ should be private. They are NOT good substitutes for the function
+ versions like safe_strcmp(). Maybe external users of these 3
+ macros should be converted to use safe_strcmp(). Actually, THESE
+ MACROS AFFECT CONTROL FLOW. YUCK! */
#define SAFE_STRCMP_REAL(fcn,da,db) { \
if ((da) && (db)) { \
if ((da) != (db)) { \
@@ -135,5 +141,16 @@
void gnc_engine_string_cache_destroy (void);
+/* TODO: hide the gcache as a static */
+
+/* You can use this function as a destroy notifier for a GHashTable
+ that uses common strings as keys (or values, for that matter.) */
+void gnc_string_cache_remove(gpointer key);
+
+/* You can use this function with g_hash_table_insert(), or the key
+ (or value), as long as you use the destroy notifier above. */
+gpointer gnc_string_cache_insert(gpointer key);
+
+
#endif /* QOF_UTIL_H */
/** @} */
Index: src/engine/qofbook.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook.c,v
retrieving revision 1.10.2.5
diff -u -r1.10.2.5 qofbook.c
--- src/engine/qofbook.c 7 Jul 2004 04:10:29 -0000 1.10.2.5
+++ src/engine/qofbook.c 10 Feb 2005 05:06:53 -0000
@@ -49,11 +49,17 @@
#include "qofclass.h"
#include "qofid-p.h"
#include "qofobject-p.h"
+#include "gnc-engine-util.h"
#include "guid.h"
static short module = MOD_ENGINE;
+static void coll_destroy(gpointer col)
+{
+ qof_collection_destroy((QofCollection *) col);
+}
+
/* ====================================================================== */
/* constructor / destructor */
@@ -62,7 +68,9 @@
{
if (!book) return;
- book->hash_of_collections = g_hash_table_new (g_str_hash, g_str_equal);
+ book->hash_of_collections = g_hash_table_new_full(g_str_hash, g_str_equal,
+ gnc_string_cache_remove,
+ coll_destroy);
qof_instance_init (&book->inst, QOF_ID_BOOK, book);
@@ -89,14 +97,6 @@
return book;
}
-static gboolean
-coll_destroy(gpointer key, gpointer value, gpointer not_used)
-{
- QofCollection *col = value;
- qof_collection_destroy (col);
- return TRUE;
-}
-
static void
book_final (gpointer key, gpointer value, gpointer booq)
{
@@ -128,8 +128,6 @@
qof_instance_release (&book->inst);
- g_hash_table_foreach_remove (book->hash_of_collections,
- coll_destroy, NULL);
g_hash_table_destroy (book->hash_of_collections);
book->hash_of_collections = NULL;
@@ -236,21 +234,17 @@
qof_book_get_collection (QofBook *book, QofIdType entity_type)
{
QofCollection *col;
-
+
if (!book || !entity_type) return NULL;
-
+
col = g_hash_table_lookup (book->hash_of_collections, entity_type);
if (col) return col;
-
+
col = qof_collection_new (entity_type);
-
+
- /* XXX should use string_cache instead of strdup */
- /* Need strdup because values are sometimes freed */
- /* this is a memory leak, since malloc'ed value is not freed */
- /* ??? huh ?? freed where? by whom? */
g_hash_table_insert (book->hash_of_collections,
- (gpointer)g_strdup(entity_type), col);
-
+ gnc_string_cache_insert((gpointer) entity_type), col);
+
return col;
}
More information about the gnucash-patches
mailing list