View previous topic :: View next topic |
Author |
Message |
pragma
Joined: 28 May 2004 Posts: 607 Location: Washington, DC
|
Posted: Mon Jun 21, 2004 9:21 am Post subject: Implications of DLL's in D |
|
|
Another hurdle to take in to account, is what happens to an object when it leaves its supporting DLL. This is a key point for DSP, since the architecture makes use of lots of DLL's.
Analysis
Suppose a DLL is defined as such, and exports one symbol: "GetNewFoobar".
Code: |
class Foobar{
int a;
this(int a){ this.a =a; }
int GetFoobar(){ return(a);
}
export(Windows) Foobar GetNewFoobar(){ return new Foobar(); }
|
Now provided a program also has Foobar properly defined (via an import for example), it can load the dll and start generating objects. This carries with it the following consequences:
1) Such objects are generated on the DLL's heap, not the calling application.
2) Any DLL's object is subject to premature collection if it is not referenced from within the DLL.
3) Externally (from the DLL's perspective) referenced objects could be maintained with a lifespan different from their originating DLL. A premature unload of the DLL would cause all outstanding objects to be collected, thus invalidating these object references without warning.
Now say I have a servlet that creates a new Foobar and attaches it to the application object. Then, I go and touch that servlet's source .dsp, which forces an unload of that library. Disaster ensues.
This is especially a problem wtih DSP, since it uses discrete DLL's for each servlet. Regenerating these DLL's on demand is a crucial feature of the architecture, and causes all of the aforementioned issues to come into play.
Discussion
Here's what I've come up with so far:
Maintaining object references (point #2) is easy enough to solve via some sort of object "sentinel", which would be a threadsafe bucket of object references that lives as long as its enclosing library. Objects would be manually assigned to the library's sentinel before leaving the dll. Additionally, the object would have to be 'returned' to the dll so it may be collected.
Code: |
export(Windows) Foobar GetNewFoobar(){
Foobar foo = new Foobar();
Sentinel.add(foo); // static sentinel holds onto the reference.
return(foo);
}
export(Windows) void DisposeFoobar(Foobar foo){
Sentinel.remove(foo); // drops reference to foo.
}
|
(Yep, it's starting to look like COM all over again.)
Merely duplicating an object's data isn't enough to escape #3 since you still have a vtable that is pointing into the library's address space. At the cost of polymorphism, you could create a new typed object within the calling space and simply ferform a shallow copy. This would be akin to serializing the object, since you only capture an object's data and nothing else.
Hooking the calling space's GC could satisfy point #1, but only that point. Library unloads would leave structs and primitives intact, but object vtables would be invalidated. Since the GC isn't aware of libary loading, or object dependency upon a library's address space, there is no good way to know when a library is "free" to be disposed of. And even if libraries themselves were "GC-able", you'd still have to contend with multiple concurrent library/object versions within the same application. (maybe not a huge problem with all problem domains, but certainly not desireable)
Conclusions
I'm going to have to look into how Java and .NET side-step these kinds of problems. I suspect that both architectures exploit some features in their respective VM's that is hard to obtain with a more "traditional" paradigm like D (or C/C++ for that matter).
Object sentinels have to happen, either in an explicit (manual) way or by subclassing or even some radical form of new/delete. This could allow for the added benefit of allowing libraries to expose another method like "CanUnload()" since the sentinel knows about all the outstanding objects.
Right now, i'd have to say that storing anything outside of primitive data to a context that has a lifespan other than the current context (eg. setting a value on an application from within a servlet) yields unpredictable behavior. Alternately, any object that is known to cross this barrier must be copied into an instance created entirely from within the destination's space.
I'm open to suggestions on how to eliminate or solve these issues with minimal intrusion into a servlet's code. _________________ -- !Eric.t.Anderton at gmail |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Fri Jul 23, 2004 11:29 am Post subject: |
|
|
So how did you resolve this Eric? |
|
Back to top |
|
|
pragma
Joined: 28 May 2004 Posts: 607 Location: Washington, DC
|
Posted: Sun Jul 25, 2004 8:36 am Post subject: |
|
|
kris wrote: | So how did you resolve this Eric? |
Well it's not exactly 'resolved' per-se, but I did design around it to prevent these kinds of cases.
- Servlet instances live inside their respective library only.
- Servlets are treated as transient resources that must be requested from their repsective library.
- Serlvet references are, in no circumstances, kept outside the response handler.
- Since no library may be used while any other library in the cache is being built, there is no chance of a servlet reference from being invalidated while any given response handle is running.
Obviously, this scheme is somewhat brittle, because there's no way to guarantee that someone isn't going to try to keep a servlet reference someplace. Also, it'd be nice to avoid the overhead associated with looking up a servlet each time you want to use it.
To deal with this I plan on using my MuticastDelegate template (the one I rolled out on the NG earlier) to support an event subsystem. Each library will have one such delegate list that will allow it (or the DSP runtime for that matter) to notify all its interested peers that need to keep servlet references alive. This should also pave the way for hand-coding servlet libraries. _________________ -- !Eric.t.Anderton at gmail |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Mon Aug 02, 2004 11:55 pm Post subject: |
|
|
Can you send me your latest dll loader please Eric? I've got a good use for it ...
- Kris |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|