88#include < iostream>
99#include < fstream>
1010
11+ namespace
12+ {
1113std::shared_ptr<IManifest> instance;
12- std::once_flag initFlag;
14+ std::mutex instanceMutex;
15+ }
1316
1417class Manifest : public IManifest
1518{
@@ -19,6 +22,47 @@ class Manifest : public IManifest
1922 Owned<IPropertyTree> manifest;
2023 StringBuffer manifestDir;
2124
25+ bool loadManifestFromDll (const char *dllname, bool resourcesOnly)
26+ {
27+ if (!dllname || !*dllname)
28+ return false ;
29+
30+ if (resourcesOnly)
31+ dll.setown (queryDllServer ().loadDllResources (dllname, DllLocationAnywhere));
32+ else
33+ dll.setown (queryDllServer ().loadDll (dllname, DllLocationAnywhere));
34+
35+ if (!dll)
36+ return false ;
37+
38+ StringBuffer xml;
39+ manifest.setown (getEmbeddedManifestXML (dll, xml) ? createPTreeFromXMLString (xml.str ()) : createPTree ());
40+ manifestDir.set (manifest->queryProp (" @manifestDir" ));
41+ return true ;
42+ }
43+
44+ bool tryFallbackLoad (const char *dllname)
45+ {
46+ try
47+ {
48+ // Fallback for platforms where resource-only loading is not implemented.
49+ if (!loadManifestFromDll (dllname, false ))
50+ DBGLOG (" Fallback load failed for %s" , dllname);
51+ return !!dll;
52+ }
53+ catch (IException *e)
54+ {
55+ VStringBuffer msg (" Fallback load failed for %s" , dllname);
56+ EXCLOG (e, msg.str ());
57+ e->Release ();
58+ }
59+ catch (...)
60+ {
61+ DBGLOG (" Fallback load failed for %s" , dllname);
62+ }
63+ return false ;
64+ }
65+
2266 static IConstWorkUnit *getWorkunit (ICodeContext *ctx)
2367 {
2468 Owned<IWorkUnitFactory> factory = getWorkUnitFactory ();
@@ -36,12 +80,10 @@ class Manifest : public IManifest
3680 q->getQueryDllName (dllname);
3781 if (dllname.length ())
3882 {
83+ bool loaded = false ;
3984 try
4085 {
41- dll.setown (queryDllServer ().loadDllResources (dllname.str (), DllLocationAnywhere));
42- StringBuffer xml;
43- manifest.setown (getEmbeddedManifestXML (dll, xml) ? createPTreeFromXMLString (xml.str ()) : createPTree ());
44- manifestDir.set (manifest->queryProp (" @manifestDir" ));
86+ loaded = loadManifestFromDll (dllname.str (), true );
4587 }
4688 catch (IException *e)
4789 {
@@ -53,6 +95,9 @@ class Manifest : public IManifest
5395 {
5496 DBGLOG (" Failed to load %s" , dllname.str ());
5597 }
98+
99+ if (!loaded)
100+ tryFallbackLoad (dllname.str ());
56101 }
57102 }
58103
@@ -72,8 +117,9 @@ class Manifest : public IManifest
72117
73118 static std::shared_ptr<IManifest> getInstance (ICodeContext *ctx)
74119 {
75- std::call_once (initFlag, [ctx]()
76- { instance = std::shared_ptr<Manifest>(new Manifest (ctx)); });
120+ std::lock_guard<std::mutex> lock (instanceMutex);
121+ if (!instance)
122+ instance = std::shared_ptr<Manifest>(new Manifest (ctx));
77123 return instance;
78124 }
79125
@@ -144,6 +190,9 @@ class Manifest : public IManifest
144190 // --- IManifest ---
145191 virtual const char *extractResources (StringBuffer &sb) const
146192 {
193+ if (!dll)
194+ return sb.str ();
195+
147196 // dll->queryManifestFiles extracts the manifest files to a tmp folder the paths as a StringArray
148197 const StringArray &resFiles = dll->queryManifestFiles (" UNKNOWN" , " nlp" );
149198 if (resFiles.length () > 0 )
@@ -161,6 +210,9 @@ class Manifest : public IManifest
161210
162211 virtual bool getResourceData (const char *partialPath, MemoryBuffer &mb) const
163212 {
213+ if (!dll)
214+ return false ;
215+
164216 Linked<IPropertyTree> res = queryResourcePT (partialPath);
165217 if (!res)
166218 return false ;
0 commit comments