You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ro...@apache.org on 2012/04/28 13:33:58 UTC

svn commit: r1331752 - in /thrift/trunk: compiler/cpp/src/generate/ lib/c_glib/test/

Author: roger
Date: Sat Apr 28 11:33:58 2012
New Revision: 1331752

URL: http://svn.apache.org/viewvc?rev=1331752&view=rev
Log:
THRIFT-1583 c_glib leaks memory
THRIFT-1578 C_GLib generated code does not compile
THRIFT-1582 Bad includes of nested thrift files in c_glib

Patch: José Antonio Santos
Minor Modificatons by roger:
- thrift prefix for includes
- g_object_unref instead of g_clear_object (needs glib>=2.28)

Modified:
    thrift/trunk/compiler/cpp/src/generate/t_c_glib_generator.cc
    thrift/trunk/lib/c_glib/test/testbinaryprotocol.c
    thrift/trunk/lib/c_glib/test/testbufferedtransport.c
    thrift/trunk/lib/c_glib/test/testdebugproto.c
    thrift/trunk/lib/c_glib/test/testframedtransport.c
    thrift/trunk/lib/c_glib/test/testmemorybuffer.c
    thrift/trunk/lib/c_glib/test/testoptionalrequired.c
    thrift/trunk/lib/c_glib/test/teststruct.c
    thrift/trunk/lib/c_glib/test/testthrifttestclient.cpp
    thrift/trunk/lib/c_glib/test/testtransportsocket.c

Modified: thrift/trunk/compiler/cpp/src/generate/t_c_glib_generator.cc
URL: http://svn.apache.org/viewvc/thrift/trunk/compiler/cpp/src/generate/t_c_glib_generator.cc?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/compiler/cpp/src/generate/t_c_glib_generator.cc (original)
+++ thrift/trunk/compiler/cpp/src/generate/t_c_glib_generator.cc Sat Apr 28 11:33:58 2012
@@ -124,6 +124,7 @@ class t_c_glib_generator : public t_oop_
   string argument_list(t_struct *tstruct);
   string xception_list(t_struct *tstruct);
   string declare_field(t_field *tfield, bool init=false, bool pointer=false, bool constant=false, bool reference=false);
+  void declare_local_variable(ofstream &out, t_type *ttype, string &base_name);
 
   /* generation functions */
   void generate_const_initializer(string name, t_type *type, t_const_value *value);
@@ -140,15 +141,19 @@ class t_c_glib_generator : public t_oop_
   void generate_serialize_set_element(ofstream &out, t_set *tset, string element, int error_ret);
   void generate_serialize_list_element(ofstream &out, t_list *tlist, string list, string index, int error_ret);
 
-  void generate_deserialize_field(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret);
-  void generate_deserialize_struct(ofstream &out, t_struct *tstruct, string prefix, int error_ret);
+  void generate_deserialize_field(ofstream &out, t_field *tfield, string prefix, string suffix, int error_ret, bool allocate=true);
+  void generate_deserialize_struct(ofstream &out, t_struct *tstruct, string prefix, int error_ret, bool allocate=true);
   void generate_deserialize_container(ofstream &out, t_type *ttype, string prefix, int error_ret);
   void generate_deserialize_map_element(ofstream &out, t_map *tmap, string prefix, int error_ret);
   void generate_deserialize_set_element(ofstream &out, t_set *tset, string prefix, int error_ret);
   void generate_deserialize_list_element(ofstream &out, t_list *tlist, string prefix, string index, int error_ret);
 
-  string generate_new_hash_from_type(t_type * ttype);
+  string generate_new_hash_from_type(t_type * key, t_type * value);
   string generate_new_array_from_type(t_type * ttype); 
+
+  string generate_free_func_from_type(t_type * ttype);
+  string generate_hash_func_from_type(t_type * ttype);
+  string generate_cmp_func_from_type(t_type * ttype);
 };
 
 /**
@@ -185,7 +190,7 @@ void t_c_glib_generator::init_generator(
   f_types_ <<
     "/* base includes */" << endl <<
     "#include <glib-object.h>" << endl <<
-    "#include <thrift_struct.h>" << endl <<
+    "#include <thrift/thrift_struct.h>" << endl <<
     "#include <thrift/protocol/thrift_protocol.h>" << endl;
 
   /* include other thrift includes */
@@ -193,7 +198,7 @@ void t_c_glib_generator::init_generator(
   for (size_t i = 0; i < includes.size(); ++i) {
     f_types_ <<
       "/* other thrift includes */" << endl <<
-      "#include \"" << this->nspace_lc << includes[i]->get_name() <<
+      "#include \"" << this->nspace_lc << initial_caps_to_underscores(includes[i]->get_name()) <<
           "_types.h\"" << endl;
   }
   f_types_ << endl;
@@ -411,7 +416,7 @@ void t_c_glib_generator::generate_servic
   f_service_ <<
     "#include <string.h>" << endl <<
     "#include <thrift/thrift.h>" << endl <<
-    "#include <thrift_application_exception.h>" << endl <<
+    "#include <thrift/thrift_application_exception.h>" << endl <<
     "#include \"" << filename << ".h\"" << endl <<
     endl;
 
@@ -650,7 +655,7 @@ string t_c_glib_generator::constant_valu
     t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
     switch (tbase) {
       case t_base_type::TYPE_STRING:
-        render << "\"" + value->get_string() + "\"";
+        render << "g_strdup (\"" + value->get_string() + "\")";
         break;
       case t_base_type::TYPE_BOOL:
         render << ((value->get_integer() != 0) ? 1 : 0);
@@ -805,6 +810,8 @@ string t_c_glib_generator::declare_field
       }
     } else if (type->is_enum()) {
       result += " = (" + type_name (type) + ") 0";
+    } else if (type->is_struct() || type->is_container()) {
+      result += " = NULL";
     }
   }
 
