August 26, 2004
In article <cgknav$ab6$1@digitaldaemon.com>, Ben Hinkle says...

>> Okay, but presumably it *is* guaranteed to collect everything not yet collected (and to call all remaining destructors) at program exit. Right?

>nope - at program exit it scans static data for roots so any object reference stored in a static variable will never get collected. I don't know if removing static data from the final scan would cause problems.

So if I have a static variable:

#    int n;

and its value happens by coincidence to be the run-time address of an instance of some class or other, then the destructor of that instance will /never/ get called? Not even at program exit?

This is worrying. I need a workaround, and I'm going to have to think hard to come up with it. (Fortunately it's not urgent).

Jill


August 26, 2004
In article <cgkpfo$b62$1@digitaldaemon.com>, Arcane Jill says...
>
>This is worrying. I need a workaround, and I'm going to have to think hard to come up with it. (Fortunately it's not urgent).
>

As distressing as this inconsistency with destructors is, I managed to compose a decent workaround last night in a fit of inspiration.

http://svn.dsource.org/svn/projects/dsp/trunk/misc/systemFinalizer.d

I'm basically eating my own dog food here: I suggested some time ago that we be given a way to flag objects for explicit deletion on exit if nothing else. :)

There are other bits in that directory as well all are welcome to critique. These are common pieces that have fallen out of DSP that are useful outside the scope of the project.

The idea is that the SystemFinalizer is a singleton that is instantiated and controlled via a separate AutoSystemFinalizer in main() (or your daemon thread if you prefer).  This way you have a single point of access from which to mark objects for deletion once the AutoSystemFinalizer goes out of scope.

Simply call SystemFinalizer.register(obj) anywhere in your app to flag an object, and off you go.  A second register() method exists that allows for a custom finalizer function, just in case the first form isn't flexible enough.

-Pragma
[[ EricAnderton at (yummy!) yahoo.com ]]
August 26, 2004
nifty. you could also use module constructors and destructors instead of auto class ctors and dtors. Module ctors and dtors will always run. It probably will be about the same - I guess the difference is that user code doesn't have to worry about doing anything in main().

"pragma" <pragma_member@pathlink.com> wrote in message news:cgku7g$dhv$1@digitaldaemon.com...
> In article <cgkpfo$b62$1@digitaldaemon.com>, Arcane Jill says...
> >
> >This is worrying. I need a workaround, and I'm going to have to think
hard to
> >come up with it. (Fortunately it's not urgent).
> >
>
> As distressing as this inconsistency with destructors is, I managed to
compose a
> decent workaround last night in a fit of inspiration.
>
> http://svn.dsource.org/svn/projects/dsp/trunk/misc/systemFinalizer.d
>
> I'm basically eating my own dog food here: I suggested some time ago that
we be
> given a way to flag objects for explicit deletion on exit if nothing else.
:)
>
> There are other bits in that directory as well all are welcome to
critique.
> These are common pieces that have fallen out of DSP that are useful
outside the
> scope of the project.
>
> The idea is that the SystemFinalizer is a singleton that is instantiated
and
> controlled via a separate AutoSystemFinalizer in main() (or your daemon
thread
> if you prefer).  This way you have a single point of access from which to
mark
> objects for deletion once the AutoSystemFinalizer goes out of scope.
>
> Simply call SystemFinalizer.register(obj) anywhere in your app to flag an
> object, and off you go.  A second register() method exists that allows for
a
> custom finalizer function, just in case the first form isn't flexible
enough.
>
> -Pragma
> [[ EricAnderton at (yummy!) yahoo.com ]]


August 26, 2004
In article <cgkcsq$5fi$1@digitaldaemon.com>, Arcane Jill says...
>
>In article <cgj8qb$2ler$1@digitaldaemon.com>, pragma says...
>
>>>The garbage collector is not guaranteed to run the destructor for all unreferenced objects.
>
>Please see THIS POST from Walter, and the discussion before and after it: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/3488
>
>In particular, Walter said: "I must have misspoke, because when the gc collects an object, it *does* run the destructor." (Walter's emphasis on *does*).
>
>I have security apps planned which rely on Walter's statement being true. Where is this "not guaranteed" quote in the manual? I couldn't find it. Basically - help! Who's right? Walter, or the manual? Walter, please could you clarify (again), and fix the manual if it's wrong.

IIRC this came up in the original discussion and that was Walter's reply.  The spec should likely be corrected.


Sean


August 26, 2004
In article <cgkvmr$ec5$1@digitaldaemon.com>, Ben Hinkle says...
>
>nifty. you could also use module constructors and destructors instead of auto class ctors and dtors. Module ctors and dtors will always run. It probably will be about the same - I guess the difference is that user code doesn't have to worry about doing anything in main().
>

Well, the main advantage here is not /if/ the destructor will run, but rather /how/.  In this case, use of a destructor registry (like SystemFinalizer) guarantees that a registered destructor (via a call to 'delete') will run while all other referenced objects are still alive.  This is in sharp contrast to how D may-or-may-not run all outsitanding finalizers and delete their corresponding objects one-by-one per finalizer.

Another way to look at it is like an event callback mechanism.  SystemFinalizer is analagous to a "System Shutdown Event" that warns registered listeners to clean up.

In retrospect, the latter would probably be more useful.

-Pragma
[[ EricAnderton at (D needs events) yahoo.com ]]
August 26, 2004
In article <cgkpfo$b62$1@digitaldaemon.com>, Arcane Jill says...
>
>In article <cgknav$ab6$1@digitaldaemon.com>, Ben Hinkle says...
>
>>> Okay, but presumably it *is* guaranteed to collect everything not yet collected (and to call all remaining destructors) at program exit. Right?
>
>>nope - at program exit it scans static data for roots so any object reference stored in a static variable will never get collected. I don't know if removing static data from the final scan would cause problems.
>
>So if I have a static variable:
>
>#    int n;
>
>and its value happens by coincidence to be the run-time address of an instance of some class or other, then the destructor of that instance will /never/ get called? Not even at program exit?
>
>This is worrying. I need a workaround, and I'm going to have to think hard to come up with it. (Fortunately it's not urgent).

