Skip to content

Commit aeead7b

Browse files
committed
Added detailed javadoc to gc-module; fixed minor gc-issues and added
a test for third-party finalizers; implemented Traverseproc for zipimporter
1 parent df3a0b5 commit aeead7b

6 files changed

Lines changed: 534 additions & 118 deletions

File tree

Lib/test/test_gc.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,14 @@ def test_collect_generations(self):
313313
gc.collect(2)
314314
assertEqual(gc.get_count(), (0, 0, 0))
315315

316+
@unittest.skipIf(test_support.is_jython,
317+
'''
318+
While this test passes in Jython, it leads to internal
319+
allocation failures because of the massive referencing
320+
in this test. To keep the JVM-process healthy and to
321+
avoid subsequent failures due to bad conditions caused
322+
by this test, we skip it for now.
323+
''')
316324
def test_trashcan(self):
317325
class Ouch:
318326
n = 0

Lib/test/test_gc_jy.py

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,22 @@ def test_manual_monitoring(self):
113113
'CPython has no gc preprocess and postprocess features')
114114
class GCTests_Jy_preprocess_and_postprocess(unittest.TestCase):
115115

116+
@classmethod
117+
def setUpClass(cls):
118+
#Jython-specific block:
119+
try:
120+
cls.savedJythonGCFlags = gc.getJythonGCFlags()
121+
gc.setMonitorGlobal(True)
122+
except Exception:
123+
pass
124+
125+
@classmethod
126+
def tearDownClass(cls):
127+
try:
128+
gc.setJythonGCFlags(cls.savedJythonGCFlags)
129+
except Exception:
130+
pass
131+
116132
def test_finalization_preprocess_and_postprocess(self):
117133
#Note that this test is done here again (already was in another class
118134
#in this module), to see that everything works as it should also with
@@ -167,9 +183,6 @@ def run(self):
167183
gc.unregisterPostFinalizationProcess(postPr)
168184

169185
def test_with_extern_NonPyObjectFinalizer_that_notifies_gc(self):
170-
#Note that this test is done here again (already was in another class
171-
#in this module), to see that everything works as it should also with
172-
#a different flag-context.
173186
comments = []
174187
class A:
175188
def __init__(self, index):
@@ -238,6 +251,8 @@ def tearDownClass(cls):
238251
except Exception:
239252
pass
240253

254+
#Tests from GCTests_Jy_preprocess_and_postprocess are repeated here
255+
#without monitoring.
241256
def test_finalization_preprocess_and_postprocess(self):
242257
#Note that this test is done here again (already was in another class
243258
#in this module), to see that everything works as it should also with
@@ -290,8 +305,54 @@ def run(self):
290305
gc.unregisterPreFinalizationProcess(prePr)
291306
gc.unregisterPostFinalizationProcess(postPr)
292307

308+
def test_with_extern_NonPyObjectFinalizer_that_notifies_gc(self):
309+
comments = []
310+
class A:
311+
def __init__(self, index):
312+
self.index = index
313+
314+
def __del__(self):
315+
comments.append("A_del_"+str(self.index))
316+
317+
class PreProcess(Runnable):
318+
preCount = 0
319+
def run(self):
320+
PreProcess.preCount += 1
321+
322+
class PostProcess(Runnable):
323+
postCount = 0
324+
def run(self):
325+
PostProcess.postCount += 1
326+
327+
prePr = PreProcess()
328+
postPr = PostProcess()
329+
time.sleep(1) # <- to avoid that the newly registered processes
330+
# become subject to previous run (remember: We
331+
# are not in monitor-mode, i.e. gc runs async.
332+
gc.registerPreFinalizationProcess(prePr)
333+
gc.registerPostFinalizationProcess(postPr)
334+
for i in range(4):
335+
f = A(i)
336+
del f
337+
#NastyFinalizer would cause this test occasionally to fail
338+
externFinalizer = GCTestHelper.NotSoNastyFinalizer()
339+
del externFinalizer
340+
for i in range(4, 8):
341+
f = A(i)
342+
del f
343+
System.gc()
344+
#we wait a bit longer here, since PostProcess runs asynchronous
345+
#and must wait for the finalizer of A
346+
time.sleep(4)
347+
self.assertEqual(len(comments), 8)
348+
self.assertEqual(PreProcess.preCount, 1)
349+
self.assertEqual(PostProcess.postCount, 1)
350+
comments = []
351+
gc.unregisterPreFinalizationProcess(prePr)
352+
gc.unregisterPostFinalizationProcess(postPr)
293353