@@ -876,7 +883,8 @@ void t_c_glib_generator::generate_const_
       endl;
   } else if (type->is_list()) {
     string list_type = "GPtrArray *";
-    string list_initializer = "g_ptr_array_new()";
+    // TODO: This initialization should contain a free function for container
+    string list_initializer = "g_ptr_array_new();";
     string list_appender = "g_ptr_array_add";
     bool list_variable = false;
 
@@ -885,6 +893,7 @@ void t_c_glib_generator::generate_const_
     vector<t_const_value*>::const_iterator v_iter;
     ostringstream initializers;
 
+    list_initializer = generate_new_array_from_type (etype);
     if (etype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type *) etype)->get_base();
       switch (tbase) {
@@ -897,7 +906,6 @@ void t_c_glib_generator::generate_const_
         case t_base_type::TYPE_I64:
         case t_base_type::TYPE_DOUBLE:
           list_type = "GArray *";
-          list_initializer = generate_new_array_from_type (etype);
           list_appender = "g_array_append_val";
           list_variable = true;
           break;
@@ -932,7 +940,7 @@ void t_c_glib_generator::generate_const_
       "  static " << list_type << " constant = NULL;" << endl <<
       "  if (constant == NULL)" << endl <<
       "  {" << endl <<
-      "    constant = " << list_initializer << ";" << endl <<
+      "    constant = " << list_initializer << endl <<
       initializers.str() << endl <<
       "  }" << endl <<
       "  return constant;" << endl <<
@@ -961,6 +969,7 @@ void t_c_glib_generator::generate_const_
       "  static GHashTable *constant = NULL;" << endl <<
       "  if (constant == NULL)" << endl <<
       "  {" << endl <<
+      // TODO: This initialization should contain a free function for elements
       "    constant = g_hash_table_new (NULL, NULL);" << endl <<
       initializers.str() << endl <<
       "  }" << endl <<
@@ -997,6 +1006,7 @@ void t_c_glib_generator::generate_const_
       "  static GHashTable *constant = NULL;" << endl <<
       "  if (constant == NULL)" << endl <<
       "  {" << endl <<
+      // TODO: This initialization should contain a free function for elements
       "    constant = g_hash_table_new (NULL, NULL);" << endl <<
       initializers.str() << endl <<
       "  }" << endl <<
@@ -1736,37 +1746,23 @@ void t_c_glib_generator::generate_object
       indent(f_types_impl_) << "object->" << name << " = NULL;" << endl;
     } else if (t->is_container()) {
       string name = (*m_iter)->get_name();
+      string init_function;
 
-      if (t->is_map() || t->is_set()) {
-        indent(f_types_impl_) << "object->" << name << " = g_hash_table_new (NULL, NULL);" << endl;
+      if (t->is_map()) {
+        t_type *key = ((t_map *) t)->get_key_type();
+        t_type *value = ((t_map *) t)->get_val_type();
+        init_function = generate_new_hash_from_type (key, value);
+      } else if (t->is_set()) {
+        t_type *etype = ((t_set *) t)->get_elem_type();
+        init_function = generate_new_hash_from_type (etype, NULL);
       } else if (t->is_list()) {
         t_type *etype = ((t_list *) t)->get_elem_type();
-        string init_function = "g_ptr_array_new()";
-
-        if (etype->is_base_type()) {
-          t_base_type::t_base tbase = ((t_base_type *) etype)->get_base();
-          switch (tbase) {
-            case t_base_type::TYPE_VOID:
-              throw "compiler error: cannot determine array type";
-            case t_base_type::TYPE_BOOL:
-            case t_base_type::TYPE_BYTE:
-            case t_base_type::TYPE_I16:
-            case t_base_type::TYPE_I32:
-            case t_base_type::TYPE_I64:
-            case t_base_type::TYPE_DOUBLE:
-              init_function = generate_new_array_from_type (etype);
-              break;
-            case t_base_type::TYPE_STRING:
-              break;
-            default:
-              throw "compiler error: no array info for type";
-          }
-        }
-
-        indent(f_types_impl_) << "object->" << name << " = " <<
-                                  init_function << ";" << endl;
+        init_function = generate_new_array_from_type (etype);
       }
 
+      indent(f_types_impl_) << "object->" << name << " = " <<
+                                  init_function << endl;
+
     }
 
     /* if not required, initialize the __isset variable */
@@ -1800,8 +1796,14 @@ void t_c_glib_generator::generate_object
     if (t->is_container()) { 
       string name = (*m_iter)->get_name();
       if (t->is_map() || t->is_set()) {
-        f_types_impl_ <<
-          indent() << "g_hash_table_unref (tobject->" << name << ");" << endl;
+        f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl;
+        f_types_impl_ << indent() << "{" << endl;
+	indent_up();
+	f_types_impl_ <<
+	indent() << "g_hash_table_destroy (tobject->" << name << ");" << endl;
+	f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl;
+	indent_down();
+	f_types_impl_ << indent() << "}" << endl;
       } else if (t->is_list()) {
         t_type *etype = ((t_list *) t)->get_elem_type();
         string destructor_function = "g_ptr_array_free";
@@ -1826,10 +1828,39 @@ void t_c_glib_generator::generate_object
           }
         }
 
+        f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl;
+        f_types_impl_ << indent() << "{" << endl;
+        indent_up();
         f_types_impl_ <<
           indent() << destructor_function << " (tobject->" << name <<
-                       ", FALSE);" << endl;
+                       ", TRUE);" << endl;
+        f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl;
+        indent_down();
+        f_types_impl_ << indent() << "}" << endl;
       }