Does the final GC pass occur after module destructors are run?  If so, a slightly lame workaround would be to have such destructors default initialize all statics in the module.  ie.

static ~this() { n = n.init; }

Basically saying that every module is effectively responsible for picking up its toys when it's done playing with them.


Sean


August 26, 2004
"pragma" <pragma_member@pathlink.com> wrote in message news:cgku7g$dhv$1@digitaldaemon.com...
> In article <cgkpfo$b62$1@digitaldaemon.com>, Arcane Jill says...
> >
> >This is worrying. I need a workaround, and I'm going to have to think hard to come up with it. (Fortunately it's not urgent).
> >
>
> As distressing as this inconsistency with destructors is, I managed to compose a decent workaround last night in a fit of inspiration.
>
> http://svn.dsource.org/svn/projects/dsp/trunk/misc/systemFinalizer.d

Why not just have the instance in a static initialiser? (Need to force linking via explicit mention of class??)


>
> I'm basically eating my own dog food here: I suggested some time ago that we be given a way to flag objects for explicit deletion on exit if nothing else. :)
>
> There are other bits in that directory as well all are welcome to critique. These are common pieces that have fallen out of DSP that are useful outside the scope of the project.
>
> The idea is that the SystemFinalizer is a singleton that is instantiated and controlled via a separate AutoSystemFinalizer in main() (or your daemon thread if you prefer).  This way you have a single point of access from which to mark objects for deletion once the AutoSystemFinalizer goes out of scope.
>
> Simply call SystemFinalizer.register(obj) anywhere in your app to flag an object, and off you go.  A second register() method exists that allows for a custom finalizer function, just in case the first form isn't flexible enough.
>
> -Pragma
> [[ EricAnderton at (yummy!) yahoo.com ]]


August 26, 2004
In article <cglhec$nn3$1@digitaldaemon.com>, Matthew says...

>
>"pragma" <pragma_member@pathlink.com> wrote in message news:cgku7g$dhv$1@digitaldaemon.com...
>> http://svn.dsource.org/svn/projects/dsp/trunk/misc/systemFinalizer.d
>
>Why not just have the instance in a static initialiser? (Need to force linking via explicit mention of class??)
>

# // so I should do this?
# static this(){
#   _instance = new SystemFinalizer();
# }

You're right.  That would make a better singleton wouldn't it?


-Pragma
[[ EricAnderton at (_instance) yahoo dot com ]]
August 29, 2004
In article <cgknav$ab6$1@digitaldaemon.com>, Ben Hinkle says...
>
>Arcane Jill wrote:
>> [...]
>> Okay, but presumably it *is* guaranteed to collect everything not yet
>> collected (and to call all remaining destructors) at program exit. Right?
>
>nope - at program exit it scans static data for roots so any object reference stored in a static variable will never get collected. I don't know if removing static data from the final scan would cause problems.

Are you sure about this? Why does it scan static data but not dynamic?

Nick


August 29, 2004
Nick wrote:

> In article <cgknav$ab6$1@digitaldaemon.com>, Ben Hinkle says...
>>
>>Arcane Jill wrote:
>>> [...]
>>> Okay, but presumably it *is* guaranteed to collect everything not yet
>>> collected (and to call all remaining destructors) at program exit.
>>> Right?
>>
>>nope - at program exit it scans static data for roots so any object reference stored in a static variable will never get collected. I don't know if removing static data from the final scan would cause problems.
> 
> Are you sure about this? Why does it scan static data but not dynamic?
> 
> Nick

The static data is scanned for roots into the dynamic data. Once a root is
found it continues to mark anything reachable from that point. Normally it
looks for root in the static data and on all stacks, but since the program
is exiting the stacks are skipped. Users can add arbitrary chunks of memory
to list of things to scan for roots, too. Once it is done marking all
reachable dynamic data it garbage collects everything else.
Does that help?
-Ben
1 2 3
Next ›   Last »