Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D: Guaranteed Destruction

Tags:

destructor

d

I'm reading Andrei Alexandrescu's The D Programming Language and found this nugget in the tear-down sequence:

...D assumes the exiting the application will de facto free all resources associated with it, so it does not invoke any destructor.

This works great for memory resources, but what about things like network sockets, custom hardware, file handles, etc.? Is there a way to guarantee that my destructor is always called? Alternatively: Does D provide a better way of handling these things (and I'm stuck in a C++ mindset)?

like image 302
Travis Gockel Avatar asked May 27 '12 01:05

Travis Gockel


2 Answers

You can use a static destructor which gets called on thread termination and the shared static destructor which gets called on (normal) application shutdown

(Now if only we had weak references so we wouldn't need another level of indirection...)

like image 82
ratchet freak Avatar answered Oct 07 '22 01:10

ratchet freak


Others have mentioned the module level destructors, but that's not really practical as it requires too much manual maintenance, and D has an irritating quirk were modules with static constructors/destructors cannot have cyclic imports. For example:

Module A

module A;
import B;
static ~this() {}
void main() {}

Module B

module B;
import A;
static ~this() {}

Try to run...

% dmd A.d B.d
% ./A
Cycle detected between modules with ctors/dtors:
A -> B -> A
object.Exception@src/rt/minfo.d(331): Aborting!

D does this just in case your destructors happen to depend on each other, even when they don't. This forces you to do weird "refactoring" of your code to work around this non-problem. There is no way to tell D that there isn't actually a dependency.

A better solution to handling resource destruction is to try and scope as much as possible. Don't have global resources that require destruction, and don't rely on class finalizers for anything, because they aren't guaranteed to run ever (Java has the same problem).

Alternatively, just do things like they do in C: manual shutdown. It's a little bit more work, but really not a big problem. It's certainly easier than wrestling with cyclic imports.

like image 41
Peter Alexander Avatar answered Oct 07 '22 01:10

Peter Alexander