+    } else if (t->is_struct() || t->is_xception()) {
+      string name = (*m_iter)->get_name();
+      // TODO: g_clear_object needs glib >= 2.28
+      // f_types_impl_ << indent() << "g_clear_object (&(tobject->" << name << "));" << endl;
+      // does g_object_unref the trick?
+      f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl;
+      f_types_impl_ << indent() << "{" << endl;
+      indent_up();
+      f_types_impl_ <<
+      indent() << "g_object_unref(tobject->" << name << ");" << endl;
+      f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl;
+      indent_down();
+      f_types_impl_ << indent() << "}" << endl;
+    } else if (t->is_string()) {
+      string name = (*m_iter)->get_name();
+      f_types_impl_ << indent() << "if (tobject->" << name << " != NULL)" << endl;
+      f_types_impl_ << indent() << "{" << endl;
+      indent_up();
+      f_types_impl_ <<
+      indent() << "g_free (tobject->" << name << ");" << endl;
+      f_types_impl_ << indent() << "tobject->" << name << " = NULL;" << endl;
+      indent_down();
+      f_types_impl_ << indent() << "}" << endl;
     }
   }
 
@@ -2008,7 +2039,7 @@ void t_c_glib_generator::generate_struct
   out <<
     indent() << "gint32 ret;" << endl <<
     indent() << "gint32 xfer = 0;" << endl <<
-    indent() << "gchar *name;" << endl <<
+    indent() << "gchar *name = NULL;" << endl <<
     indent() << "ThriftType ftype;" << endl <<
     indent() << "gint16 fid;" << endl <<
     indent() << "guint32 len = 0;" << endl <<
@@ -2044,6 +2075,7 @@ void t_c_glib_generator::generate_struct
     indent() << "}" << endl <<
     indent() << "xfer += ret;" << endl <<
     indent() << "if (name) g_free (name);" << endl <<
+    indent() << "name = NULL;" << endl <<
     endl;
 
   // read the struct fields
@@ -2062,6 +2094,7 @@ void t_c_glib_generator::generate_struct
     indent() << "}" << endl <<
     indent() << "xfer += ret;" << endl <<
     indent() << "if (name) g_free (name);" << endl <<
+    indent() << "name = NULL;" << endl <<
     endl;
 
   // check for field STOP marker
@@ -2093,7 +2126,7 @@ void t_c_glib_generator::generate_struct
 
     indent_up();
     // generate deserialize field
-    generate_deserialize_field (out, *f_iter, this_name, "", error_ret);
+    generate_deserialize_field (out, *f_iter, this_name, "", error_ret, false);
     indent_down();
 
     out <<
@@ -2319,9 +2352,11 @@ void t_c_glib_generator::generate_serial
       indent() << "GList *key_list = NULL, *iter = NULL;" << endl <<
       indent() << telem_name << telem_ptr << " elem;" << endl <<
       indent() << "gpointer value;" << endl <<
+      indent() << "THRIFT_UNUSED_VAR (value);" << endl <<
+      endl <<
       indent() << "g_hash_table_foreach ((GHashTable *) " << prefix <<
                    ", thrift_hash_table_get_keys, &key_list);" << endl <<
-      indent() << telem_name << telem_ptr << "keys[g_list_length (key_list)];" << endl <<
+      indent() << telem_name << telem_ptr << " keys[g_list_length (key_list)];" << endl <<
       indent() << "int i=0, key_count = g_list_length (key_list);" << endl <<
       indent() << "for (iter = g_list_first (key_list); iter; iter = iter->next)" << endl <<
       indent() << "{" << endl <<
@@ -2347,17 +2382,19 @@ void t_c_glib_generator::generate_serial
       indent() << "xfer += ret;" << endl;
   } else if (ttype->is_list()) {
     string length = prefix + "->len";
+    string i = tmp("i");
     out <<
       indent() << "if ((ret = thrift_protocol_write_list_begin (protocol, " <<
                    type_to_enum (((t_list *) ttype)->get_elem_type()) <<
                    ", (gint32) " << length << ", error)) < 0)" << endl <<
       indent() << "  return " << error_ret << ";" << endl <<
       indent() << "xfer += ret;" << endl <<
-      indent() << "guint i;" << endl <<
-      indent() << "for (i=0; i<" << length << "; i++)" << endl;
+      indent() << "guint " << i << ";" << endl <<
+      indent() << "for ("<< i << "=0; " << i << "<" << length << "; " << i <<
+                         "++)" << endl;
 
     scope_up(out);
-    generate_serialize_list_element (out, (t_list *) ttype, prefix, "i", error_ret);
+    generate_serialize_list_element (out, (t_list *) ttype, prefix, i, error_ret);
     scope_down(out);
 
     out <<
@@ -2397,6 +2434,7 @@ void t_c_glib_generator::generate_serial
   t_type *ttype = tlist->get_elem_type();
 
   // cast to non-const
+  string cast = "";
   string name = "g_ptr_array_index ((GPtrArray *) " + list + ", "
                 + index + ")";
 
@@ -2425,13 +2463,40 @@ void t_c_glib_generator::generate_serial
         name = "g_array_index (" + list + ", gdouble, " + index + ")";
         break;
       case t_base_type::TYPE_STRING:
+        cast = "(gchar*)";
         break;
       default:
         throw "compiler error: no array info for type";
     }
+  } else if (ttype->is_map() || ttype->is_set()) {
+    cast = "(GHashTable*)";
+  } else if (ttype->is_list()) {
+    t_type *base = ((t_list *)ttype)->get_elem_type();
+    if (base->is_base_type()) {
+      switch (((t_base_type *) base)->get_base()) {
+        case t_base_type::TYPE_VOID:
+          throw "compiler error: cannot determine array type";
+          break;
+        case t_base_type::TYPE_BOOL:
+        case t_base_type::TYPE_BYTE:
+        case t_base_type::TYPE_I16:
+        case t_base_type::TYPE_I32:
+        case t_base_type::TYPE_I64:
+        case t_base_type::TYPE_DOUBLE:
+          cast = "(GArray*)";
+          break;
+        case t_base_type::TYPE_STRING:
+          cast = "(GPtrArray*)";
+          break;
+        default:
+          throw "Compiler error: no array info for type";
+      }
+    } else {
+      cast = "(GPtrArray*)";
+    }
   }
 
