digitalmars.D - issue with calling destructors from GC
- Ben Hinkle (9/9) Aug 18 2004 I have a question about calling destructors from the GC - in particular ...
- Ben Hinkle (10/19) Aug 18 2004 I should probably add that a fallback position is to have the buffered
- Russ Lewis (49/57) Aug 18 2004 AFAIK, the GC doesn't let you control in what order things are
- Berin Loritsch (11/36) Aug 18 2004 The thing is that GC is essentially nondeterministic, and efforts to
I have a question about calling destructors from the GC - in particular at the program exit. I'm fixing some bugs in std.stream and one of the things I'm doing is adding a destructor for BufferedStream that closes the source stream. The problem is that when the GC runs the source stream can be destroyed before the buffered stream's destructor runs. So I end up trying to reference an object that has been destroyed. Is there some way I can tell if an object is still valid - or somehow control the order in which the GC runs the destructors? -Ben
Aug 18 2004
I should probably add that a fallback position is to have the buffered stream's destructor print a warning to stderr if the stream is still open and the buffer is non-empty. This isn't so bad IMO since managing non-memory resources though garbage collection is problematic in any case - the least of which is that the destructor may never run. Failing to close the buffered stream could mean the final buffered content is never written to the source stream, but at least a warning to stderr would alert users to the problem. -Ben "Ben Hinkle" <bhinkle4 juno.com> wrote in message news:cg02ss$4fp$1 digitaldaemon.com...I have a question about calling destructors from the GC - in particular at the program exit. I'm fixing some bugs in std.stream and one of the things I'm doing is adding a destructor for BufferedStream that closes the source stream. The problem is that when the GC runs the source stream can be destroyed before the buffered stream's destructor runs. So I end up trying to reference an object that has been destroyed. Is there some way I can tell if an object is still valid - or somehow control the order in which the GC runs the destructors? -Ben
Aug 18 2004
Ben Hinkle wrote:I have a question about calling destructors from the GC - in particular at the program exit. I'm fixing some bugs in std.stream and one of the things I'm doing is adding a destructor for BufferedStream that closes the source stream. The problem is that when the GC runs the source stream can be destroyed before the buffered stream's destructor runs. So I end up trying to reference an object that has been destroyed. Is there some way I can tell if an object is still valid - or somehow control the order in which the GC runs the destructors?AFAIK, the GC doesn't let you control in what order things are destructed. However, if you care about order, here's a way to make sure things appen in order. Basically, the concept is that you have to keep a global list of references to the objects that you want to clean up last. This global list prevents those objects from being garbage. When the other object is cleaned up, you remove this reference in your destructor. Thus, the former object only becomes garbage after you've cleaned up. class Used {} class User { static Object destructionOrderingArray_syncObj; static int[Used] destructionOrderingArray; static this() { destructionOrderingArray_syncObj = new Object; } void removeFromOrderingArray(Used u) { assert(u in destructionOrderingArray); destructionOrderingArray[u]--; if(destructionOrderingArray[u] == 0) delete /*from array*/ destructionOrderingArray[u]; } void addToOrderingArray(Used u) { if(u in destructionOrderingArray) destructionOrderingArray[u]++; else destructionOrderingArray[u] = 1; } Used _myUsed; void used(Used u) { // settor property if(u === _myUsed) return; synchronized(destructionOrderingArray_syncObj) { if(_myUsed !== null) removeFromOrderingArray(_myUsed); addToOrderingArray(_myUsed); } _myUsed = used; } Used used() { // gettor property return _myUsed; } ~this() { if(_myUsed !== null) removeFromOrderingArray(_myUsed); } }
Aug 18 2004
Russ Lewis wrote:Ben Hinkle wrote:The thing is that GC is essentially nondeterministic, and efforts to make it deterministic only cause the language implementation to become very complex--and worse, it invites people to try to out-think the GC. If you accept that the GC is nondeterministic then there are ways to deal with it. So, if you call delete on a deleted object would an exception be thrown, or would the system ignore the extraneous call to delete? This would allow the BufferedStream to delete the underlying stream (and if written correctly consequently release the resources held by it), and do nothing if the underlying stream has been collected.I have a question about calling destructors from the GC - in particular at the program exit. I'm fixing some bugs in std.stream and one of the things I'm doing is adding a destructor for BufferedStream that closes the source stream. The problem is that when the GC runs the source stream can be destroyed before the buffered stream's destructor runs. So I end up trying to reference an object that has been destroyed. Is there some way I can tell if an object is still valid - or somehow control the order in which the GC runs the destructors?AFAIK, the GC doesn't let you control in what order things are destructed. However, if you care about order, here's a way to make sure things appen in order. Basically, the concept is that you have to keep a global list of references to the objects that you want to clean up last. This global list prevents those objects from being garbage. When the other object is cleaned up, you remove this reference in your destructor. Thus, the former object only becomes garbage after you've cleaned up.
Aug 18 2004