294354
def test_delayedFinalization(self):
355+
#time.sleep(2)
295356
resurrect = []
296357
comments = []
297358

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

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import org.python.core.PyObject;
44
import org.python.core.JyAttribute;
5-
import org.python.core.Py;
65
import org.python.core.PySystemState;
76
import org.python.modules.gc;
87

@@ -131,27 +130,27 @@ protected FinalizeTrigger(PyObject toFinalize) {
131130
}
132131

133132
protected boolean isCyclic() {
134-
gc.CycleMarkAttr cm = (gc.CycleMarkAttr)
135-
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
133+
gc.CycleMarkAttr cm = (gc.CycleMarkAttr)
134+
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
136135
if (cm != null && cm.isCyclic()) {
137136
return true;
138137
} else {
139138
gc.markCyclicObjects(toFinalize, (flags & NOT_FINALIZABLE_FLAG) == 0);
140139
cm = (gc.CycleMarkAttr)
141-
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
140+
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
142141
return cm != null && cm.isCyclic();
143142
}
144143
}
145144

146145
protected boolean isUncollectable() {
147-
gc.CycleMarkAttr cm = (gc.CycleMarkAttr)
148-
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
146+
gc.CycleMarkAttr cm = (gc.CycleMarkAttr)
147+
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
149148
if (cm != null && cm.isUncollectable()) {
150149
return true;
151150
} else {
152151
gc.markCyclicObjects(toFinalize, (flags & NOT_FINALIZABLE_FLAG) == 0);
153152
cm = (gc.CycleMarkAttr)
154-
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
153+
JyAttribute.getAttr(toFinalize, JyAttribute.GC_CYCLE_MARK_ATTR);
155154
return cm != null && cm.isUncollectable();
156155
}
157156
}
@@ -167,13 +166,13 @@ public void performFinalization() {
167166
runFinalizer(toFinalize, (flags & ONLY_BUILTIN_FLAG) != 0);
168167
}
169168
} else {
170-
if ((flags & NOT_FINALIZABLE_FLAG) == 0) {
171-
runFinalizer(toFinalize, (flags & ONLY_BUILTIN_FLAG) != 0);
172-
}
169+
if ((flags & NOT_FINALIZABLE_FLAG) == 0) {
170+
runFinalizer(toFinalize, (flags & ONLY_BUILTIN_FLAG) != 0);
171+
}
173172
}
174173
if ((gc.getJythonGCFlags() & gc.VERBOSE_FINALIZE) != 0) {
175-
gc.writeDebug("gc", "finalization of "+toFinalize);
176-
}
174+
gc.writeDebug("gc", "finalization of "+toFinalize);
175+
}
177176
if (saveGarbage == 1 || (saveGarbage == 0 &&
178177
(gc.get_debug() & gc.DEBUG_SAVEALL) != 0 && isCyclic())) {
179178
if ((flags & NOT_FINALIZABLE_FLAG) == 0) {
@@ -185,14 +184,14 @@ public void performFinalization() {
185184
}
186185
gc.garbage.add(toFinalize);
187186
if ((gc.getJythonGCFlags() & gc.VERBOSE_FINALIZE) != 0) {
188-
gc.writeDebug("gc", toFinalize+" added to garbage.");
189-
}
187+
gc.writeDebug("gc", toFinalize+" added to garbage.");
188+
}
190189
}
191190
}
192191
if ((flags & NOTIFY_GC_FLAG) != 0) {
193-
if ((gc.getJythonGCFlags() & gc.VERBOSE_FINALIZE) != 0) {
194-
gc.writeDebug("gc", "notify finalization of "+toFinalize);
195-
}
192+
if ((gc.getJythonGCFlags() & gc.VERBOSE_FINALIZE) != 0) {
193+
gc.writeDebug("gc", "notify finalization of "+toFinalize);
194+
}
196195
gc.notifyFinalize(toFinalize);
197196
flags &= ~NOTIFY_GC_FLAG;
198197
}
@@ -202,9 +201,9 @@ protected void finalize() throws Throwable {
202201
flags |= FINALIZED_FLAG;
203202
gc.notifyPreFinalization();
204203
if (gc.delayedFinalizationEnabled() && toFinalize != null) {
205-
if ((gc.getJythonGCFlags() & gc.VERBOSE_FINALIZE) != 0) {
206-
gc.writeDebug("gc", "delayed finalization for "+toFinalize);
207-
}
204+
if ((gc.getJythonGCFlags() & gc.VERBOSE_FINALIZE) != 0) {
205+
gc.writeDebug("gc", "delayed finalization for "+toFinalize);
206+
}
208207
gc.registerForDelayedFinalization(toFinalize);
209208
} else {
210209
performFinalization();

0 commit comments

Comments
 (0)