-  t_field efield (ttype, name);
+  t_field efield (ttype, "(" + cast + name + ")");
   generate_serialize_field (out, &efield, "", "", error_ret);
 }
 
@@ -2440,7 +2505,8 @@ void t_c_glib_generator::generate_deseri
                                                     t_field *tfield,
                                                     string prefix,
                                                     string suffix,
-                                                    int error_ret) {
+                                                    int error_ret,
+                                                    bool allocate) {
   t_type *type = get_true_type (tfield->get_type());
 
   if (type->is_void()) {
@@ -2451,12 +2517,21 @@ void t_c_glib_generator::generate_deseri
   string name = prefix + tfield->get_name() + suffix;
 
   if (type->is_struct() || type->is_xception()) {
-    generate_deserialize_struct (out, (t_struct *) type, name, error_ret);
+    generate_deserialize_struct (out, (t_struct *) type, name, error_ret, allocate);
   } else if (type->is_container()) {
     generate_deserialize_container (out, type, name, error_ret);
   } else if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type *) type)->get_base();
-
+    if (tbase == t_base_type::TYPE_STRING) {
+      indent(out) << "if (" << name << " != NULL)" << endl <<
+        indent() << "{" << endl;
+      indent_up();
+      indent(out) << "g_free(" << name << ");" << endl <<
+        indent() << name << " = NULL;" << endl;
+      indent_down();
+      indent(out) << "}" << endl <<
+      endl;
+    }
     indent(out) << "if ((ret = thrift_protocol_read_";
 
     switch (tbase) {
@@ -2529,12 +2604,39 @@ void t_c_glib_generator::generate_deseri
 void t_c_glib_generator::generate_deserialize_struct(ofstream &out,
                                                      t_struct *tstruct,
                                                      string prefix,
-                                                     int error_ret) {
+                                                     int error_ret,
+                                                     bool allocate) {
   string name_uc = to_upper_case(initial_caps_to_underscores(tstruct->get_name()));
+  if (tstruct->is_xception()) {
+    out <<
+      indent() << "/* This struct is an exception */" << endl;
+    allocate = true;
+  }
+
+  if (allocate) {
+    out <<
+      indent() << "if ( " << prefix << " != NULL)" << endl <<
+      indent() << "{" << endl;
+    indent_up();
+    out <<
+      indent() << "g_object_unref (" << prefix << ");" << endl;
+    indent_down();
+    out <<
+      indent() << "}" << endl <<
+      indent() << prefix << " = g_object_new (" << this->nspace_uc << "TYPE_" << name_uc << ", NULL);" << endl;
+  }
   out <<
-    indent() << prefix << " = g_object_new (" << this->nspace_uc << "TYPE_" << name_uc << ", NULL);" << endl <<
     indent() << "if ((ret = thrift_struct_read (THRIFT_STRUCT (" << prefix << "), protocol, error)) < 0)" << endl <<
-    indent() << "  return " << error_ret << ";" << endl <<
+    indent() << "{" << endl;
+  indent_up();
+  if (allocate) {
+    indent(out) << "g_object_unref (" << prefix << ");" << endl;
+  }
+  out <<
+    indent() << "return " << error_ret << ";" << endl;
+  indent_down();
+  out <<
+    indent() << "}" << endl <<
     indent() << "xfer += ret;" << endl;
 }
 
@@ -2624,35 +2726,36 @@ void t_c_glib_generator::generate_deseri
   scope_down(out);
 }
 
