From 75c7cd86f630e928b77884305ff26013cbbba4ee Mon Sep 17 00:00:00 2001 From: plt Date: Sun, 13 Nov 2011 14:09:58 +0800 Subject: [PATCH] Fix memory leaks --- lib/gencode.py | 2 +- lib/searpc-server.c | 41 ++++++++++++++++++++++++++++++++++------- lib/searpc-server.h | 17 +++++++++++++++-- tests/test-searpc.c | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 11 deletions(-) diff --git a/lib/gencode.py b/lib/gencode.py index b8ac124..00bd073 100644 --- a/lib/gencode.py +++ b/lib/gencode.py @@ -139,7 +139,7 @@ def gen_marshal_register_function(): print "}" signature_template = r""" -inline static const gchar * +inline static gchar * ${signature_name}() { return searpc_compute_signature (${args}); diff --git a/lib/searpc-server.c b/lib/searpc-server.c index 4d0c3a2..79f7fab 100644 --- a/lib/searpc-server.c +++ b/lib/searpc-server.c @@ -14,15 +14,30 @@ struct FuncItem; typedef struct MarshalItem { SearpcMarshalFunc mfunc; - const gchar *signature; + gchar *signature; } MarshalItem; typedef struct FuncItem { void *func; - const gchar *fname; + gchar *fname; MarshalItem *marshal; } FuncItem; + +static void +func_item_free (FuncItem *item) +{ + g_free (item->fname); + g_free (item); +} + +static void +marshal_item_free (MarshalItem *item) +{ + g_free (item->signature); + g_free (item); +} + static GHashTable *marshal_table; static GHashTable *func_table; @@ -106,15 +121,23 @@ void searpc_server_init () { func_table = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, g_free); - marshal_table = g_hash_table_new (g_str_hash, g_str_equal); + NULL, func_item_free); + marshal_table = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, marshal_item_free); /* register buildin marshal functions */ register_marshals(marshal_table); } +void +searpc_server_final() +{ + g_hash_table_destroy (func_table); + g_hash_table_destroy (marshal_table); +} + gboolean -searpc_server_register_marshal (const gchar *signature, SearpcMarshalFunc marshal) +searpc_server_register_marshal (gchar *signature, SearpcMarshalFunc marshal) { MarshalItem *mitem; @@ -122,6 +145,7 @@ searpc_server_register_marshal (const gchar *signature, SearpcMarshalFunc marsha if (g_hash_table_lookup (marshal_table, signature) != NULL) { g_warning ("[Sea RPC] cannot register duplicate marshal.\n"); + g_free (signature); return FALSE; } @@ -134,7 +158,7 @@ searpc_server_register_marshal (const gchar *signature, SearpcMarshalFunc marsha } gboolean -searpc_server_register_function (void *func, const gchar *fname, const gchar *signature) +searpc_server_register_function (void *func, const gchar *fname, gchar *signature) { FuncItem *item; MarshalItem *mitem; @@ -142,8 +166,10 @@ searpc_server_register_function (void *func, const gchar *fname, const gchar *si g_assert (func != NULL && fname != NULL && signature != NULL); mitem = g_hash_table_lookup (marshal_table, signature); - if (!mitem) + if (!mitem) { + g_free (signature); return FALSE; + } item = g_new0 (FuncItem, 1); item->marshal = mitem; @@ -152,6 +178,7 @@ searpc_server_register_function (void *func, const gchar *fname, const gchar *si g_hash_table_insert (func_table, (gpointer)item->fname, item); + g_free (signature); return TRUE; } diff --git a/lib/searpc-server.h b/lib/searpc-server.h index 2a358dc..bf0596c 100644 --- a/lib/searpc-server.h +++ b/lib/searpc-server.h @@ -15,22 +15,35 @@ typedef gchar* (*SearpcMarshalFunc) (void *func, struct _JsonArray *param_array, */ void searpc_server_init (); +/** + * searpc_server_final: + * + * Free the server structure. + */ +void searpc_server_final (); + /** * searpc_server_register_marshal: * * For user to extend marshal functions. + * + * @signature: the signature of the marshal, register_marshal() will take + * owner of this string. */ -gboolean searpc_server_register_marshal (const gchar *signature, +gboolean searpc_server_register_marshal (gchar *signature, SearpcMarshalFunc marshal); /** * searpc_server_register_function: * * Register a rpc function with given signature. + * + * @signature: the signature of the function, register_function() will take + * owner of this string. */ gboolean searpc_server_register_function (void* func, const gchar *fname, - const gchar *signature); + gchar *signature); /** * searpc_server_call_function: diff --git a/tests/test-searpc.c b/tests/test-searpc.c index 4b6af73..e9ff949 100644 --- a/tests/test-searpc.c +++ b/tests/test-searpc.c @@ -93,6 +93,17 @@ maman_bar_get_property (GObject *object, } } +static void +maman_bar_finalize (GObject *gobject) +{ + MamanBar *self = MAMAN_BAR (gobject); + + g_free (self->name); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (maman_bar_parent_class)->finalize (gobject); +} + static void maman_bar_class_init (MamanBarClass *klass) { @@ -101,6 +112,7 @@ maman_bar_class_init (MamanBarClass *klass) gobject_class->set_property = maman_bar_set_property; gobject_class->get_property = maman_bar_get_property; + gobject_class->finalize = maman_bar_finalize; pspec = g_param_spec_string ("name", "Maman name", @@ -163,14 +175,20 @@ void test_simple_call (void *fixture, const void *data) fret = searpc_server_call_function (fcall, fcall_len, &ret_len); result = searpc_client_fret__string (fret, ret_len, &error); g_assert (strcmp(result, "he") == 0); + g_free (fcall); + g_free (fret); g_free (result); /* error should return */ + result = NULL; fcall = searpc_client_fcall__string_int ("get_substring", "hello", 7, &fcall_len); fret = searpc_server_call_function (fcall, fcall_len, &ret_len); result = searpc_client_fret__string (fret, ret_len, &error); g_assert (error->message); + g_free (fcall); + g_free (fret); + g_free (result); } GObject * @@ -190,6 +208,10 @@ void test_object_call (void *fixture, const void *data) &fcall_len); fret = searpc_server_call_function (fcall, fcall_len, &ret_len); result = searpc_client_fret__object (MAMAN_TYPE_BAR, fret, ret_len, &error); + + g_free (fcall); + g_free (fret); + g_object_unref (result); } @@ -231,14 +253,22 @@ void test_objlist_call (void *fixture, const void *data) &fcall_len); fret = searpc_server_call_function (fcall, fcall_len, &ret_len); result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error); + g_free (fcall); + g_free (fret); for (ptr = result; ptr; ptr = ptr->next) g_object_unref (ptr->data); g_list_free (result); + fcall = searpc_client_fcall__string_int ("get_maman_bar_list", "kitty", 0, &fcall_len); fret = searpc_server_call_function (fcall, fcall_len, &ret_len); result = searpc_client_fret__objlist (MAMAN_TYPE_BAR, fret, ret_len, &error); + g_free (fcall); + g_free (fret); + for (ptr = result; ptr; ptr = ptr->next) + g_object_unref (ptr->data); + g_list_free (result); } @@ -269,5 +299,9 @@ main (int argc, char *argv[]) g_test_add ("/searpc/objlist", void, NULL, NULL, test_objlist_call, NULL); - return g_test_run(); + int ret = g_test_run(); + + /* free memory for memory debug with valgrind */ + searpc_server_final(); + return ret; }