[Jython-checkins] jython: JyNI-related work on GC-support.

stefan.richthofer jython-checkins at python.org
Sun Sep 27 21:45:39 CEST 2015


https://hg.python.org/jython/rev/a32410e8df69
changeset:   7736:a32410e8df69
user:        Stefan Richthofer <stefan.richthofer at gmx.de>
date:        Sun Sep 27 21:45:18 2015 +0200
summary:
  JyNI-related work on GC-support.

files:
  src/org/python/core/finalization/FinalizablePyObject.java |   2 -
  src/org/python/modules/_weakref/GlobalRef.java            |   5 +-
  src/org/python/modules/gc.java                            |  54 ++++++++-
  3 files changed, 48 insertions(+), 13 deletions(-)


diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java
--- a/src/org/python/core/finalization/FinalizablePyObject.java
+++ b/src/org/python/core/finalization/FinalizablePyObject.java
@@ -1,7 +1,5 @@
 package org.python.core.finalization;
 
-import org.python.core.JyAttribute;
-
 /**
  * <p>
  * This interface allows {@code PyObject}s to have finalizers.
diff --git a/src/org/python/modules/_weakref/GlobalRef.java b/src/org/python/modules/_weakref/GlobalRef.java
--- a/src/org/python/modules/_weakref/GlobalRef.java
+++ b/src/org/python/modules/_weakref/GlobalRef.java
@@ -63,6 +63,9 @@
     private static ConcurrentMap<GlobalRef, ReferenceBackend> objects = Generic.concurrentMap();
     private static List<GlobalRef> delayedCallbacks;
 
+    /*
+     * Consider to make this protected, so use of newInstance is enforced.
+     */
     public GlobalRef(PyObject object) {
         super(object, referenceQueue);
         hashCode = System.identityHashCode(object);
@@ -247,7 +250,7 @@
                 objects.put(newRef,  ref);
                 JyAttribute.setAttr(object, JyAttribute.WEAK_REF_ATTR, ref);
             } else {
-                // We clear the not-needed Global ref so that it won't
+                // We clear the not-needed GlobalRef so that it won't
                 // pop up in ref-reaper thread's activity.
                 newRef.clear();
                 newRef.cleared = true;
diff --git a/src/org/python/modules/gc.java b/src/org/python/modules/gc.java
--- a/src/org/python/modules/gc.java
+++ b/src/org/python/modules/gc.java
@@ -1093,15 +1093,16 @@
                 DelayedFinalizationProcess.defaultInstance) != -1) {
             suspendDelayedFinalization();
         }
-        if (delayedWeakrefCallbacksEnabled()) {
-            if (GlobalRef.hasDelayedCallbacks()) {
-                Thread dlcProcess = new Thread() {
-                    public void run() {
-                        GlobalRef.processDelayedCallbacks();
-                    }
-                };
-                dlcProcess.start();
-            }
+        if (!delayedWeakrefCallbacksEnabled() &&
+                GlobalRef.hasDelayedCallbacks()) {
+            // If delayed callbacks were turned off, we process remaining
+            // queued callbacks immediately (but in a new thread though):
+            Thread dlcProcess = new Thread() {
+                public void run() {
+                    GlobalRef.processDelayedCallbacks();
+                }
+            };
+            dlcProcess.start();
         }
     }
 
@@ -1394,8 +1395,41 @@
     }
 
     public static void notifyPreFinalization() {
+        long callTime = System.currentTimeMillis();
+/*
+ * This section is experimental and kept for further investigation. In theory, it can
+ * prevent potential problems in JyNI-gc, if a gc-run overlaps the previous run's
+ * post-finalization phase. However it currently breaks gc-tests, so is out-commented
+ * so far. In practical sense, JyNI's gc-support also works fine without it so far.
+ */
+//        if (postFinalizationPending) {
+//            if ((gcFlags & VERBOSE_COLLECT) != 0) {
+//                writeDebug("gc", "waiting for pending post-finalization process.");
+//            }
+//            /* It is important to have the while (which is actually an "if" since the
+//             * InterruptedException is very unlikely to occur) *inside* the synchronized
+//             * block. Otherwise the notification might come just between the check and the wait,
+//             * causing an endless waiting. This is no pure academic consideration, but was
+//             * actually observed to happen from time to time, especially on faster systems.
+//             */
+//            synchronized(PostFinalizationProcessor.class) {
+//                while (postFinalizationPending) {
+//                    try {
+//                        PostFinalizationProcessor.class.wait();
+//                    } catch (InterruptedException ie3) {}
+//                }
+//            }
+//            if ((gcFlags & VERBOSE_COLLECT) != 0) {
+//                writeDebug("gc", "post-finalization finished.");
+//            }
+//        }
+//        /*
+//         * Increment of openFinalizeCount must not happen before waiting for pending
+//         * post-finalization process is done. Otherwise PostFinalizationProcessor can
+//         * be waiting for a neutral openFinalizeCount, causing a deadlock.
+//         */
         ++openFinalizeCount;
-        if (System.currentTimeMillis() - postFinalizationTimestamp
+        if (callTime - postFinalizationTimestamp
                 < postFinalizationTimeOut) {
             return;
         }

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list