+void t_c_glib_generator::declare_local_variable(ofstream &out, t_type *ttype, string &name) {
+  string tname = type_name (ttype);
+  string ptr = ttype->is_string() || !ttype->is_base_type() ? "" : "*";
+
+  if (ttype->is_map()) {
+    out <<
+    indent() << tname << ptr << " " << name << " = g_hash_table_new (NULL, NULL);" << endl;
+  } else if (ttype->is_enum()) {
+    out <<
+    indent() << tname << ptr << " " << name << ";" << endl;
+  } else {
+    out <<
+    indent() << tname << ptr << " " << name << (ptr != "" ? " = g_new (" + tname + ", 1)" : " = NULL") << ";" << endl;
+  }
+}
+
+
 void t_c_glib_generator::generate_deserialize_map_element(ofstream &out,
                                                           t_map *tmap,
                                                           string prefix,
                                                           int error_ret) {
   t_type *tkey = tmap->get_key_type();
   t_type *tval = tmap->get_val_type();
-  string tkey_name = type_name (tkey);
-  string tval_name = type_name (tval);
   string tkey_ptr = tkey->is_string() || !tkey->is_base_type() ? "" : "*";
   string tval_ptr = tval->is_string() || !tval->is_base_type() ? "" : "*";
-
   string keyname = tmp("key");
   string valname = tmp("val");
 
-  if (tkey->is_map()) {
-    out <<
-      indent() << tkey_name << tkey_ptr << " " << keyname << " = g_hash_table_new (NULL, NULL);" << endl;
-  } else {
-    out <<
-      indent() << tkey_name << tkey_ptr << " " << keyname << (tkey_ptr != "" ? " = g_new (" + tkey_name + ", 1)" : "") << ";" << endl;
-  }
-
-  if (tval->is_map()) {
-    out <<
-      indent() << tval_name << tval_ptr << " " << valname << " = g_hash_table_new (NULL, NULL);" << endl;
-  } else {
-    out <<
-      indent() << tval_name << tval_ptr << " " << valname << (tval_ptr != "" ? " = g_new (" + tval_name + ", 1)" : "") << ";" << endl;
-  }
+  declare_local_variable(out, tkey, keyname);
+  declare_local_variable(out, tval, valname);
 
   // deserialize the fields of the map element
   t_field fkey (tkey, tkey_ptr + keyname);
@@ -2660,10 +2763,8 @@ void t_c_glib_generator::generate_deseri
   t_field fval (tval, tval_ptr + valname);
   generate_deserialize_field (out, &fval, "", "", error_ret);
 
-  // insert into the hashtable.  if the field is not a pointer, then use
-  // the address of the object.
   indent(out) <<
-    "g_hash_table_insert ((GHashTable *)" << prefix << ", (gpointer) " << (tkey_ptr != "" ? "" : "&") << keyname << ", (gpointer) " << (tval_ptr != "" ? "" : "&") << valname << ");" << endl;
+    "g_hash_table_insert ((GHashTable *)" << prefix << ", (gpointer) " << keyname << ", (gpointer) " << valname << ");" << endl;
 }
 
 void t_c_glib_generator::generate_deserialize_set_element(ofstream &out,
@@ -2671,22 +2772,17 @@ void t_c_glib_generator::generate_deseri
                                                           string prefix,
                                                           int error_ret) {
   t_type *telem = tset->get_elem_type();
-  string telem_name = type_name (telem);
+  string elem = tmp ("_elem");
   string telem_ptr = telem->is_string() || !telem->is_base_type() ? "" : "*";
 
-  if (telem->is_map()) {
-    out <<
-      indent() << telem_name << telem_ptr << " elem = g_hash_table_new (NULL, NULL);" << endl;
-  } else {
-    out <<
-      indent() << telem_name << telem_ptr << " elem" << (telem_ptr != "" ? " = g_new (" + telem_name + ", 1)" : "") << ";" << endl;
-  }
+  declare_local_variable(out, telem, elem);
 
-  t_field felem (telem, telem_ptr + "elem");
+  t_field felem (telem, telem_ptr + elem);
   generate_deserialize_field (out, &felem, "", "", error_ret);
 
   indent(out) <<
-    "g_hash_table_insert ((GHashTable *) " << prefix << ", (gpointer) elem, (gpointer) 1);" << endl;
+    "g_hash_table_insert ((GHashTable *) " << prefix << ", (gpointer) " <<
+                              elem << ", (gpointer) 1);" << endl;
 }
 
 void t_c_glib_generator::generate_deserialize_list_element(ofstream &out,
@@ -2695,15 +2791,17 @@ void t_c_glib_generator::generate_deseri
                                                            string index,
                                                            int error_ret) {
   (void) index;
+  t_type *ttype = tlist->get_elem_type();
   string elem = tmp ("_elem");
-  t_field felem (tlist->get_elem_type(), elem);
+  string telem_ptr = ttype->is_string() || !ttype->is_base_type() ? "" : "*";
+
+  declare_local_variable(out, ttype, elem);
 
-  indent(out) << declare_field (&felem, true) << endl;
+  t_field felem (ttype, telem_ptr + elem);
   generate_deserialize_field (out, &felem, "", "", error_ret);
 
   indent(out);
 
-  t_type *ttype = tlist->get_elem_type();
   if (ttype->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type *) ttype)->get_base();
     switch (tbase) {
@@ -2727,7 +2825,10 @@ void t_c_glib_generator::generate_deseri
   out << "g_ptr_array_add (" << prefix << ", " << elem << ");" << endl;
 }
 
