Thread overview
Shutdown Handling: DLL & Shared Object Detachment?
Sep 01, 2008
Benji Smith
Sep 01, 2008
Sergey Gromov
Sep 01, 2008
Benji Smith
Sep 02, 2008
Sergey Gromov
September 01, 2008
The project I'm currently working on is a library for remote-collection of anonymous user statistics. Third-party app developers will link to my library, which will connect to a server periodically and report usage metrics. (More about the project here, if you're interested: http://benjismith.net/index.php/2008/06/02/business-intelligence-for-desktop-software/ )

I'm developing the embeddable library in D/Tango, and I'll distribute a DLL on Windows, and an SO file for Linux (and eventually Mac, pending a compiler that can reliably build the project on OSX).

The architecture is pretty simple. I create a thread that runs for the lifetime of the host application, waking up every few minutes to check its environment, potentially sending an HTTP request, and then going back to sleep.

So far, so good. The project is coming along nicely, and D is turning out to be a great environment for developing the code.

But I'd like to run some cleanup code during the application's shutdown sequence, and I'm not sure how to do it.

In java, I'd set my thread to be a daemon thread, and use the Runtime.addShutdownHook() method to tell the JVM to run a cleanup thread during the its shutdown sequence.

Is there a way to accomplish the same thing in D/Tango?

Ideally, I'd like to write the shutdown-handling code in a way that's agnostic to the platform, with the same code for the DLL and SO libraries, though I'm skeptical about whether that's actually possible...

Looking at the Tango DLL tutorial:

http://dsource.org/projects/tango/wiki/TutDLL

...I'm guessing that I could put the cleanup code in the rt_term() function.

But, not knowing much about DLL programming, I don't know whether a host application is required to unload the DLL, or whether it's more common for the host application's process to just terminate without ever detaching from the DLL. If the process terminates suddenly, or if the programmer of the host application neglects to unload the DLL, does the OS call the unload function?

Is there analogous functionality for building Linux/Mac shared objects?

Thanks!

--benji
September 01, 2008
Benji Smith <dlanguage@benjismith.net> wrote:
> But, not knowing much about DLL programming, I don't know whether a host application is required to unload the DLL, or whether it's more common for the host application's process to just terminate without ever detaching from the DLL. If the process terminates suddenly, or if the programmer of the host application neglects to unload the DLL, does the OS call the unload function?

In Windows, you must implement DllMain() anyway.

http://msdn.microsoft.com/en-us/library/ms682583.aspx

This function is called with a *reason*. It could be DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, and some others. The ATTACH is called whenever a DLL is loaded into the host process's address space. The DETACH is called whenever a process stops using DLL for whatever reason, including failure to load DLL and process termination. The reason of calling DETACH is also specified.

The problem is, if DETACH is called because a process terminates, the order of uninitializing process DLLs is unknown, not unlike the order of collecting objects by GC is unknown. It may happen that sockets library is already uninitialized. Basically you cannot do anything sophisticated in DllMain which is discussed in the above article.

There are no other standard ways to know if the host process is terminating.

I know nothing about Unix/Mac shared objects.

-- 
SnakE
September 01, 2008
Sergey Gromov wrote:
> The problem is, if DETACH is called because a process terminates, the order of uninitializing process DLLs is unknown, not unlike the order of collecting objects by GC is unknown. It may happen that sockets library is already uninitialized. Basically you cannot do anything sophisticated in DllMain which is discussed in the above article.

That's good to know. I'll avoid anything fancy in my detach handler. I assume file IO is safe?

--benji
September 02, 2008
Benji Smith <dlanguage@benjismith.net> wrote:
> Sergey Gromov wrote:
> > The problem is, if DETACH is called because a process terminates, the order of uninitializing process DLLs is unknown, not unlike the order of collecting objects by GC is unknown. It may happen that sockets library is already uninitialized. Basically you cannot do anything sophisticated in DllMain which is discussed in the above article.
> 
> That's good to know. I'll avoid anything fancy in my detach handler. I assume file IO is safe?

The file I/O is in kernel32.dll which is guaranteed to be present at all times. Taking into account that D uses statically-linked runtime, I think yes, file I/O should be safe.

-- 
SnakE