Finalisation problem (bug??)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Finalisation problem (bug??)

Chris Uppal-3
I've got a problem with finalisation.

The picture is that I have an object representing an external resource
(various structures allocated in an external library).  That object can clean
itself up by finalisation if necessary.

When it is cleaned up (whether by finalisation or not) it issues various API
calls, and they, in turn can result in the external library invoking various
ExternalCallbacks associated with the object.  That all works fine when the
object is cleared normally, but when it is cleared by finalisation, I'm getting
walkbacks from the finalisation thread.

The problem is that, although the object in question is still holding on to its
own references to the ExternalCallbacks (so they haven't been GCed), it appears
that the corresponding entries /have/ been removed from the ExternalCallbacks
class's registry.  In the debugger, I can see that the ExternalCallbacks
instances still exist, and that their #thunk-s are normal (so they haven't been
#free-ed), but the registry contains the DeadObject at the index corresponding
to their cookies.

I speculate that objects can be removed from weak collections (such as the
registry of ExternalCallbacks) while they are still reachable from objects on
the finalisation queue.  If that is the case then is it a bug ?  And anyway,
how do I fix or work around it ?

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Finalisation problem (bug??)

Chris Uppal-3
I wrote:

> I speculate that objects can be removed from weak collections (such as the
> registry of ExternalCallbacks) while they are still reachable from
> objects on the finalisation queue.  If that is the case then is it a bug
> ?  And anyway, how do I fix or work around it ?

I'm sorry to nag, but I'd very much appreciate an answer to this.  As it stands
it appears impossible to clean up objects with finalisation if they use
callbacks.  If that's the case then OK, fair enough, my object will not be
finalisable, but I don't want to go that route unless I have to.

TIA

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Finalisation problem (bug??)

Andy Bower-3
Chris,

> > I speculate that objects can be removed from weak collections (such
> > as the registry of ExternalCallbacks) while they are still
> > reachable from objects on the finalisation queue.  If that is the
> > case then is it a bug ?  And anyway, how do I fix or work around it
> > ?

This is effectively issue #1580, which is recorded as follows:

---

The garbage collectors scan to mark finalizable free objects is
currently combined with the weak reference "nilling" scan. This means
that it is possible that a finalizable object may be marked after any
weak references to its children have already been nilled (it is correct
that weak references to the object itself should be nilled, since when
an object is finalized there should be no references to it at all apart
from the finalization queue reference).

An example is the ExternalCallback objects. These have a weak register
mapping integer indices to objects. The integer indices are saved in
the thunks, and are passed back into the image when the callback
occurs. The index is then used to look up the relevant callback object
in order to invoke it to handle the callback. Consider a situation
where a callback is owned by some object, and is passed to, and capture
by, some external API. The owning object uses finalization to inform
the external API that the callback is no longer valid. This means that
the callback must remain valid until the finalization is actioned. In
order for the callback to remain valid, the weak registry must retain
the reference to the callback object. Because of this bug, it is
possible that the weak registry will be encountered in the GC scan
before the callback owner. If the callback owner is no longer
referenced, then the callback itself will be unmarked. Thus the scan
will nill out the weak reference. Later in the scan the finalizable
callback owner is encountered, and its children are recursively marked
in order to rescue them for finalization. Thus it is possible to hit
finalization with an invalid callback. This problem was encountered in
practice when implementing the FileSystemWatcher class which registers
a BlockCallback as the APC callback function for overlapped I/O. In
order to complete finalization the directory handle is closed, and the
ReadDirectoryChangesW sends a further APC. This APC cannot be processed
because the callback is no longer in the callback registry. This causes
either a walkback (due to the use of the invalid callback index), or a
GPF.
---

The problem has been addressed in Dolphin 6.

Best regards

 
Andy Bower
Dolphin Support
www.object-arts.com


Reply | Threaded
Open this post in threaded view
|

Re: Finalisation problem (bug??)

Chris Uppal-3
Andy,

> This is effectively issue #1580, which is recorded as follows:
> [...]
> The problem has been addressed in Dolphin 6.

Great.  Thank you.

    -- chris