-string t_c_glib_generator::generate_new_hash_from_type (t_type * ttype) {
+string t_c_glib_generator::generate_free_func_from_type (t_type * ttype) {
+  if (ttype == NULL)
+    return "NULL";
+
   if (ttype->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type *) ttype)->get_base();
     switch (tbase) {
@@ -2735,24 +2836,135 @@ string t_c_glib_generator::generate_new_
         throw "compiler error: cannot determine hash type";
         break;
       case t_base_type::TYPE_BOOL:
-        return "g_hash_table_new (thrift_gboolean_hash, thrift_gboolean_equal);";
       case t_base_type::TYPE_BYTE:
-        return "g_hash_table_new (thrift_gint8_hash, thrift_gint8_equal);";
       case t_base_type::TYPE_I16:
-        return "g_hash_table_new (thrift_gint16_hash, thrift_gint16_equal);";
       case t_base_type::TYPE_I32:
-        return "g_hash_table_new (thrift_gint32_hash, thrift_gint32_equal);";
       case t_base_type::TYPE_I64:
-        return "g_hash_table_new (thrift_gint64_hash, thrift_gint64_equal);";
       case t_base_type::TYPE_DOUBLE:
-        return "g_hash_table_new (thrift_gdouble_hash, thrift_gdouble_equal);";
+        return "NULL";
       case t_base_type::TYPE_STRING:
-        return "g_hash_table_new (g_str_hash, g_str_equal);";
+        return "g_free";
       default:
         throw "compiler error: no hash table info for type";
     }
-  }
-  return "g_hash_table_new (NULL, NULL);";
+  } else if (ttype->is_enum()) {
+    return "NULL";
+  } else if (ttype->is_map() || ttype->is_set()) {
+    return "(GDestroyNotify) g_hash_table_destroy";
+  } else if (ttype->is_struct()) {
+    return "g_object_unref";
+  } else if (ttype->is_list()) {
+    t_type *etype = ((t_list *) ttype)->get_elem_type();
+    if (etype->is_base_type()) {
+      t_base_type::t_base tbase = ((t_base_type *) etype)->get_base();
+      switch (tbase) {
+        case t_base_type::TYPE_VOID:
+          throw "compiler error: cannot determine array type";
+          break;
+        case t_base_type::TYPE_BOOL:
+        case t_base_type::TYPE_BYTE:
+        case t_base_type::TYPE_I16:
+        case t_base_type::TYPE_I32:
+        case t_base_type::TYPE_I64:
+        case t_base_type::TYPE_DOUBLE:
+          return "(GDestroyNotify) g_array_unref";
+        case t_base_type::TYPE_STRING:
+          return "(GDestroyNotify) g_ptr_array_unref";
+        default:
+          throw "compiler error: no array info for type";
+      }
+    } else if (etype->is_container() || etype->is_struct()) {
+      return "(GDestroyNotify) g_ptr_array_unref";;
+    } else if (etype->is_enum()) {
+      return "(GDestroyNotify) g_array_unref";
+    }
+    printf("Type not expected inside the array: %s\n", etype->get_name().c_str());
+    throw "Type not expected inside array" ;
+  } else if (ttype->is_typedef()) {
+    return generate_free_func_from_type(((t_typedef *) ttype)->get_type());
+  }
+  printf("Type not expected: %s\n", ttype->get_name().c_str());
+  throw "Type not expected";
+}
+
+string t_c_glib_generator::generate_hash_func_from_type (t_type * ttype) {
+  if (ttype == NULL)
+    return "NULL";
+
+  if (ttype->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type *) ttype)->get_base();
+    switch (tbase) {
+      case t_base_type::TYPE_VOID:
+        throw "compiler error: cannot determine hash type";
+        break;
+      case t_base_type::TYPE_BOOL:
+      case t_base_type::TYPE_BYTE:
+      case t_base_type::TYPE_I16:
+      case t_base_type::TYPE_I32:
+        return "g_int_hash";
+      case t_base_type::TYPE_I64:
+        return "g_int64_hash";
+      case t_base_type::TYPE_DOUBLE:
+        return "g_double_hash";
+      case t_base_type::TYPE_STRING:
+        return "g_str_hash";
+      default:
+        throw "compiler error: no hash table info for type";
+    }
+  } else if (ttype->is_enum()) {
+    return "g_direct_hash";
+  } else if (ttype->is_container() || ttype->is_struct()) {
+    return "g_direct_hash";
+  } else if (ttype->is_typedef()) {
+    return generate_hash_func_from_type(((t_typedef *) ttype)->get_type());
+  }
+  printf("Type not expected: %s\n", ttype->get_name().c_str());
+  throw "Type not expected";
+}
+
+string t_c_glib_generator::generate_cmp_func_from_type (t_type * ttype) {
+  if (ttype == NULL)
+    return "NULL";
+
+  if (ttype->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type *) ttype)->get_base();
+    switch (tbase) {
+      case t_base_type::TYPE_VOID:
+        throw "compiler error: cannot determine hash type";
+        break;
+      case t_base_type::TYPE_BOOL:
+      case t_base_type::TYPE_BYTE:
+      case t_base_type::TYPE_I16:
+      case t_base_type::TYPE_I32:
+        return "g_int_equal";
+      case t_base_type::TYPE_I64:
+        return "g_int64_equal";
+      case t_base_type::TYPE_DOUBLE:
+        return "g_double_equal";
+      case t_base_type::TYPE_STRING:
+        return "g_str_equal";
+      default:
+        throw "compiler error: no hash table info for type";
+    }
+  } else if (ttype->is_enum()) {
+    return "NULL";
+  } else if (ttype->is_container() || ttype->is_struct()) {
+    return "g_direct_equal";
+  } else if (ttype->is_typedef()) {
+    return generate_cmp_func_from_type(((t_typedef *) ttype)->get_type());
+  }
+  printf("Type not expected: %s\n", ttype->get_name().c_str());
+  throw "Type not expected";
+}
+
+string t_c_glib_generator::generate_new_hash_from_type (t_type * key, t_type *value) {
+  string hash_func = generate_hash_func_from_type(key);
+  string cmp_func = generate_cmp_func_from_type(key);
+  string key_free_func = generate_free_func_from_type(key);
+  string value_free_func = generate_free_func_from_type(value);
+
+  return "g_hash_table_new_full (" + hash_func + ", " + cmp_func + ", " +
+                              key_free_func + ", " + value_free_func + ");";
 }
 
 string t_c_glib_generator::generate_new_array_from_type(t_type * ttype) {
@@ -2775,11 +2987,17 @@ string t_c_glib_generator::generate_new_
       case t_base_type::TYPE_DOUBLE:
         return "g_array_new (0, 1, sizeof (gdouble));";
       case t_base_type::TYPE_STRING:
-        return "g_ptr_array_new();";
+        return "g_ptr_array_new_with_free_func (g_free);";
       default:
         throw "compiler error: no array info for type";
     }
+  } else if (ttype->is_enum()) {
+    return "g_array_new (0, 1, sizeof (gint32));";
+  } else {
+    string free_func = generate_free_func_from_type(ttype);
+    return "g_ptr_array_new_with_free_func (" + free_func + ");";
   }
+
   return "g_ptr_array_new();";
 }
 

