Xcos: remove MVC object leaks on importXcosDiagram() 03/18203/3
Clément DAVID [Tue, 31 May 2016 17:09:16 +0000 (19:09 +0200)]
Change-Id: Iff7f0536ac4a9e8706edb3dfe28e300ba73037e5

scilab/modules/scicos/tests/unit_tests/model/Block_copy_list.dia.ref
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/ScicosObjectOwner.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/model/XcosCell.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/PortHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/XcosSAXHandler.java
scilab/modules/xcos/tests/unit_tests/mvc_memleaks.dia.ref [new file with mode: 0644]
scilab/modules/xcos/tests/unit_tests/mvc_memleaks.tst [new file with mode: 0644]

index 126d222..5a33329 100644 (file)
@@ -114,7 +114,7 @@ Xcos debug: objectUnreferenced( 1 , BLOCK ) : 0
 clear Sum
 // Sum2's refCount must have been affected by "clear Sum"
 Sum2
- Sum2  = (2)
+ Sum2  = 
 GUI     : BIGSOM_f
 Graphics: 
 Xcos debug: objectReferenced( 1 , BLOCK ) : 1
index b29e2d1..350329b 100644 (file)
@@ -18,6 +18,9 @@ package org.scilab.modules.xcos.graph.model;
 import org.scilab.modules.xcos.JavaController;
 import org.scilab.modules.xcos.Kind;
 
