FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Implications of DLL's in D

 
Post new topic   Reply to topic     Forum Index -> DSP
View previous topic :: View next topic  
Author Message
pragma



Joined: 28 May 2004
Posts: 607
Location: Washington, DC

PostPosted: Mon Jun 21, 2004 9:21 am    Post subject: Implications of DLL's in D Reply with quote

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. Sad

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
View user's profile Send private message Yahoo Messenger
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Fri Jul 23, 2004 11:29 am    Post subject: Reply with quote

So how did you resolve this Eric?
Back to top
View user's profile Send private message
pragma



Joined: 28 May 2004
Posts: 607
Location: Washington, DC

PostPosted: Sun Jul 25, 2004 8:36 am    Post subject: Reply with quote

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. Very Happy

- 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
View user's profile Send private message Yahoo Messenger
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Mon Aug 02, 2004 11:55 pm    Post subject: Reply with quote

Can you send me your latest dll loader please Eric? I've got a good use for it ...

- Kris
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> DSP All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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