1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsComponentManager_h__
39 : #define nsComponentManager_h__
40 :
41 : #include "nsXPCOM.h"
42 :
43 : #include "xpcom-private.h"
44 : #include "nsIComponentManager.h"
45 : #include "nsIComponentRegistrar.h"
46 : #include "nsIServiceManager.h"
47 : #include "nsILocalFile.h"
48 : #include "mozilla/Module.h"
49 : #include "mozilla/ModuleLoader.h"
50 : #include "mozilla/ReentrantMonitor.h"
51 : #include "nsXULAppAPI.h"
52 : #include "nsNativeComponentLoader.h"
53 : #include "nsIFactory.h"
54 : #include "nsIInterfaceRequestor.h"
55 : #include "nsIInterfaceRequestorUtils.h"
56 : #include "pldhash.h"
57 : #include "prtime.h"
58 : #include "nsCOMPtr.h"
59 : #include "nsAutoPtr.h"
60 : #include "nsWeakReference.h"
61 : #include "nsIFile.h"
62 : #include "plarena.h"
63 : #include "nsCOMArray.h"
64 : #include "nsDataHashtable.h"
65 : #include "nsInterfaceHashtable.h"
66 : #include "nsClassHashtable.h"
67 : #include "nsTArray.h"
68 :
69 : #include "mozilla/Omnijar.h"
70 :
71 : struct nsFactoryEntry;
72 : class nsIServiceManager;
73 : struct PRThread;
74 :
75 : #define NS_COMPONENTMANAGER_CID \
76 : { /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
77 : 0x91775d60, \
78 : 0xd5dc, \
79 : 0x11d2, \
80 : {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
81 : }
82 :
83 : /* keys for registry use */
84 : extern const char xpcomKeyName[];
85 : extern const char xpcomComponentsKeyName[];
86 : extern const char lastModValueName[];
87 : extern const char fileSizeValueName[];
88 : extern const char nativeComponentType[];
89 : extern const char staticComponentType[];
90 :
91 : #ifdef DEBUG
92 : #define XPCOM_CHECK_PENDING_CIDS
93 : #endif
94 : ////////////////////////////////////////////////////////////////////////////////
95 :
96 : extern const mozilla::Module kXPCOMModule;
97 :
98 : // Array of Loaders and their type strings
99 0 : struct nsLoaderdata {
100 : nsCOMPtr<mozilla::ModuleLoader> loader;
101 : nsCString type;
102 : };
103 :
104 : class nsComponentManagerImpl
105 : : public nsIComponentManager
106 : , public nsIServiceManager
107 : , public nsSupportsWeakReference
108 : , public nsIComponentRegistrar
109 : , public nsIInterfaceRequestor
110 : {
111 : public:
112 : NS_DECL_ISUPPORTS
113 : NS_DECL_NSIINTERFACEREQUESTOR
114 : NS_DECL_NSICOMPONENTMANAGER
115 : NS_DECL_NSICOMPONENTREGISTRAR
116 :
117 : static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
118 :
119 : nsresult RegistryLocationForFile(nsIFile* aFile,
120 : nsCString& aResult);
121 : nsresult FileForRegistryLocation(const nsCString &aLocation,
122 : nsILocalFile **aSpec);
123 :
124 : NS_DECL_NSISERVICEMANAGER
125 :
126 : // nsComponentManagerImpl methods:
127 : nsComponentManagerImpl();
128 :
129 : static nsComponentManagerImpl* gComponentManager;
130 : nsresult Init();
131 :
132 : nsresult Shutdown(void);
133 :
134 : nsresult FreeServices();
135 :
136 : already_AddRefed<mozilla::ModuleLoader> LoaderForExtension(const nsACString& aExt);
137 : nsInterfaceHashtable<nsCStringHashKey, mozilla::ModuleLoader> mLoaderMap;
138 :
139 : already_AddRefed<nsIFactory> FindFactory(const nsCID& aClass);
140 : already_AddRefed<nsIFactory> FindFactory(const char *contractID,
141 : PRUint32 aContractIDLen);
142 :
143 : already_AddRefed<nsIFactory> LoadFactory(nsFactoryEntry *aEntry);
144 :
145 : nsFactoryEntry *GetFactoryEntry(const char *aContractID,
146 : PRUint32 aContractIDLen);
147 : nsFactoryEntry *GetFactoryEntry(const nsCID &aClass);
148 :
149 : nsDataHashtable<nsIDHashKey, nsFactoryEntry*> mFactories;
150 : nsDataHashtable<nsCStringHashKey, nsFactoryEntry*> mContractIDs;
151 :
152 : mozilla::ReentrantMonitor mMon;
153 :
154 : static void InitializeStaticModules();
155 : static void InitializeModuleLocations();
156 :
157 : struct ComponentLocation
158 6460 : {
159 : NSLocationType type;
160 : mozilla::FileLocation location;
161 : };
162 :
163 : class ComponentLocationComparator
164 : {
165 : public:
166 595 : bool Equals(const ComponentLocation& a, const ComponentLocation& b) const
167 : {
168 595 : return (a.type == b.type && a.location.Equals(b.location));
169 : }
170 : };
171 :
172 : static nsTArray<const mozilla::Module*>* sStaticModules;
173 : static nsTArray<ComponentLocation>* sModuleLocations;
174 :
175 : nsNativeModuleLoader mNativeModuleLoader;
176 :
177 : class KnownModule
178 : {
179 : public:
180 : /**
181 : * Static or binary module.
182 : */
183 5679 : KnownModule(const mozilla::Module* aModule, mozilla::FileLocation &aFile)
184 : : mModule(aModule)
185 : , mFile(aFile)
186 : , mLoaded(false)
187 5679 : , mFailed(false)
188 5679 : { }
189 :
190 78045 : KnownModule(const mozilla::Module* aModule)
191 : : mModule(aModule)
192 : , mLoaded(false)
193 78045 : , mFailed(false)
194 78045 : { }
195 :
196 100771 : KnownModule(mozilla::FileLocation &aFile)
197 : : mModule(NULL)
198 : , mFile(aFile)
199 : , mLoader(NULL)
200 : , mLoaded(false)
201 100771 : , mFailed(false)
202 100771 : { }
203 :
204 184495 : ~KnownModule()
205 184495 : {
206 184495 : if (mLoaded && mModule->unloadProc)
207 13218 : mModule->unloadProc();
208 184495 : }
209 :
210 : bool EnsureLoader();
211 : bool Load();
212 :
213 106280 : const mozilla::Module* Module() const
214 : {
215 106280 : return mModule;
216 : }
217 :
218 : /**
219 : * For error logging, get a description of this module, either the
220 : * file path, or <static module>.
221 : */
222 : nsCString Description() const;
223 :
224 : private:
225 : const mozilla::Module* mModule;
226 : mozilla::FileLocation mFile;
227 : nsCOMPtr<mozilla::ModuleLoader> mLoader;
228 : bool mLoaded;
229 : bool mFailed;
230 : };
231 :
232 : // The KnownModule is kept alive by these members, it is
233 : // referenced by pointer from the factory entries.
234 : nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules;
235 : // The key is the URI string of the module
236 : nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules;
237 :
238 : void RegisterModule(const mozilla::Module* aModule,
239 : mozilla::FileLocation* aFile);
240 : void RegisterCIDEntry(const mozilla::Module::CIDEntry* aEntry,
241 : KnownModule* aModule);
242 : void RegisterContractID(const mozilla::Module::ContractIDEntry* aEntry);
243 :
244 : void RegisterManifest(NSLocationType aType, mozilla::FileLocation &aFile,
245 : bool aChromeOnly);
246 :
247 : struct ManifestProcessingContext
248 : {
249 99082 : ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile, bool aChromeOnly)
250 : : mType(aType)
251 : , mFile(aFile)
252 99082 : , mChromeOnly(aChromeOnly)
253 99082 : { }
254 :
255 99082 : ~ManifestProcessingContext() { }
256 :
257 : NSLocationType mType;
258 : mozilla::FileLocation mFile;
259 : bool mChromeOnly;
260 : };
261 :
262 : void ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv);
263 : void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
264 : void ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv);
265 : void ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
266 : void ManifestContract(ManifestProcessingContext& cx, int lineno, char* const * argv);
267 : void ManifestCategory(ManifestProcessingContext& cx, int lineno, char* const * argv);
268 :
269 : void RereadChromeManifests(bool aChromeOnly = true);
270 :
271 : // Shutdown
272 : enum {
273 : NOT_INITIALIZED,
274 : NORMAL,
275 : SHUTDOWN_IN_PROGRESS,
276 : SHUTDOWN_COMPLETE
277 : } mStatus;
278 :
279 : nsTArray<nsLoaderdata> mLoaderData;
280 :
281 : PLArenaPool mArena;
282 :
283 77872 : struct PendingServiceInfo {
284 : const nsCID* cid;
285 : PRThread* thread;
286 : };
287 :
288 : inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID,
289 : PRThread* aThread);
290 : inline void RemovePendingService(const nsCID& aServiceCID);
291 : inline PRThread* GetPendingServiceThread(const nsCID& aServiceCID) const;
292 :
293 : nsTArray<PendingServiceInfo> mPendingServices;
294 :
295 : private:
296 : ~nsComponentManagerImpl();
297 : };
298 :
299 :
300 : #define NS_MAX_FILENAME_LEN 1024
301 :
302 : #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
303 :
304 : struct nsFactoryEntry
305 : {
306 : nsFactoryEntry(const mozilla::Module::CIDEntry* entry,
307 : nsComponentManagerImpl::KnownModule* module);
308 :
309 : // nsIComponentRegistrar.registerFactory support
310 : nsFactoryEntry(const nsCID& aClass, nsIFactory* factory);
311 :
312 : ~nsFactoryEntry();
313 :
314 : already_AddRefed<nsIFactory> GetFactory();
315 :
316 : const mozilla::Module::CIDEntry* mCIDEntry;
317 : nsComponentManagerImpl::KnownModule* mModule;
318 :
319 : nsCOMPtr<nsIFactory> mFactory;
320 : nsCOMPtr<nsISupports> mServiceObject;
321 : };
322 :
323 : #endif // nsComponentManager_h__
|