+/**
+ * Helper class to own a Scicos MVC object from the Java world.
+ */
 public class ScicosObjectOwner {
     final long uid;
     final Kind kind;
@@ -54,6 +57,7 @@ public class ScicosObjectOwner {
     @Override
     protected void finalize() throws Throwable {
         JavaController controller = new JavaController();
+
         controller.deleteObject(uid);
     }
 }
\ No newline at end of file
index 5b17a9d..ac9149f 100644 (file)
@@ -31,6 +31,15 @@ import com.mxgraph.model.mxICell;
 import com.mxgraph.util.mxPoint;
 import java.util.regex.Pattern;
 
+/**
+ * An Xcos cell is a JGraphX cell that store most of its information into the
+ * Scicos MVC.
+ *
+ * The reference to the Scicos MVC object is taken at construction time and
+ * released by the destructor. There is thus no need to manage parent /
+ * children, block / port or port / link association referencing as the JVM will
+ * GC the object if needed.
+ */
 public class XcosCell extends mxCell {
     private static final long serialVersionUID = 1L;
     private static Pattern validCIdentifier = Pattern.compile("[a-zA-Z][a-zA-Z0-9_]+");
@@ -40,8 +49,6 @@ public class XcosCell extends mxCell {
     /**
      * Construct an Xcos graphical object.
      *
-     * This Java object owns the corresponding MVC object and thus will unrefererence it on GC.
-     *
      * @param controller
      *            the shared controller
      * @param uid
@@ -107,7 +114,7 @@ public class XcosCell extends mxCell {
                 if (validCIdentifier.matcher(String.valueOf(value)).matches()) {
                     controller.setObjectProperty(getUID(), getKind(), ObjectProperties.LABEL, String.valueOf(value));
                 }
-                // no break on purpose
+            // no break on purpose
             case ANNOTATION:
                 controller.setObjectProperty(getUID(), getKind(), ObjectProperties.DESCRIPTION, String.valueOf(value));
                 break;
@@ -456,9 +463,6 @@ public class XcosCell extends mxCell {
                 default:
                     break;
             }
-
-            JavaController controller = new JavaController();
-            controller.referenceObject(c.getUID());
         }
 
         return inserted;
@@ -515,9 +519,6 @@ public class XcosCell extends mxCell {
                 default:
                     break;
             }
-
-            JavaController controller = new JavaController();
-            controller.deleteObject(c.getUID());
         }
         return removed;
     }
@@ -559,7 +560,6 @@ public class XcosCell extends mxCell {
         controller.getObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
         children.remove(c.getUID());
         controller.setObjectProperty(getUID(), getKind(), ObjectProperties.CHILDREN, children);
-
     }
 
     /*
index 4a2bc9a..b25598f 100644 (file)
@@ -173,7 +173,6 @@ class PortHandler implements ScilabHandler {
 
                 associatedPorts.resize(Math.max(associatedPorts.size(), ordering + 1));
                 associatedPorts.set(ordering, uid);
-                shared.controller.referenceObject(uid);
 
                 shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.SOURCE_BLOCK, parent);
                 shared.controller.setObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
index f93826a..67b1e40 100644 (file)
@@ -207,7 +207,6 @@ public class XcosSAXHandler extends DefaultHandler {
         controller.getObjectProperty(parentUID, parentKind, ObjectProperties.CHILDREN, children);
 
         children.add(cell.getUID());
-        controller.referenceObject(cell.getUID());
 
         controller.setObjectProperty(parentUID, parentKind, ObjectProperties.CHILDREN, children);
     }
diff --git a/scilab/modules/xcos/tests/unit_tests/mvc_memleaks.dia.ref b/scilab/modules/xcos/tests/unit_tests/mvc_memleaks.dia.ref
new file mode 100644 (file)
index 0000000..3242460
--- /dev/null
@@ -0,0 +1,64 @@
+// ============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Scilab Enterprises - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// ============================================================================
+// <-- TEST WITH GRAPHIC -->
+// <-- LINUX ONLY -->
+//
+// <-- Short Description -->
+// Check that a diagram import and a simulation does not leak MVC objects.
+// helper function to generate a MVC log of a script
+function logfile = generatelog(script)
+    mputl( ["loadXcosLibs();"
+    "jimport java.lang.System;"
+    ""
+    "scicos_log(""DEBUG"");"
+    ""
+    script
+    ""
+    "System.gc();"
+    "clear scs_m;"], "memleaks.sce");
+    cmd = SCI+"/bin/scilab -nw <memleaks.sce &>memleaks.sce.log"
+    host(cmd);
+    logfile = "memleaks.sce.log";
+    deletefile("memleaks.sce");
+endfunction
+// helper function to parse the MVC log and extract leaks
+function leaks = parselog(logfile)
+    leaks = [];
+    fd = mopen(logfile, "r");
+    if fd < 0 then bugmes();quit;end
+    line = mgetl(fd, 1);
+    while line <> [] do
+        t = tokens(line);
+        if and(size(t) == [9 1]) & and(t(1:2) == ["Xcos";"debug:"]) then
+            if t(3) == "objectUnreferenced(" then
+                increment = -1;
+            elseif t(3) == "objectReferenced(" then
+                increment = +1;
+            else
+                increment = 0;
+            end
+            uid = msscanf(t(4), "%d");
+            if size(leaks, "*") < uid then
+                leaks(uid) = 0;
+            end
+            leaks(uid) = leaks(uid) + increment;
+        end
+        line = mgetl(fd, 1);
+    end
+    mclose(fd);
+endfunction
+logfile = generatelog("importXcosDiagram(SCI+""/modules/xcos/demos/Discrete-KalmanFilter.zcos"");");
+leaks = parselog(logfile);
+find(leaks)
+ ans  =
+    []
+logfile = generatelog( ["importXcosDiagram(SCI+""/modules/xcos/demos/Discrete-KalmanFilter.zcos"");"
+"xcos_simulate(scs_m);"]);
+leaks = parselog(logfile);
+find(leaks)
+ ans  =
+    []
diff --git a/scilab/modules/xcos/tests/unit_tests/mvc_memleaks.tst b/scilab/modules/xcos/tests/unit_tests/mvc_memleaks.tst
new file mode 100644 (file)
index 0000000..f6f26c9
--- /dev/null
@@ -0,0 +1,72 @@
+// ============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Scilab Enterprises - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// ============================================================================
+
+// <-- TEST WITH GRAPHIC -->
+// <-- LINUX ONLY -->
+//
+// <-- Short Description -->
+// Check that a diagram import and a simulation does not leak MVC objects.
+
+// helper function to generate a MVC log of a script
+function logfile = generatelog(script)
+    mputl( ["loadXcosLibs();"
+    "jimport java.lang.System;"
+    ""
+    "scicos_log(""DEBUG"");"
+    ""
+    script
+    ""
+    "System.gc();"
+    "clear scs_m;"], "memleaks.sce");
+
+    cmd = SCI+"/bin/scilab -nw <memleaks.sce &>memleaks.sce.log"
+    host(cmd);
+
+    logfile = "memleaks.sce.log";
+
+    deletefile("memleaks.sce");
+endfunction
+
+// helper function to parse the MVC log and extract leaks
+function leaks = parselog(logfile)
+    leaks = [];
+
+    fd = mopen(logfile, "r");
+    if fd < 0 then pause, end
+
+    line = mgetl(fd, 1);
+    while line <> [] do
+        t = tokens(line);
+        if and(size(t) == [9 1]) & and(t(1:2) == ["Xcos";"debug:"]) then
+            if t(3) == "objectUnreferenced(" then
+                increment = -1;
+            elseif t(3) == "objectReferenced(" then
+                increment = +1;
+            else
+                increment = 0;
+            end
+            uid = msscanf(t(4), "%d");
+
+            if size(leaks, "*") < uid then
+                leaks(uid) = 0;
+            end
+            leaks(uid) = leaks(uid) + increment;
+        end
+
+        line = mgetl(fd, 1);
+    end
+    mclose(fd);
+endfunction
+
+logfile = generatelog("importXcosDiagram(SCI+""/modules/xcos/demos/Discrete-KalmanFilter.zcos"");");
+leaks = parselog(logfile);
+find(leaks)
+
+logfile = generatelog( ["importXcosDiagram(SCI+""/modules/xcos/demos/Discrete-KalmanFilter.zcos"");"
+"xcos_simulate(scs_m);"]);
+leaks = parselog(logfile);
+find(leaks)