Finalization question

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

Finalization question

David T. Lewis
I have a case in which I want to register objects for finalization
in order to ensure that external references (file handles on OS pipes)
are closed if the object has not been properly closed by its user.
I thought it would be a good idea to unregister these objects explicitly
when I know that they *have* been properly closed. This seemed
like a good idea because allowing weak registries to grow can be a
big performance problem, and I thought it would be good to keep
the registry as small as possible.

The result appears to be an occasional race condition in which the
finalization process attempts to remove an element that somebody else
(me) has removed from another process. At least I think that's what's
happening, see attached png of the debugger.

Is explicitly removing an object from the finalization registry a
Bad Thing To Do? Or is this perhaps a bug that should be resolved
by synchronizing access to the finalization registry, or by ignoring
the error condition in the finalization process?

Thanks,

Dave




FinalizationRaceCondition.png (26K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Finalization question

cdavidshaffer
David T. Lewis wrote:

>I have a case in which I want to register objects for finalization
>in order to ensure that external references (file handles on OS pipes)
>are closed if the object has not been properly closed by its user.
>I thought it would be a good idea to unregister these objects explicitly
>when I know that they *have* been properly closed. This seemed
>like a good idea because allowing weak registries to grow can be a
>big performance problem, and I thought it would be good to keep
>the registry as small as possible.
>
>The result appears to be an occasional race condition in which the
>finalization process attempts to remove an element that somebody else
>(me) has removed from another process. At least I think that's what's
>happening, see attached png of the debugger.
>
>Is explicitly removing an object from the finalization registry a
>Bad Thing To Do? Or is this perhaps a bug that should be resolved
>by synchronizing access to the finalization registry, or by ignoring
>the error condition in the finalization process?
>
>Thanks,
>
>Dave
>
>  
>
Did you ever sort this out Dave?  Looking at StandardFileStream I see
exactly the pattern you describe:

unregister method removes the file stream from the registry via
remove:ifAbsent:

close sends unregister

It seems odd that your race condition occurs but I've never had such a
problem with file streams.  Further investigation shows that Socket does
the same thing.  Maybe you could look at them and see where your usage
differs.  Is the problem Squeak version dependent?  I've looked over
WeakRegistry in 3.7 and it looks solid.  No obvious race
conditions...but they are never obvious, are they ;-)

David


Reply | Threaded
Open this post in threaded view
|

Re: Finalization question

johnmci
I'll also note MPEGFile uses the same pattern which was copied from  
the Socket code originally.
This pattern of code is used in other class I've written, (6 more in  
Sophie) and if someone can find a bug in
it this pattern of code would be interesting to know.

I'll note if your code does cleanup processing as part of an explicit  
method send, then in the finalize
method you may need a guard clause to prevent double usage of destroy  
logic (which might cause problem).



On 14-Jun-06, at 10:13 AM, David Shaffer wrote:

> Did you ever sort this out Dave?  Looking at StandardFileStream I see
> exactly the pattern you describe:
>
> unregister method removes the file stream from the registry via
> remove:ifAbsent:
>
> close sends unregister
>
> It seems odd that your race condition occurs but I've never had such a
> problem with file streams.  Further investigation shows that Socket  
> does
> the same thing.  Maybe you could look at them and see where your usage
> differs.  Is the problem Squeak version dependent?  I've looked over
> WeakRegistry in 3.7 and it looks solid.  No obvious race
> conditions...but they are never obvious, are they ;-)
>
> David
>
>

--
========================================================================
===
John M. McIntosh <[hidden email]> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===


Reply | Threaded
Open this post in threaded view
|

Re: Finalization question

David T. Lewis
John, David,

Thanks for your replies.

No, I did not really sort out the problem, I simply quit unregistering
the objects, which of course made the symptoms go away. I suspect that
I was registering and unregistering things at a higher rate than would
typically be the case for file streams and sockets, so perhaps that
increases the likelihood of the problem.

I'll take another look at the socket and file stream examples and
see if I can spot where I went wrong.

