#BUGFIX by cg
authorClaus Gittinger <cg@exept.de>
Tue, 01 Nov 2016 13:29:51 +0100
changeset 20701 32a0109f2ccb
parent 20700 7cc4b1aa3949
child 20702 5dfa0631a814
#BUGFIX by cg class: ObjectMemory class definition changed: #finalize #initialize run the finalization in a critical region.
ObjectMemory.st
--- a/ObjectMemory.st	Tue Nov 01 12:59:30 2016 +0100
+++ b/ObjectMemory.st	Tue Nov 01 13:29:51 2016 +0100
@@ -30,7 +30,8 @@
 		InterruptLatencyGoal VMSelectors DynamicCodeGCTrigger
 		DynamicCodeLimit JustInTimeCompilationEnabled
 		JavaJustInTimeCompilationEnabled JavaNativeCodeOptimization
-		BackgroundCollectMaximumInterval SavedGarbageCollectorSettings'
+		BackgroundCollectMaximumInterval SavedGarbageCollectorSettings
+		FinalizerAccessLock'
 	poolDictionaries:''
 	category:'System-Support'
 !
@@ -696,32 +697,33 @@
 
     "/ protect against double initialization
     AllocationFailureSignal isNil ifTrue:[
-	AllocationFailureSignal := AllocationFailure.
-	AllocationFailureSignal notifierString:'allocation failure'.
-
-	MallocFailureSignal := MallocFailure.
-	MallocFailureSignal notifierString:'(malloc) allocation failure'.
-
-	LowSpaceSemaphore := Semaphore new name:'LowSpaceSemaphore'.
-
-	DisposeInterruptHandler := self.
-
-	"/ BackgroundCollectMaximumInterval := 3600.     "/ run it at least once an hour
-	BackgroundCollectMaximumInterval := nil.      "/ only run when space situation makes it feasable
-	IncrementalGCLimit := 500000.                 "/ run it whenever 500k have been allocated
-	FreeSpaceGCLimit := FreeSpaceGCAmount := nil. "/ no minumum-freeSpace trigger.
-	MemoryInterruptHandler := self.
-	ExceptionInterruptHandler := self.
-
-	VMSelectors := #( #noByteCode #invalidCodeObject #invalidByteCode #invalidInstruction
-			  #tooManyArguments #badLiteralTable #receiverNotBoolean: #typeCheckError
-			  #integerCheckError #wrongNumberOfArguments: #privateMethodCalled
-			  #doesNotUnderstand: #invalidReturn: #invalidReturnOrRestart:
-			  #userInterrupt #internalError: #spyInterrupt #timerInterrupt #stepInterrupt
-			  #errorInterrupt:with: #disposeInterrupt #recursionInterrupt
-			  #memoryInterrupt #fpExceptionInterrupt #signalInterrupt: #childSignalInterrupt
-			  #ioInterrupt #customInterrupt #schedulerInterrupt #contextInterrupt
-			  #interruptLatency:receiver:class:selector:vmActivity:id:).
+        AllocationFailureSignal := AllocationFailure.
+        AllocationFailureSignal notifierString:'allocation failure'.
+
+        MallocFailureSignal := MallocFailure.
+        MallocFailureSignal notifierString:'(malloc) allocation failure'.
+
+        LowSpaceSemaphore := Semaphore new name:'LowSpaceSemaphore'.
+        FinalizerAccessLock := Semaphore forMutualExclusion.
+        
+        DisposeInterruptHandler := self.
+
+        "/ BackgroundCollectMaximumInterval := 3600.     "/ run it at least once an hour
+        BackgroundCollectMaximumInterval := nil.      "/ only run when space situation makes it feasable
+        IncrementalGCLimit := 500000.                 "/ run it whenever 500k have been allocated
+        FreeSpaceGCLimit := FreeSpaceGCAmount := nil. "/ no minumum-freeSpace trigger.
+        MemoryInterruptHandler := self.
+        ExceptionInterruptHandler := self.
+
+        VMSelectors := #( #noByteCode #invalidCodeObject #invalidByteCode #invalidInstruction
+                          #tooManyArguments #badLiteralTable #receiverNotBoolean: #typeCheckError
+                          #integerCheckError #wrongNumberOfArguments: #privateMethodCalled
+                          #doesNotUnderstand: #invalidReturn: #invalidReturnOrRestart:
+                          #userInterrupt #internalError: #spyInterrupt #timerInterrupt #stepInterrupt
+                          #errorInterrupt:with: #disposeInterrupt #recursionInterrupt
+                          #memoryInterrupt #fpExceptionInterrupt #signalInterrupt: #childSignalInterrupt
+                          #ioInterrupt #customInterrupt #schedulerInterrupt #contextInterrupt
+                          #interruptLatency:receiver:class:selector:vmActivity:id:).
     ]
 
     "Modified: / 5.8.1998 / 15:30:12 / cg"
@@ -4518,20 +4520,22 @@
 finalize
     "tell all weak objects that something happened."
 
-    self allChangedShadowObjectsDo:[:aShadowArray |
-	Error handle:[:ex |
-	    'ObjectMemory [warning]: caught error in weakArray processing: ' errorPrint.
-	    ex description errorPrintCR.
-	    ex suspendedContext fullPrintAllLevels:10.
-	    "Restart the do block to clean up the rest of the shadow array.
-	     This is safe here, because the old executor that triggered the error
-	     has already been removed from the Registry"
-	    ex restart.
-	] do:[
-	    aShadowArray lostPointer.
-	].
+    FinalizerAccessLock critical:[
+        self allChangedShadowObjectsDo:[:aShadowArray |
+            Error handle:[:ex |
+                'ObjectMemory [warning]: caught error in weakArray processing: ' errorPrint.
+                ex description errorPrintCR.
+                ex suspendedContext fullPrintAllLevels:10.
+                "Restart the do block to clean up the rest of the shadow array.
+                 This is safe here, because the old executor that triggered the error
+                 has already been removed from the Registry"
+                ex restart.
+            ] do:[
+                aShadowArray lostPointer.
+            ].
+        ].
     ].
-
+    
     "/ we should change the setup,
     "/ to make the Dependencies collection a dependent
     "/ of all the WeakArrays and WeakIDSets there,