| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | How do DLLs load and unload ? |
JdBP>> How are DLLs loaded and unloaded ? In particular, how does OS/2
JdBP>> Warp keep track of which DLL_InitTerm functions it needs to call
JdBP>> when executing DosFreeModule ? It seems to me that there is a
MS> whats the problem? theoretical a simple recursive logic:
MS> unloadDLL(...)
MS> {
MS> list_of_required_dlls *list;
MS> for all elements in list do unloadDLL(element)
MS> ** unload from memory
MS> done
MS> }
This much is obvious. But, unfortunately, it glibly skips over some very
important details, the very ones that I am actually asking about, in the
step that I have marked with the "**".
For example, it doesn't in any way clarify what happens with respect to
locking and unlocking the per-process and system module tables. In
particular, how does it cope with a recursive call into DosFreeModule from
within the termination function of a DLL. Would the kernel deadlock itself
? Or would it simply corrupt the module graph ? Or is the locking
fine-grained ? If the latter, what are the objects that are locked ?
For another example, it doesn't clarify whether the DLL's memory objects
are unmapped from the address space immediately, i.e. it really is the
single-pass algorithm that the above simplified pseudo-code makes it appear
to be, or whether there is in fact a *two*-stage process involved (stage 1
recursively descending the module graph and calling the termination
functions, and stage 2 performing a second recursive descent to perform the
actual unmapping).
Incidentally, your quote from Roger Pett:
RP> We get away with this because the OS doesn't immediately unload the
RP> DLL after running the DLL termination.
would imply that indeed OS/2 *does* use a two-pass algorithm, because it
implies that all of the InitTerm functions are called before any of the
memory objects are actually unmapped.
To modify your pseudo-code a bit, this would imply something like:
RecursiveTerminate(module)
{
if (--module.referencecount == 0) {
Ring3Callback(module.InitTerm) ;
for m <- module.all_referenced_modules()
RecursiveTerminate(m) ;
}
}
RecursiveUnmap(module)
{
if (module.referencecount == 0) {
unmap all memory objects for this module from the process ;
for m <- module.all_referenced_modules()
RecursiveUnmap(m) ;
}
}
DosFreeModule(module)
{
RecursiveTerminate(module) ;
RecursiveUnmap(module) ;
}
This still isn't perfectly re-entrant, though. And it's unclear, assuming
that we *do* want a fine-grained locking scheme, what objects to lock and
what the duration of those locks should be.
¯ JdeBP ®
--- FleetStreet 1.19 NR
* Origin: JdeBP's point, using Squish (2:440/4.3)SEEN-BY: 396/1 632/0 371 633/210 260 267 270 371 635/506 728 639/252 670/218 @PATH: 440/4 255/1 251/25 396/1 633/260 635/506 728 633/267 |
|
| SOURCE: echomail via fidonet.ozzmosis.com | |
Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.