Kill off allCatalogs list.

No longer needed, and fixes crash on shutdown.
This commit is contained in:
James Turner
2015-02-20 11:31:15 +00:00
parent e5995208a9
commit 611785c04b
3 changed files with 83 additions and 95 deletions
+31 -41
View File
@@ -33,10 +33,8 @@
#include <simgear/package/Install.hxx> #include <simgear/package/Install.hxx>
namespace simgear { namespace simgear {
namespace pkg {
CatalogList static_catalogs; namespace pkg {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -46,25 +44,25 @@ public:
Downloader(CatalogRef aOwner, const std::string& aUrl) : Downloader(CatalogRef aOwner, const std::string& aUrl) :
HTTP::Request(aUrl), HTTP::Request(aUrl),
m_owner(aOwner) m_owner(aOwner)
{ {
} }
protected: protected:
virtual void gotBodyData(const char* s, int n) virtual void gotBodyData(const char* s, int n)
{ {
m_buffer += std::string(s, n); m_buffer += std::string(s, n);
} }
virtual void onDone() virtual void onDone()
{ {
if (responseCode() != 200) { if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url()); SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url());
m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD); m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD);
return; return;
} }
SGPropertyNode* props = new SGPropertyNode; SGPropertyNode* props = new SGPropertyNode;
try { try {
readProperties(m_buffer.data(), m_buffer.size(), props); readProperties(m_buffer.data(), m_buffer.size(), props);
m_owner->parseProps(props); m_owner->parseProps(props);
@@ -73,7 +71,7 @@ protected:
m_owner->refreshComplete(Delegate::FAIL_EXTRACT); m_owner->refreshComplete(Delegate::FAIL_EXTRACT);
return; return;
} }
std::string ver(m_owner->root()->catalogVersion()); std::string ver(m_owner->root()->catalogVersion());
if (!checkVersion(ver, props)) { if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t" SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
@@ -81,7 +79,7 @@ protected:
m_owner->refreshComplete(Delegate::FAIL_VERSION); m_owner->refreshComplete(Delegate::FAIL_VERSION);
return; return;
} }
// cache the catalog data, now we have a valid install root // cache the catalog data, now we have a valid install root
Dir d(m_owner->installRoot()); Dir d(m_owner->installRoot());
SGPath p = d.file("catalog.xml"); SGPath p = d.file("catalog.xml");
@@ -89,12 +87,12 @@ protected:
std::ofstream f(p.c_str(), std::ios::out | std::ios::trunc); std::ofstream f(p.c_str(), std::ios::out | std::ios::trunc);
f.write(m_buffer.data(), m_buffer.size()); f.write(m_buffer.data(), m_buffer.size());
f.close(); f.close();
time(&m_owner->m_retrievedTime); time(&m_owner->m_retrievedTime);
m_owner->writeTimestamp(); m_owner->writeTimestamp();
m_owner->refreshComplete(Delegate::FAIL_SUCCESS); m_owner->refreshComplete(Delegate::FAIL_SUCCESS);
} }
private: private:
bool checkVersion(const std::string& aVersion, SGPropertyNode* aProps) bool checkVersion(const std::string& aVersion, SGPropertyNode* aProps)
{ {
@@ -105,29 +103,21 @@ private:
} }
return false; return false;
} }
CatalogRef m_owner; CatalogRef m_owner;
std::string m_buffer; std::string m_buffer;
}; };
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
CatalogList Catalog::allCatalogs()
{
return static_catalogs;
}
Catalog::Catalog(Root *aRoot) : Catalog::Catalog(Root *aRoot) :
m_root(aRoot), m_root(aRoot),
m_retrievedTime(0) m_retrievedTime(0)
{ {
static_catalogs.push_back(this);
} }
Catalog::~Catalog() Catalog::~Catalog()
{ {
CatalogList::iterator it = std::find(static_catalogs.begin(), static_catalogs.end(), this);
static_catalogs.erase(it);
} }
CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl) CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl)
@@ -136,10 +126,10 @@ CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl)
c->m_url = aUrl; c->m_url = aUrl;
Downloader* dl = new Downloader(c, aUrl); Downloader* dl = new Downloader(c, aUrl);
aRoot->makeHTTPRequest(dl); aRoot->makeHTTPRequest(dl);
return c; return c;
} }
CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath) CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
{ {
SGPath xml = aPath; SGPath xml = aPath;
@@ -147,26 +137,26 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
if (!xml.exists()) { if (!xml.exists()) {
return NULL; return NULL;
} }
SGPropertyNode_ptr props; SGPropertyNode_ptr props;
try { try {
props = new SGPropertyNode; props = new SGPropertyNode;
readProperties(xml.str(), props); readProperties(xml.str(), props);
} catch (sg_exception& e) { } catch (sg_exception& e) {
return NULL; return NULL;
} }
if (props->getStringValue("version") != aRoot->catalogVersion()) { if (props->getStringValue("version") != aRoot->catalogVersion()) {
SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t" SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t"
<< props->getStringValue("version") << " vs required " << aRoot->catalogVersion()); << props->getStringValue("version") << " vs required " << aRoot->catalogVersion());
return NULL; return NULL;
} }
CatalogRef c = new Catalog(aRoot); CatalogRef c = new Catalog(aRoot);
c->m_installRoot = aPath; c->m_installRoot = aPath;
c->parseProps(props); c->parseProps(props);
c->parseTimestamp(); c->parseTimestamp();
return c; return c;
} }
@@ -196,7 +186,7 @@ Catalog::packagesNeedingUpdate() const
if (!p->isInstalled()) { if (!p->isInstalled()) {
continue; continue;
} }
if (p->install()->hasUpdate()) { if (p->install()->hasUpdate()) {
r.push_back(p); r.push_back(p);
} }
@@ -215,7 +205,7 @@ Catalog::installedPackages() const
} }
return r; return r;
} }
InstallRef Catalog::installForPackage(PackageRef pkg) const InstallRef Catalog::installForPackage(PackageRef pkg) const
{ {
PackageInstallDict::const_iterator it = m_installed.find(pkg); PackageInstallDict::const_iterator it = m_installed.find(pkg);
@@ -226,13 +216,13 @@ InstallRef Catalog::installForPackage(PackageRef pkg) const
if (p.exists()) { if (p.exists()) {
return Install::createFromPath(p, CatalogRef(const_cast<Catalog*>(this))); return Install::createFromPath(p, CatalogRef(const_cast<Catalog*>(this)));
} }
return NULL; return NULL;
} }
return it->second; return it->second;
} }
void Catalog::refresh() void Catalog::refresh()
{ {
Downloader* dl = new Downloader(this, url()); Downloader* dl = new Downloader(this, url());
@@ -294,13 +284,13 @@ void Catalog::parseProps(const SGPropertyNode* aProps)
<< " is now at: " << m_props->getStringValue("url")); << " is now at: " << m_props->getStringValue("url"));
} }
} }
m_url = m_props->getStringValue("url"); m_url = m_props->getStringValue("url");
if (m_installRoot.isNull()) { if (m_installRoot.isNull()) {
m_installRoot = m_root->path(); m_installRoot = m_root->path();
m_installRoot.append(id()); m_installRoot.append(id());
Dir d(m_installRoot); Dir d(m_installRoot);
d.create(0755); d.create(0755);
} }
@@ -331,7 +321,7 @@ std::string Catalog::description() const
{ {
return getLocalisedString(m_props, "description"); return getLocalisedString(m_props, "description");
} }
SGPropertyNode* Catalog::properties() const SGPropertyNode* Catalog::properties() const
{ {
return m_props.ptr(); return m_props.ptr();
@@ -366,7 +356,7 @@ bool Catalog::needsRefresh() const
unsigned int maxAge = m_props->getIntValue("max-age-sec", m_root->maxAgeSeconds()); unsigned int maxAge = m_props->getIntValue("max-age-sec", m_root->maxAgeSeconds());
return (ageInSeconds() > maxAge); return (ageInSeconds() > maxAge);
} }
std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
{ {
if (aRoot->hasChild(m_root->getLocale())) { if (aRoot->hasChild(m_root->getLocale())) {
@@ -375,7 +365,7 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
return localeRoot->getStringValue(aName); return localeRoot->getStringValue(aName);
} }
} }
return aRoot->getStringValue(aName); return aRoot->getStringValue(aName);
} }
@@ -389,7 +379,7 @@ void Catalog::registerInstall(Install* ins)
if (!ins || ins->package()->catalog() != this) { if (!ins || ins->package()->catalog() != this) {
return; return;
} }
m_installed[ins->package()] = ins; m_installed[ins->package()] = ins;
} }
@@ -398,7 +388,7 @@ void Catalog::unregisterInstall(Install* ins)
if (!ins || ins->package()->catalog() != this) { if (!ins || ins->package()->catalog() != this) {
return; return;
} }
m_installed.erase(ins->package()); m_installed.erase(ins->package());
} }
+27 -29
View File
@@ -32,9 +32,9 @@
namespace simgear namespace simgear
{ {
namespace HTTP { class Client; } namespace HTTP { class Client; }
namespace pkg namespace pkg
{ {
@@ -43,11 +43,11 @@ class Package;
class Catalog; class Catalog;
class Root; class Root;
class Install; class Install;
typedef SGSharedPtr<Package> PackageRef; typedef SGSharedPtr<Package> PackageRef;
typedef SGSharedPtr<Catalog> CatalogRef; typedef SGSharedPtr<Catalog> CatalogRef;
typedef SGSharedPtr<Install> InstallRef; typedef SGSharedPtr<Install> InstallRef;
typedef std::vector<PackageRef> PackageList; typedef std::vector<PackageRef> PackageList;
typedef std::vector<CatalogRef> CatalogList; typedef std::vector<CatalogRef> CatalogList;
@@ -55,16 +55,14 @@ class Catalog : public SGReferenced
{ {
public: public:
virtual ~Catalog(); virtual ~Catalog();
static CatalogRef createFromUrl(Root* aRoot, const std::string& aUrl); static CatalogRef createFromUrl(Root* aRoot, const std::string& aUrl);
static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath); static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath);
static CatalogList allCatalogs();
Root* root() const Root* root() const
{ return m_root;}; { return m_root;};
/** /**
* perform a refresh of the catalog contents * perform a refresh of the catalog contents
*/ */
@@ -89,53 +87,53 @@ public:
/** /**
* retrieve all the packages in the catalog which are installed * retrieve all the packages in the catalog which are installed
* and have a pendig update * and have a pendig update
*/ */
PackageList packagesNeedingUpdate() const; PackageList packagesNeedingUpdate() const;
SGPath installRoot() const SGPath installRoot() const
{ return m_installRoot; } { return m_installRoot; }
std::string id() const; std::string id() const;
std::string url() const; std::string url() const;
std::string description() const; std::string description() const;
PackageRef getPackageById(const std::string& aId) const; PackageRef getPackageById(const std::string& aId) const;
InstallRef installForPackage(PackageRef pkg) const; InstallRef installForPackage(PackageRef pkg) const;
/** /**
* test if the catalog data was retrieved longer ago than the * test if the catalog data was retrieved longer ago than the
* maximum permitted age for this catalog. * maximum permitted age for this catalog.
*/ */
bool needsRefresh() const; bool needsRefresh() const;
unsigned int ageInSeconds() const; unsigned int ageInSeconds() const;
/** /**
* access the raw property data in the catalog * access the raw property data in the catalog
*/ */
SGPropertyNode* properties() const; SGPropertyNode* properties() const;
private: private:
Catalog(Root* aRoot); Catalog(Root* aRoot);
class Downloader; class Downloader;
friend class Downloader; friend class Downloader;
friend class Install; friend class Install;
void registerInstall(Install* ins); void registerInstall(Install* ins);
void unregisterInstall(Install* ins); void unregisterInstall(Install* ins);
void parseProps(const SGPropertyNode* aProps); void parseProps(const SGPropertyNode* aProps);
void refreshComplete(Delegate::FailureCode aReason); void refreshComplete(Delegate::FailureCode aReason);
void parseTimestamp(); void parseTimestamp();
void writeTimestamp(); void writeTimestamp();
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
Root* m_root; Root* m_root;
SGPropertyNode_ptr m_props; SGPropertyNode_ptr m_props;
SGPath m_installRoot; SGPath m_installRoot;
@@ -146,13 +144,13 @@ private:
typedef std::map<std::string, Package*> PackageWeakMap; typedef std::map<std::string, Package*> PackageWeakMap;
PackageWeakMap m_variantDict; PackageWeakMap m_variantDict;
// important that this is a weak-ref to Installs, // important that this is a weak-ref to Installs,
// since it is only cleaned up in the Install destructor // since it is only cleaned up in the Install destructor
typedef std::map<PackageRef, Install*> PackageInstallDict; typedef std::map<PackageRef, Install*> PackageInstallDict;
PackageInstallDict m_installed; PackageInstallDict m_installed;
}; };
} // of namespace pkg } // of namespace pkg
} // of namespace simgear } // of namespace simgear
+25 -25
View File
@@ -26,7 +26,7 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
using namespace simgear; using namespace simgear;
using namespace std; using namespace std;
bool keepRunning = true; bool keepRunning = true;
@@ -37,29 +37,29 @@ public:
virtual void refreshComplete() virtual void refreshComplete()
{ {
} }
virtual void failedRefresh(pkg::Catalog* aCatalog, FailureCode aReason) virtual void failedRefresh(pkg::Catalog* aCatalog, FailureCode aReason)
{ {
cerr << "failed refresh of " << aCatalog->description() << ":" << aReason << endl; cerr << "failed refresh of " << aCatalog->description() << ":" << aReason << endl;
} }
virtual void startInstall(pkg::Install* aInstall) virtual void startInstall(pkg::Install* aInstall)
{ {
_lastPercent = 999; _lastPercent = 999;
cout << "starting install of " << aInstall->package()->name() << endl; cout << "starting install of " << aInstall->package()->name() << endl;
} }
virtual void installProgress(pkg::Install* aInstall, unsigned int bytes, unsigned int total) virtual void installProgress(pkg::Install* aInstall, unsigned int bytes, unsigned int total)
{ {
unsigned int percent = (bytes * 100) / total; unsigned int percent = (bytes * 100) / total;
if (percent == _lastPercent) { if (percent == _lastPercent) {
return; return;
} }
_lastPercent = percent; _lastPercent = percent;
cout << percent << "%" << endl; cout << percent << "%" << endl;
} }
virtual void finishInstall(pkg::Install* aInstall) virtual void finishInstall(pkg::Install* aInstall)
{ {
cout << "done install of " << aInstall->package()->name() << endl; cout << "done install of " << aInstall->package()->name() << endl;
@@ -71,7 +71,7 @@ public:
} }
private: private:
unsigned int _lastPercent; unsigned int _lastPercent;
}; };
void printRating(pkg::Package* pkg, const std::string& aRating, const std::string& aLabel) void printRating(pkg::Package* pkg, const std::string& aRating, const std::string& aLabel)
@@ -87,24 +87,24 @@ void printPackageInfo(pkg::Package* pkg)
cout << "Name:" << pkg->name() << endl; cout << "Name:" << pkg->name() << endl;
cout << "Description:" << pkg->description() << endl; cout << "Description:" << pkg->description() << endl;
cout << "Long description:\n" << pkg->getLocalisedProp("long-description") << endl << endl; cout << "Long description:\n" << pkg->getLocalisedProp("long-description") << endl << endl;
if (pkg->properties()->hasChild("author")) { if (pkg->properties()->hasChild("author")) {
cout << "Authors:" << endl; cout << "Authors:" << endl;
BOOST_FOREACH(SGPropertyNode* author, pkg->properties()->getChildren("author")) { BOOST_FOREACH(SGPropertyNode* author, pkg->properties()->getChildren("author")) {
if (author->hasChild("name")) { if (author->hasChild("name")) {
cout << "\t" << author->getStringValue("name") << endl; cout << "\t" << author->getStringValue("name") << endl;
} else { } else {
// simple author structure // simple author structure
cout << "\t" << author->getStringValue() << endl; cout << "\t" << author->getStringValue() << endl;
} }
} }
cout << endl; cout << endl;
} }
cout << "Ratings:" << endl; cout << "Ratings:" << endl;
printRating(pkg, "fdm", "Flight-model "); printRating(pkg, "fdm", "Flight-model ");
printRating(pkg, "cockpit", "Cockpit "); printRating(pkg, "cockpit", "Cockpit ");
@@ -117,15 +117,15 @@ int main(int argc, char** argv)
HTTP::Client* http = new HTTP::Client(); HTTP::Client* http = new HTTP::Client();
pkg::Root* root = new pkg::Root(Dir::current().path(), ""); pkg::Root* root = new pkg::Root(Dir::current().path(), "");
MyDelegate dlg; MyDelegate dlg;
root->setDelegate(&dlg); root->setDelegate(&dlg);
cout << "Package root is:" << Dir::current().path() << endl; cout << "Package root is:" << Dir::current().path() << endl;
cout << "have " << pkg::Catalog::allCatalogs().size() << " catalog(s)" << endl; cout << "have " << root->catalogs().size() << " catalog(s)" << endl;
root->setHTTPClient(http); root->setHTTPClient(http);
if (!strcmp(argv[1], "add")) { if (!strcmp(argv[1], "add")) {
std::string url(argv[2]); std::string url(argv[2]);
pkg::Catalog::createFromUrl(root, url); pkg::Catalog::createFromUrl(root, url);
@@ -137,12 +137,12 @@ int main(int argc, char** argv)
cerr << "unknown package:" << argv[2] << endl; cerr << "unknown package:" << argv[2] << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (pkg->isInstalled()) { if (pkg->isInstalled()) {
cout << "package " << pkg->id() << " is already installed at " << pkg->install()->path() << endl; cout << "package " << pkg->id() << " is already installed at " << pkg->install()->path() << endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
pkg::CatalogRef catalog = pkg->catalog(); pkg::CatalogRef catalog = pkg->catalog();
cout << "Will install:" << pkg->id() << " from " << catalog->id() << cout << "Will install:" << pkg->id() << " from " << catalog->id() <<
"(" << catalog->description() << ")" << endl; "(" << catalog->description() << ")" << endl;
@@ -153,12 +153,12 @@ int main(int argc, char** argv)
cerr << "unknown package:" << argv[2] << endl; cerr << "unknown package:" << argv[2] << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!pkg->isInstalled()) { if (!pkg->isInstalled()) {
cerr << "package " << argv[2] << " not installed" << endl; cerr << "package " << argv[2] << " not installed" << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
cout << "Will uninstall:" << pkg->id() << endl; cout << "Will uninstall:" << pkg->id() << endl;
pkg->install()->uninstall(); pkg->install()->uninstall();
} else if (!strcmp(argv[1], "update-all")) { } else if (!strcmp(argv[1], "update-all")) {
@@ -172,7 +172,7 @@ int main(int argc, char** argv)
cout << "no packages with updates" << endl; cout << "no packages with updates" << endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
cout << updates.size() << " packages have updates" << endl; cout << updates.size() << " packages have updates" << endl;
BOOST_FOREACH(pkg::Package* p, updates) { BOOST_FOREACH(pkg::Package* p, updates) {
cout << "\t" << p->id() << " " << p->getLocalisedProp("name") << endl; cout << "\t" << p->id() << " " << p->getLocalisedProp("name") << endl;
@@ -183,13 +183,13 @@ int main(int argc, char** argv)
cerr << "unknown package:" << argv[2] << endl; cerr << "unknown package:" << argv[2] << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printPackageInfo(pkg); printPackageInfo(pkg);
} else { } else {
cerr << "unknown command:" << argv[1] << endl; cerr << "unknown command:" << argv[1] << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
while (http->hasActiveRequests()) { while (http->hasActiveRequests()) {
http->update(); http->update();
} }