Modified: thrift/trunk/lib/c_glib/test/testbinaryprotocol.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testbinaryprotocol.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testbinaryprotocol.c (original)
+++ thrift/trunk/lib/c_glib/test/testbinaryprotocol.c Sat Apr 28 11:33:58 2012
@@ -71,7 +71,7 @@ my_thrift_transport_write (ThriftTranspo
 
 #define thrift_transport_read my_thrift_transport_read
 #define thrift_transport_write my_thrift_transport_write
-#include "../src/protocol/thrift_binary_protocol.c"
+#include "../src/thrift/protocol/thrift_binary_protocol.c"
 #undef thrift_transport_read
 #undef thrift_transport_write
 

Modified: thrift/trunk/lib/c_glib/test/testbufferedtransport.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testbufferedtransport.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testbufferedtransport.c (original)
+++ thrift/trunk/lib/c_glib/test/testbufferedtransport.c Sat Apr 28 11:33:58 2012
@@ -27,7 +27,7 @@
 
 #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
 
-#include "../src/transport/thrift_buffered_transport.c"
+#include "../src/thrift/transport/thrift_buffered_transport.c"
 
 static const char TEST_ADDRESS[] = "localhost";
 static const short TEST_PORT = 64444;

Modified: thrift/trunk/lib/c_glib/test/testdebugproto.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testdebugproto.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testdebugproto.c (original)
+++ thrift/trunk/lib/c_glib/test/testdebugproto.c Sat Apr 28 11:33:58 2012
@@ -32,6 +32,8 @@ test_debug_proto(void)
   TTestOneOfEach *ooe = NULL;
   TTestNesting *n = NULL;
   TTestHolyMoley *hm = NULL;
+  gchar *random = g_strdup("random string");
+  gchar *nothing = g_strdup("nothing");
 
   ooe = g_object_new (T_TEST_TYPE_ONE_OF_EACH, NULL);
   ooe->im_true = TRUE;
@@ -41,38 +43,37 @@ test_debug_proto(void)
   ooe->integer32 = 1<<24;
   ooe->integer64 = (guint64) 6000 * 1000 * 1000;
   ooe->double_precision = M_PI;
-  ooe->some_characters = "Debug THIS!";
-  ooe->zomg_unicode = "\xd7\n\a\t";
+  ooe->some_characters = g_strdup("Debug THIS!");
+  ooe->zomg_unicode = g_strdup("\xd7\n\a\t");
 
   n = g_object_new (T_TEST_TYPE_NESTING, NULL);
+  if (n->my_ooe != NULL)
+    g_object_unref(n->my_ooe);
+
   n->my_ooe = ooe;
   n->my_ooe->integer16 = 16;
   n->my_ooe->integer32 = 32;
   n->my_ooe->integer64 = 64;
   n->my_ooe->double_precision = (sqrt(5.0) + 1) / 2;
-  n->my_ooe->some_characters = ":R (me going \"rrrr\")";
-  n->my_ooe->zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20";
+  n->my_ooe->some_characters = g_strdup(":R (me going \"rrrr\")");
+  n->my_ooe->zomg_unicode = g_strdup("\xd3\x80\xe2\x85\xae\xce\x9d\x20");
   n->my_bonk->type = 31337;
-  n->my_bonk->message = "I am a bonk... xor!";
+  n->my_bonk->message = g_strdup("I am a bonk... xor!");
 
   hm = g_object_new (T_TEST_TYPE_HOLY_MOLEY, NULL);
   g_ptr_array_add (hm->big, ooe);
-  g_ptr_array_add (hm->big, n->my_ooe);
+  g_ptr_array_add (hm->big, g_object_ref(n->my_ooe));
   ((TTestOneOfEach *) g_ptr_array_index (hm->big, 0))->a_bite = 0x22;
   ((TTestOneOfEach *) g_ptr_array_index (hm->big, 1))->a_bite = 0x33;
 
-  g_hash_table_insert (hm->contain, "random string", "random string");
+  g_hash_table_insert (hm->contain, random, random);
 
   TTestBonk *bonk = NULL;
   bonk = g_object_new (T_TEST_TYPE_BONK, NULL);
-  GPtrArray *bonks = g_ptr_array_new ();
+  GPtrArray *bonks = g_ptr_array_new_with_free_func (g_object_unref);
   g_ptr_array_add (bonks, bonk);
-  g_hash_table_insert (hm->bonks, "nothing", bonks);
+  g_hash_table_insert (hm->bonks, nothing, bonks);
 
-  g_ptr_array_free (bonks, TRUE);
-  g_object_unref (bonk);
-  g_object_unref (ooe);
-  g_object_unref (n);
   g_object_unref (hm);
 
   return 0;

Modified: thrift/trunk/lib/c_glib/test/testframedtransport.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testframedtransport.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testframedtransport.c (original)
+++ thrift/trunk/lib/c_glib/test/testframedtransport.c Sat Apr 28 11:33:58 2012
@@ -27,7 +27,7 @@
 
 #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
 
-#include "../src/transport/thrift_framed_transport.c"
+#include "../src/thrift/transport/thrift_framed_transport.c"
 
 static const char TEST_ADDRESS[] = "localhost";
 static const short TEST_PORT = 64444;
@@ -150,7 +150,7 @@ thrift_server (const int port)
   int bytes = 0;
   ThriftServerTransport *transport = NULL;
   ThriftTransport *client = NULL;
-  guchar buf[10]; /* a buffer */
+  guchar buf[12]; /* a buffer */
   guchar match[10] = TEST_DATA;
 
   ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,

Modified: thrift/trunk/lib/c_glib/test/testmemorybuffer.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testmemorybuffer.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testmemorybuffer.c (original)
+++ thrift/trunk/lib/c_glib/test/testmemorybuffer.c Sat Apr 28 11:33:58 2012
@@ -27,7 +27,7 @@
 
 #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
 
-#include "../src/transport/thrift_memory_buffer.c"
+#include "../src/thrift/transport/thrift_memory_buffer.c"
 
 /* test object creation and destruction */
 static void

Modified: thrift/trunk/lib/c_glib/test/testoptionalrequired.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testoptionalrequired.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testoptionalrequired.c (original)
+++ thrift/trunk/lib/c_glib/test/testoptionalrequired.c Sat Apr 28 11:33:58 2012
@@ -20,7 +20,7 @@
 #include <assert.h>
 #include <glib.h>
 
-#include "thrift_struct.h"
+#include <thrift/thrift_struct.h>
 #include <thrift/protocol/thrift_protocol.h>
 #include <thrift/protocol/thrift_binary_protocol.h>
 #include <thrift/transport/thrift_memory_buffer.h>
@@ -55,8 +55,10 @@ test_old_school1 (void)
   o->im_int = 10;
   o->im_str = g_strdup ("test");
   o->im_big = g_ptr_array_new ();
-  g_ptr_array_free (o->im_big, FALSE);
+  g_ptr_array_free (o->im_big, TRUE);
+  o->im_big = NULL;
   g_free (o->im_str);
+  o->im_str = NULL;
   g_object_unref (o);
 }
 

