Skip to content

Commit 7fc73ef

Browse files
committed
JyNI-related work on GC-support.
1 parent 19933e2 commit 7fc73ef

3 files changed

Lines changed: 48 additions & 13 deletions

File tree

src/org/python/core/finalization/FinalizablePyObject.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.python.core.finalization;
22

3-
import org.python.core.JyAttribute;
4-
53
/**
64
* <p>
75
* This interface allows {@code PyObject}s to have finalizers.

src/org/python/modules/_weakref/GlobalRef.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ public class GlobalRef extends WeakReference<PyObject> implements ReferenceBacke
6363
private static ConcurrentMap<GlobalRef, ReferenceBackend> objects = Generic.concurrentMap();
6464
private static List<GlobalRef> delayedCallbacks;
6565

66+
/*
67+
* Consider to make this protected, so use of newInstance is enforced.
68+
*/
6669
public GlobalRef(PyObject object) {
6770
super(object, referenceQueue);
6871
hashCode = System.identityHashCode(object);
@@ -247,7 +250,7 @@ public static ReferenceBackend newInstance(PyObject object) {
247250
objects.put(newRef, ref);
248251
JyAttribute.setAttr(object, JyAttribute.WEAK_REF_ATTR, ref);
249252
} else {
250-
// We clear the not-needed Global ref so that it won't
253+
// We clear the not-needed GlobalRef so that it won't
251254
// pop up in ref-reaper thread's activity.
252255
newRef.clear();
253256
newRef.cleared = true;

src/org/python/modules/gc.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,15 +1093,16 @@ private static void updateDelayedFinalizationState() {
10931093
DelayedFinalizationProcess.defaultInstance) != -1) {
10941094
suspendDelayedFinalization();
10951095
}
1096-
if (delayedWeakrefCallbacksEnabled()) {
1097-
if (GlobalRef.hasDelayedCallbacks()) {
1098-
Thread dlcProcess = new Thread() {
1099-
public void run() {
1100-
GlobalRef.processDelayedCallbacks();
1101-
}
1102-
};
1103-
dlcProcess.start();
1104-
}
1096+
if (!delayedWeakrefCallbacksEnabled() &&
1097+
GlobalRef.hasDelayedCallbacks()) {
1098+
// If delayed callbacks were turned off, we process remaining
1099+
// queued callbacks immediately (but in a new thread though):
1100+
Thread dlcProcess = new Thread() {
1101+
public void run() {
1102+
GlobalRef.processDelayedCallbacks();
1103+
}
1104+
};
1105+
dlcProcess.start();
11051106
}
11061107
}
11071108

@@ -1394,8 +1395,41 @@ public static void unregisterPostFinalizationProcessAfterNextRun(Runnable proces
13941395
}
13951396

13961397
public static void notifyPreFinalization() {
1398+
long callTime = System.currentTimeMillis();
1399+
/*
1400+
* This section is experimental and kept for further investigation. In theory, it can
1401+
* prevent potential problems in JyNI-gc, if a gc-run overlaps the previous run's
1402+
* post-finalization phase. However it currently breaks gc-tests, so is out-commented
1403+
* so far. In practical sense, JyNI's gc-support also works fine without it so far.
1404+
*/
1405+
// if (postFinalizationPending) {
1406+
// if ((gcFlags & VERBOSE_COLLECT) != 0) {
1407+
// writeDebug("gc", "waiting for pending post-finalization process.");
1408+
// }
1409+
// /* It is important to have the while (which is actually an "if" since the
1410+
// * InterruptedException is very unlikely to occur) *inside* the synchronized
1411+
// * block. Otherwise the notification might come just between the check and the wait,
1412+
// * causing an endless waiting. This is no pure academic consideration, but was
1413+
// * actually observed to happen from time to time, especially on faster systems.
1414+
// */
1415+
// synchronized(PostFinalizationProcessor.class) {
1416+
// while (postFinalizationPending) {
1417+
// try {
1418+
// PostFinalizationProcessor.class.wait();
1419+
// } catch (InterruptedException ie3) {}
1420+
// }
1421+
// }
1422+
// if ((gcFlags & VERBOSE_COLLECT) != 0) {
1423+
// writeDebug("gc", "post-finalization finished.");
1424+
// }
1425+
// }
1426+
// /*
1427+
// * Increment of openFinalizeCount must not happen before waiting for pending
1428+
// * post-finalization process is done. Otherwise PostFinalizationProcessor can
1429+
// * be waiting for a neutral openFinalizeCount, causing a deadlock.
1430+
// */
13971431
++openFinalizeCount;
1398-
if (System.currentTimeMillis() - postFinalizationTimestamp
1432+
if (callTime - postFinalizationTimestamp
13991433
< postFinalizationTimeOut) {
14001434
return;
14011435
}

0 commit comments

Comments
 (0)