src/JavaFinalizationRegistry.st
branchjk_new_structure
changeset 1548 af9097580037
child 1549 d99bd163584e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/JavaFinalizationRegistry.st	Tue Jul 24 01:42:45 2012 +0000
@@ -0,0 +1,195 @@
+"
+ COPYRIGHT (c) 1996-2011 by Claus Gittinger
+
+ New code and modifications done at SWING Research Group [1]:
+
+ COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
+                            SWING Research Group, Czech Technical University in Prague
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+
+ [1] Code written at SWING Research Group contains a signature
+     of one of the above copright owners. For exact set of such code,
+     see the differences between this version and version stx:libjava
+     as of 1.9.2010
+"
+"{ Package: 'stx:libjava' }"
+
+Object subclass:#JavaFinalizationRegistry
+	instanceVariableNames:'activeReferees'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Languages-Java-Support'
+!
+
+!JavaFinalizationRegistry class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 1996-2011 by Claus Gittinger
+
+ New code and modifications done at SWING Research Group [1]:
+
+ COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
+                            SWING Research Group, Czech Technical University in Prague
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+
+ [1] Code written at SWING Research Group contains a signature
+     of one of the above copright owners. For exact set of such code,
+     see the differences between this version and version stx:libjava
+     as of 1.9.2010
+
+"
+!
+
+documentation
+"
+    A tricky class that implements Java-style finalization.
+    Future versions may involve some C / VM optimization,
+    if this algorithm prooves usefull
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!JavaFinalizationRegistry class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!JavaFinalizationRegistry methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    activeReferees := Array new: 200.
+    "/ super initialize.   -- commented since inherited method does nothing
+
+    "Modified (comment): / 24-07-2012 / 02:05:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaFinalizationRegistry methodsFor:'private'!
+
+collectionCycle
+
+    | referees references living wasBlocked firstPendingReference lastPendingReference|
+
+    referees := (activeReferees collect:[:e|e notNil]) asArray.
+    references := Array new: referees size.
+    living := Array new: referees size.
+    firstPendingReference := nil.
+
+    ObjectMemory allObjectsIncludingContextsDo:[:o|
+        | index |
+
+        (index := self references: o anyOf: referees) ~~ 0 ifTrue:[
+            o class name == #'java/lang/ref/Finalizer' ifTrue:[
+                self assert: (o instVarNamed: #next) isNil.
+                references at: index put: o                
+            ] ifFalse:[
+                living at: index put: o.
+            ]
+        ].
+    ].
+
+    wasBlocked := OperatingSystem blockInterrupts.
+
+    living withIndexDo:[:each :index|
+        each notNil ifTrue:[
+            | ref |
+
+            ref := references at: index.    
+            references at: index put: nil.
+            firstPendingReference isNil ifTrue:[
+                firstPendingReference := lastPendingReference := ref
+            ] ifFalse:[
+                lastPendingReference instVarNamed: #'next' put: ref.
+                lastPendingReference := ref.
+            ].
+            lastPendingReference instVarNamed: #'next' put: lastPendingReference.
+        ].
+    ].
+    firstPendingReference notNil ifTrue:[
+        (Java classForName: 'java.lang.ref.Reference') 
+            instVarNamed: #pending put: firstPendingReference
+        ].
+    wasBlocked ifFalse:[ OperatingSystem unblockInterrupts.]
+
+    "Created: / 24-07-2012 / 01:30:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+firstFreeIndex
+    activeReferees withIndexDo:[:value :index|
+        value isNil ifTrue:[
+            ^index
+        ].
+    ].
+    self grow.
+
+    "Created: / 24-07-2012 / 01:19:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+grow
+
+    self shouldImplement.
+
+    "Created: / 24-07-2012 / 01:20:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+references: object anyOf: collection
+    "If object references any object in a collection, return
+     index of value which it references, zero otherwise"
+
+    "This is naturaly a candidate for optimization, look
+     at Object>>referencesAny:"
+
+    collection withIndexDo:[:each :eachi|
+        (object references: each) ifTrue:[^eachi].
+    ].
+    ^0
+
+    "Created: / 24-07-2012 / 01:49:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaFinalizationRegistry methodsFor:'registering objects'!
+
+register: object
+    "Register an object for being finalized"
+
+    | index finalizedClass |
+    index := self firstFreeIndex.
+    activeReferees at: index put: object.
+    ((finalizedClass := Java classForName:'java.lang.ref.Finalizer') methodDictionary at: #'register(Ljava/lang/Object;)V')
+        valueWithReceiver: finalizedClass arguments: (Array with: object)
+
+    "Created: / 24-07-2012 / 01:14:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaFinalizationRegistry class methodsFor:'documentation'!
+
+version_SVN
+    ^ '$Id::                                                                                                                        $'
+! !