Modified: thrift/trunk/lib/c_glib/test/teststruct.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/teststruct.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/teststruct.c (original)
+++ thrift/trunk/lib/c_glib/test/teststruct.c Sat Apr 28 11:33:58 2012
@@ -20,7 +20,7 @@
 #include <assert.h>
 #include <glib-object.h>
 
-#include "../src/thrift_struct.c"
+#include "../src/thrift/thrift_struct.c"
 
 /* tests to ensure we can extend a ThriftStruct */
 

Modified: thrift/trunk/lib/c_glib/test/testthrifttestclient.cpp
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testthrifttestclient.cpp?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testthrifttestclient.cpp (original)
+++ thrift/trunk/lib/c_glib/test/testthrifttestclient.cpp Sat Apr 28 11:33:58 2012
@@ -396,23 +396,25 @@ test_thrift_client (void)
   xtruct_out->__isset_i64_thing = TRUE;
   xtruct_out->string_thing = g_strdup ("abc123");
   xtruct_out->__isset_string_thing = TRUE;
+  xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, NULL);
   assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE);
   assert (error == NULL);
 
   xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
   xtruct2_out->byte_thing = 1;
   xtruct2_out->__isset_byte_thing = TRUE;
+  if (xtruct2_out->struct_thing != NULL)
+    g_object_unref(xtruct2_out->struct_thing);
   xtruct2_out->struct_thing = xtruct_out;
   xtruct2_out->__isset_struct_thing = TRUE;
   xtruct2_out->i32_thing = 123;
   xtruct2_out->__isset_i32_thing = TRUE;
+  xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
   assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE);
   assert (error == NULL);
 
   g_object_unref (xtruct2_out);
   g_object_unref (xtruct2_in);
-  g_free (xtruct_out->string_thing);
-  g_object_unref (xtruct_out);
   g_object_unref (xtruct_in);
 
   map_out = g_hash_table_new (NULL, NULL);
@@ -490,7 +492,6 @@ test_thrift_client (void)
   xtruct2->string_thing = g_strdup ("abc123");
   xtruct2->__isset_string_thing = TRUE;
 
-  insanity_out->xtructs = g_ptr_array_new ();
   insanity_in = g_hash_table_new (NULL, NULL);
   g_ptr_array_add (insanity_out->xtructs, xtruct1);
   g_ptr_array_add (insanity_out->xtructs, xtruct2);
@@ -498,25 +499,24 @@ test_thrift_client (void)
 
   g_hash_table_unref (insanity_in);
   g_ptr_array_free (insanity_out->xtructs, TRUE);
-  g_free (xtruct1->string_thing);
-  g_free (xtruct2->string_thing);
-  g_object_unref (xtruct1);
-  g_object_unref (xtruct2);
 
   multi_map_out = g_hash_table_new (NULL, NULL);
   string = g_strdup ("abc123");
   g_hash_table_insert (multi_map_out, &i16, string);
+  multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
   assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE);
   assert (multi_in->i32_thing == i32);
   assert (multi_in->i64_thing == i64);
   g_object_unref (multi_in);
   g_hash_table_unref (multi_map_out);
-  g_free (string); 
+  g_free (string);
 
   assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE);
   assert (xception->errorCode == 1001);
   g_error_free (error);
   error = NULL;
+  g_object_unref (xception);
+  xception = NULL;
 
   assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE);
   g_error_free (error);
@@ -527,23 +527,33 @@ test_thrift_client (void)
   assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE);
   assert (error == NULL);
 
+  multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
   assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", NULL, &xception, &xception2, &error) == FALSE);
   assert (xception->errorCode == 1001);
+  assert (xception2 == NULL);
   g_error_free (error);
   error = NULL;
   g_object_unref (xception);
+  g_object_unref (multi_in);
   xception = NULL;
-  xception2 = NULL;
+  multi_in = NULL;
 
+  multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
   assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", NULL, &xception, &xception2, &error) == FALSE);
   assert (xception2->errorCode == 2002);
+  assert (xception == NULL);
   g_error_free (error);
   error = NULL;
   g_object_unref (xception2);
+  g_object_unref (multi_in);
   xception2 = NULL;
+  multi_in = NULL;
 
+  multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
   assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, NULL , NULL, &xception, &xception2, &error) == TRUE);
   assert (error == NULL);
+  g_object_unref(multi_in);
+  multi_in = NULL;
 
   assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE);
   assert (error == NULL);

Modified: thrift/trunk/lib/c_glib/test/testtransportsocket.c
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/c_glib/test/testtransportsocket.c?rev=1331752&r1=1331751&r2=1331752&view=diff
==============================================================================
--- thrift/trunk/lib/c_glib/test/testtransportsocket.c (original)
+++ thrift/trunk/lib/c_glib/test/testtransportsocket.c Sat Apr 28 11:33:58 2012
@@ -63,7 +63,7 @@ my_send(int socket, const void *buffer, 
 #define socket my_socket
 #define recv my_recv
 #define send my_send
-#include "../src/transport/thrift_socket.c"
+#include "../src/thrift/transport/thrift_socket.c"
 #undef socket
 #undef recv
 #undef send