By the way, I did try synchronizing access to the registry, which
indeed made the race condition go away. But some other horrible
problem cropped up, at which point I decided I was wasting my time
trying to violate the laws of nature. I'll have another look and
see if I can clarify what was happening.

On Wed, Jun 14, 2006 at 10:39:51AM -0700, John M McIntosh wrote:

> I'll also note MPEGFile uses the same pattern which was copied from  
> the Socket code originally.
> This pattern of code is used in other class I've written, (6 more in  
> Sophie) and if someone can find a bug in
> it this pattern of code would be interesting to know.
>
> I'll note if your code does cleanup processing as part of an explicit  
> method send, then in the finalize
> method you may need a guard clause to prevent double usage of destroy  
> logic (which might cause problem).
>
>
>
> On 14-Jun-06, at 10:13 AM, David Shaffer wrote:
>
> >Did you ever sort this out Dave?  Looking at StandardFileStream I see
> >exactly the pattern you describe:
> >
> >unregister method removes the file stream from the registry via
> >remove:ifAbsent:
> >
> >close sends unregister
> >
> >It seems odd that your race condition occurs but I've never had such a
> >problem with file streams.  Further investigation shows that Socket  
> >does
> >the same thing.  Maybe you could look at them and see where your usage
> >differs.  Is the problem Squeak version dependent?  I've looked over
> >WeakRegistry in 3.7 and it looks solid.  No obvious race
> >conditions...but they are never obvious, are they ;-)
> >
> >David
> >

Reply | Threaded
Open this post in threaded view
|

Re: Finalization question

David T. Lewis
This is just to follow up on my original question.

I tried to reproduce my problem in a stand-alone test. I was not
able to produce any kind of concurrency problems when registering
and unregistering objects for finalization, regardless of how
many processes were doing the register/unregister operations.

So yes, it is perfectly OK to explicitly unregister objects
from a finalization registry.

Thanks,
Dave


On Wed, Jun 14, 2006 at 09:42:41PM -0400, David T. Lewis wrote:

> John, David,
>
> Thanks for your replies.
>
> No, I did not really sort out the problem, I simply quit unregistering
> the objects, which of course made the symptoms go away. I suspect that
> I was registering and unregistering things at a higher rate than would
> typically be the case for file streams and sockets, so perhaps that
> increases the likelihood of the problem.
>
> I'll take another look at the socket and file stream examples and
> see if I can spot where I went wrong.
>
> By the way, I did try synchronizing access to the registry, which
> indeed made the race condition go away. But some other horrible
> problem cropped up, at which point I decided I was wasting my time
> trying to violate the laws of nature. I'll have another look and
> see if I can clarify what was happening.
>
> On Wed, Jun 14, 2006 at 10:39:51AM -0700, John M McIntosh wrote:
> > I'll also note MPEGFile uses the same pattern which was copied from  
> > the Socket code originally.
> > This pattern of code is used in other class I've written, (6 more in  
> > Sophie) and if someone can find a bug in
> > it this pattern of code would be interesting to know.
> >
> > I'll note if your code does cleanup processing as part of an explicit  
> > method send, then in the finalize
> > method you may need a guard clause to prevent double usage of destroy  
> > logic (which might cause problem).
> >
> >
> >
> > On 14-Jun-06, at 10:13 AM, David Shaffer wrote:
> >
> > >Did you ever sort this out Dave?  Looking at StandardFileStream I see
> > >exactly the pattern you describe:
> > >
> > >unregister method removes the file stream from the registry via
> > >remove:ifAbsent:
> > >
> > >close sends unregister
> > >
> > >It seems odd that your race condition occurs but I've never had such a
> > >problem with file streams.  Further investigation shows that Socket  
> > >does
> > >the same thing.  Maybe you could look at them and see where your usage
> > >differs.  Is the problem Squeak version dependent?  I've looked over
> > >WeakRegistry in 3.7 and it looks solid.  No obvious race
> > >conditions...but they are never obvious, are they ;-)
> > >
> > >David
> > >