/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/dynload.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/dynload.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File size: 9007 byte(s)
committing r3113 initial commit again...
1 william 31 /////////////////////////////////////////////////////////////////////////////
2     // Name: src/common/dynload.cpp
3     // Purpose: Dynamic loading framework
4     // Author: Ron Lee, David Falkinder, Vadim Zeitlin and a cast of 1000's
5     // (derived in part from dynlib.cpp (c) 1998 Guilhem Lavaux)
6     // Modified by:
7     // Created: 03/12/01
8     // RCS-ID: $Id: dynload.cpp 40943 2006-08-31 19:31:43Z ABX $
9     // Copyright: (c) 2001 Ron Lee <ron@debian.org>
10     // Licence: wxWindows licence
11     /////////////////////////////////////////////////////////////////////////////
12    
13     // ----------------------------------------------------------------------------
14     // headers
15     // ----------------------------------------------------------------------------
16    
17     #include "wx/wxprec.h"
18    
19     #ifdef __BORLANDC__
20     #pragma hdrstop
21     #endif
22    
23     #if wxUSE_DYNAMIC_LOADER
24    
25     #ifdef __WINDOWS__
26     #include "wx/msw/private.h"
27     #endif
28    
29     #ifndef WX_PRECOMP
30     #include "wx/log.h"
31     #include "wx/intl.h"
32     #include "wx/hash.h"
33     #include "wx/utils.h"
34     #include "wx/module.h"
35     #endif
36    
37     #include "wx/strconv.h"
38    
39     #include "wx/dynload.h"
40    
41    
42     // ---------------------------------------------------------------------------
43     // wxPluginLibrary
44     // ---------------------------------------------------------------------------
45    
46    
47     wxDLImports* wxPluginLibrary::ms_classes = NULL;
48    
49     class wxPluginLibraryModule : public wxModule
50     {
51     public:
52     wxPluginLibraryModule() { }
53    
54     // TODO: create ms_classes on demand, why always preallocate it?
55     virtual bool OnInit()
56     {
57     wxPluginLibrary::ms_classes = new wxDLImports;
58     wxPluginManager::CreateManifest();
59     return true;
60     }
61    
62     virtual void OnExit()
63     {
64     delete wxPluginLibrary::ms_classes;
65     wxPluginLibrary::ms_classes = NULL;
66     wxPluginManager::ClearManifest();
67     }
68    
69     private:
70     DECLARE_DYNAMIC_CLASS(wxPluginLibraryModule )
71     };
72    
73     IMPLEMENT_DYNAMIC_CLASS(wxPluginLibraryModule, wxModule)
74    
75    
76     wxPluginLibrary::wxPluginLibrary(const wxString &libname, int flags)
77     : m_linkcount(1)
78     , m_objcount(0)
79     {
80     m_before = wxClassInfo::sm_first;
81     Load( libname, flags );
82     m_after = wxClassInfo::sm_first;
83    
84     if( m_handle != 0 )
85     {
86     UpdateClasses();
87     RegisterModules();
88     }
89     else
90     {
91     // Flag us for deletion
92     --m_linkcount;
93     }
94     }
95    
96     wxPluginLibrary::~wxPluginLibrary()
97     {
98     if( m_handle != 0 )
99     {
100     UnregisterModules();
101     RestoreClasses();
102     }
103     }
104    
105     wxPluginLibrary *wxPluginLibrary::RefLib()
106     {
107     wxCHECK_MSG( m_linkcount > 0, NULL,
108     _T("Library had been already deleted!") );
109    
110     ++m_linkcount;
111     return this;
112     }
113    
114     bool wxPluginLibrary::UnrefLib()
115     {
116     wxASSERT_MSG( m_objcount == 0,
117     _T("Library unloaded before all objects were destroyed") );
118    
119     if ( m_linkcount == 0 || --m_linkcount == 0 )
120     {
121     delete this;
122     return true;
123     }
124    
125     return false;
126     }
127    
128     // ------------------------
129     // Private methods
130     // ------------------------
131    
132     void wxPluginLibrary::UpdateClasses()
133     {
134     for (wxClassInfo *info = m_after; info != m_before; info = info->m_next)
135     {
136     if( info->GetClassName() )
137     {
138     // Hash all the class names into a local table too so
139     // we can quickly find the entry they correspond to.
140     (*ms_classes)[info->GetClassName()] = this;
141     }
142     }
143     }
144    
145     void wxPluginLibrary::RestoreClasses()
146     {
147     // Check if there is a need to restore classes.
148     if (!ms_classes)
149     return;
150    
151     for(wxClassInfo *info = m_after; info != m_before; info = info->m_next)
152     {
153     ms_classes->erase(ms_classes->find(info->GetClassName()));
154     }
155     }
156    
157     void wxPluginLibrary::RegisterModules()
158     {
159     // Plugin libraries might have wxModules, Register and initialise them if
160     // they do.
161     //
162     // Note that these classes are NOT included in the reference counting since
163     // it's implicit that they will be unloaded if and when the last handle to
164     // the library is. We do have to keep a copy of the module's pointer
165     // though, as there is currently no way to Unregister it without it.
166    
167     wxASSERT_MSG( m_linkcount == 1,
168     _T("RegisterModules should only be called for the first load") );
169    
170     for ( wxClassInfo *info = m_after; info != m_before; info = info->m_next)
171     {
172     if( info->IsKindOf(CLASSINFO(wxModule)) )
173     {
174     wxModule *m = wxDynamicCast(info->CreateObject(), wxModule);
175    
176     wxASSERT_MSG( m, _T("wxDynamicCast of wxModule failed") );
177    
178     m_wxmodules.push_back(m);
179     wxModule::RegisterModule(m);
180     }
181     }
182    
183     // FIXME: Likewise this is (well was) very similar to InitializeModules()
184    
185     for ( wxModuleList::iterator it = m_wxmodules.begin();
186     it != m_wxmodules.end();
187     ++it)
188     {
189     if( !(*it)->Init() )
190     {
191     wxLogDebug(_T("wxModule::Init() failed for wxPluginLibrary"));
192    
193     // XXX: Watch this, a different hash implementation might break it,
194     // a good hash implementation would let us fix it though.
195    
196     // The name of the game is to remove any uninitialised modules and
197     // let the dtor Exit the rest on shutdown, (which we'll initiate
198     // shortly).
199    
200     wxModuleList::iterator oldNode = m_wxmodules.end();
201     do {
202     ++it;
203     if( oldNode != m_wxmodules.end() )
204     m_wxmodules.erase(oldNode);
205     wxModule::UnregisterModule( *it );
206     oldNode = it;
207     } while( it != m_wxmodules.end() );
208    
209     --m_linkcount; // Flag us for deletion
210     break;
211     }
212     }
213     }
214    
215     void wxPluginLibrary::UnregisterModules()
216     {
217     wxModuleList::iterator it;
218    
219     for ( it = m_wxmodules.begin(); it != m_wxmodules.end(); ++it )
220     (*it)->Exit();
221    
222     for ( it = m_wxmodules.begin(); it != m_wxmodules.end(); ++it )
223     wxModule::UnregisterModule( *it );
224    
225     // NB: content of the list was deleted by UnregisterModule calls above:
226     m_wxmodules.clear();
227     }
228    
229    
230     // ---------------------------------------------------------------------------
231     // wxPluginManager
232     // ---------------------------------------------------------------------------
233    
234     wxDLManifest* wxPluginManager::ms_manifest = NULL;
235    
236     // ------------------------
237     // Static accessors
238     // ------------------------
239    
240     wxPluginLibrary *
241     wxPluginManager::LoadLibrary(const wxString &libname, int flags)
242     {
243     wxString realname(libname);
244    
245     if( !(flags & wxDL_VERBATIM) )
246     realname += wxDynamicLibrary::GetDllExt();
247    
248     wxPluginLibrary *entry;
249    
250     if ( flags & wxDL_NOSHARE )
251     {
252     entry = NULL;
253     }
254     else
255     {
256     entry = FindByName(realname);
257     }
258    
259     if ( entry )
260     {
261     wxLogTrace(_T("dll"),
262     _T("LoadLibrary(%s): already loaded."), realname.c_str());
263    
264     entry->RefLib();
265     }
266     else
267     {
268     entry = new wxPluginLibrary( libname, flags );
269    
270     if ( entry->IsLoaded() )
271     {
272     (*ms_manifest)[realname] = entry;
273    
274     wxLogTrace(_T("dll"),
275     _T("LoadLibrary(%s): loaded ok."), realname.c_str());
276    
277     }
278     else
279     {
280     wxLogTrace(_T("dll"),
281     _T("LoadLibrary(%s): failed to load."), realname.c_str());
282    
283     // we have created entry just above
284     if ( !entry->UnrefLib() )
285     {
286     // ... so UnrefLib() is supposed to delete it
287     wxFAIL_MSG( _T("Currently linked library is not loaded?") );
288     }
289    
290     entry = NULL;
291     }
292     }
293    
294     return entry;
295     }
296    
297     bool wxPluginManager::UnloadLibrary(const wxString& libname)
298     {
299     wxString realname = libname;
300    
301     wxPluginLibrary *entry = FindByName(realname);
302    
303     if ( !entry )
304     {
305     realname += wxDynamicLibrary::GetDllExt();
306    
307     entry = FindByName(realname);
308     }
309    
310     if ( !entry )
311     {
312     wxLogDebug(_T("Attempt to unload library '%s' which is not loaded."),
313     libname.c_str());
314    
315     return false;
316     }
317    
318     wxLogTrace(_T("dll"), _T("UnloadLibrary(%s)"), realname.c_str());
319    
320     if ( !entry->UnrefLib() )
321     {
322     // not really unloaded yet
323     return false;
324     }
325    
326     ms_manifest->erase(ms_manifest->find(realname));
327    
328     return true;
329     }
330    
331     // ------------------------
332     // Class implementation
333     // ------------------------
334    
335     bool wxPluginManager::Load(const wxString &libname, int flags)
336     {
337     m_entry = wxPluginManager::LoadLibrary(libname, flags);
338    
339     return IsLoaded();
340     }
341    
342     void wxPluginManager::Unload()
343     {
344     wxCHECK_RET( m_entry, _T("unloading an invalid wxPluginManager?") );
345    
346     for ( wxDLManifest::iterator i = ms_manifest->begin();
347     i != ms_manifest->end();
348     ++i )
349     {
350     if ( i->second == m_entry )
351     {
352     ms_manifest->erase(i);
353     break;
354     }
355     }
356    
357     m_entry->UnrefLib();
358    
359     m_entry = NULL;
360     }
361    
362     #endif // wxUSE_DYNAMIC_LOADER

  ViewVC Help
Powered by ViewVC 1.1.22