[Xorp-cvs] SF.net SVN: xorp:[11597] trunk/xorp/xrl/scripts/clnt-gen

bms_fbsd at users.sourceforge.net bms_fbsd at users.sourceforge.net
Thu Nov 26 18:56:41 PST 2009


Revision: 11597
          http://xorp.svn.sourceforge.net/xorp/?rev=11597&view=rev
Author:   bms_fbsd
Date:     2009-11-27 02:56:41 +0000 (Fri, 27 Nov 2009)

Log Message:
-----------
Fix memory leak and non-reentrant behaviour in the XRL client stubs.
The fix is applied to the code generator.

Previously, individual Xrls for each client method were cached
using a static pointer to the class Xrl instance. This meant that the
allocated memory could not be reclaimed, and the code was non-reentrant.

Allocation is now made through an auto_ptr<Xrl*> private to the
client stub class. If the client stub class is re-instantiated repeatedly,
this may cause allocator churn.
In practice, most XORP code instantiates a client only when it needs
to make a call; this may need to be revisited.

'scons check' runs without error on FreeBSD 7.2-STABLE/amd64.

With: find obj/*/xrl/interfaces -name '*.so' | xargs size -t
+54K code size on amd64 with optimize=no.
+41K code size on amd64 with optimize=yes.

Modified Paths:
--------------
    trunk/xorp/xrl/scripts/clnt-gen

Modified: trunk/xorp/xrl/scripts/clnt-gen
===================================================================
--- trunk/xorp/xrl/scripts/clnt-gen	2009-11-27 02:28:48 UTC (rev 11596)
+++ trunk/xorp/xrl/scripts/clnt-gen	2009-11-27 02:56:41 UTC (rev 11597)
@@ -57,6 +57,7 @@
 
 def implement_send_xrl(cls, method_no, method, ifqname):
     cb_name = "%sCB" % (caps_cpp_classname(method.name()))
+    xrl_ptr_name = "ap_xrl_%s" % method.name()
     atypes = ["\n\tconst char*\tdst_xrl_target_name"]
     for a in method.args():
         atypes.append("\n\tconst %s&\t%s" % (a.cpp_type(), a.name()))
@@ -64,12 +65,13 @@
     s = "\nbool\n%s::send_%s(%s\n)\n{\n" \
         % (cls, cpp_name(method.name()), csv(atypes))
 
-    s += "    static Xrl* x = NULL;\n"
+    s += "    Xrl* x = %s.get();\n" % xrl_ptr_name
     s += "\n"
     s += "    if (!x) {\n"
     s += "        x = new Xrl(dst_xrl_target_name, \"%s\");\n" % ifqname
     for a in method.args():
         s += "        x->args().add(\"%s\", %s);\n" % (a.name(), a.name())
+    s += "        %s.reset(x);\n" % xrl_ptr_name
     s += "    }\n"
     s += "\n"
     s += "    x->set_target(dst_xrl_target_name);\n"
@@ -95,6 +97,11 @@
     s += "\n%s);\n\n" % xorp_indent(1)
     return s
 
+def declare_xrl_auto_ptr(method_name):
+    xrl_ptr_name = "ap_xrl_%s" % method_name
+    s = xorp_indent(1) + "auto_ptr<Xrl> %s;\n" % xrl_ptr_name
+    return s
+
 def implement_unmarshall(cls, method_no, method):
 
     nargs = []
@@ -163,6 +170,7 @@
 #include "libxipc/xrl_error.hh"
 #include "libxipc/xrl_sender.hh"
 
+#include <memory>
 """ % (protect(hh_file), protect(hh_file), modulename)
     return s
 
@@ -184,6 +192,12 @@
 """
     for i in range(0, len(methods)):
         s += declare_unmarshall(methods[i].name())
+
+    s += "private:\n"
+    s += "    /* Declare cached Xrl pointers */\n"
+    for i in range(0, len(methods)):
+        s += declare_xrl_auto_ptr(methods[i].name())
+
     s += "};\n"
 
     return s


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Xorp-cvs mailing list