From 64bc79d1f68dc2fff39d603ef1da45fc532bb24d Mon Sep 17 00:00:00 2001 From: randomdan Date: Fri, 11 Feb 2011 17:05:22 +0000 Subject: Don't rely on crazy dangerous global init/destroy for loader registration --- project2/dumpTask.cpp | 2 +- project2/fileRows.cpp | 2 +- project2/fsRows.cpp | 2 +- project2/if.cpp | 2 +- project2/iterate.cpp | 2 +- project2/procRows.cpp | 2 +- project2/rawView.cpp | 2 +- project2/rdbmsDataSource.cpp | 6 ++--- project2/regexCheck.cpp | 2 +- project2/rowView.cpp | 2 +- project2/sendmailTask.cpp | 2 +- project2/sessionClearTask.cpp | 2 +- project2/sessionSetTask.cpp | 2 +- project2/sqlCheck.cpp | 2 +- project2/sqlMergeTask.cpp | 4 +-- project2/sqlRows.cpp | 2 +- project2/sqlTask.cpp | 2 +- project2/urlRows.cpp | 2 +- project2/xmlObjectLoader.cpp | 57 ++++++++++++++++++++++++++++++------------- project2/xmlObjectLoader.h | 33 ++++++++++++------------- project2/xmlRows.cpp | 2 +- project2/xslRows.cpp | 2 +- 22 files changed, 77 insertions(+), 59 deletions(-) diff --git a/project2/dumpTask.cpp b/project2/dumpTask.cpp index cdf8c1b..b266821 100644 --- a/project2/dumpTask.cpp +++ b/project2/dumpTask.cpp @@ -5,7 +5,7 @@ #include #include -ElementLoaderImpl dumptaskLoader("dumptask"); +DECLARE_LOADER("dumptask", DumpTask); DumpTask::DumpTask(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/fileRows.cpp b/project2/fileRows.cpp index 4a3c58b..315c987 100644 --- a/project2/fileRows.cpp +++ b/project2/fileRows.cpp @@ -4,7 +4,7 @@ #include "exceptions.h" #include -ElementLoaderImpl filerowsLoader("filerows"); +DECLARE_LOADER("filerows", FileRows); FileRows::FileRows(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/fsRows.cpp b/project2/fsRows.cpp index ca901c8..327d9f4 100644 --- a/project2/fsRows.cpp +++ b/project2/fsRows.cpp @@ -16,7 +16,7 @@ typedef boost::filesystem::basic_directory_iterator DirEnt; -ElementLoaderImpl fsrowsLoader("fsrows"); +DECLARE_LOADER("fsrows", FsRows); const Glib::ustring field_absPath("absPath"); const Glib::ustring field_relPath("relPath"); diff --git a/project2/if.cpp b/project2/if.cpp index 647c0d0..9d367bf 100644 --- a/project2/if.cpp +++ b/project2/if.cpp @@ -2,7 +2,7 @@ #include "logger.h" #include "xmlObjectLoader.h" -ElementLoaderImpl ifLoader("if"); +DECLARE_LOADER("if", If); class IfModeIsNonsense : public std::exception { }; diff --git a/project2/iterate.cpp b/project2/iterate.cpp index cdb0cc6..fa0bd77 100644 --- a/project2/iterate.cpp +++ b/project2/iterate.cpp @@ -2,7 +2,7 @@ #include #include "xmlObjectLoader.h" -ElementLoaderImpl iterateLoader("iterate"); +DECLARE_LOADER("iterate", Iterate); Iterate::Iterate(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/procRows.cpp b/project2/procRows.cpp index c3ae6aa..11ae35e 100644 --- a/project2/procRows.cpp +++ b/project2/procRows.cpp @@ -2,7 +2,7 @@ #include "xmlObjectLoader.h" #include -ElementLoaderImpl procrowsLoader("procrows"); +DECLARE_LOADER("procrows", ProcRows); class SubProcessFailedToStart : public std::exception { }; class SubProcessFailed : public std::exception { }; diff --git a/project2/rawView.cpp b/project2/rawView.cpp index 595890b..325460a 100644 --- a/project2/rawView.cpp +++ b/project2/rawView.cpp @@ -5,7 +5,7 @@ #include "environment.h" #include "appEngine.h" -ElementLoaderImpl rawviewLoader("rawview"); +DECLARE_LOADER("rawview", RawView); RawView::RawView(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp index 0c37814..ac63042 100644 --- a/project2/rdbmsDataSource.cpp +++ b/project2/rdbmsDataSource.cpp @@ -20,9 +20,6 @@ class UnknownConnectionProvider : public std::exception { }; class RdbmsDataSourceLoader : public ElementLoaderImpl { public: - RdbmsDataSourceLoader() : ElementLoaderImpl("rdbmsdatasource") - { - } void onIdle() { // Disconnect all cached database connections @@ -44,7 +41,8 @@ class RdbmsDataSourceLoader : public ElementLoaderImpl { { RdbmsDataSource::changedDSNs.clear(); } -} rdbmsLoader; +}; +DECLARE_CUSTOM_LOADER("rdbmsdatasource", RdbmsDataSourceLoader); RdbmsDataSource::DBHosts RdbmsDataSource::dbhosts; RdbmsDataSource::FailedHosts RdbmsDataSource::failedhosts; diff --git a/project2/regexCheck.cpp b/project2/regexCheck.cpp index 08b1e75..5588673 100644 --- a/project2/regexCheck.cpp +++ b/project2/regexCheck.cpp @@ -3,7 +3,7 @@ #include "commonObjects.h" #include -ElementLoaderImpl regexCheckLoader("regexcheck"); +DECLARE_LOADER("regexcheck", RegexCheck); RegexCheck::RegexCheck(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/rowView.cpp b/project2/rowView.cpp index 9d69e9a..f6e7b67 100644 --- a/project2/rowView.cpp +++ b/project2/rowView.cpp @@ -2,7 +2,7 @@ #include "presenter.h" #include -ElementLoaderImpl viewLoader("view"); +DECLARE_LOADER("view", RowView); RowView::RowView(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp index 7e2242b..7f1274e 100644 --- a/project2/sendmailTask.cpp +++ b/project2/sendmailTask.cpp @@ -10,7 +10,7 @@ #include #include -ElementLoaderImpl sendmailLoader("sendmail"); +DECLARE_LOADER("sendmail", SendMailTask); class SendEmailFailed : public std::runtime_error { public: diff --git a/project2/sessionClearTask.cpp b/project2/sessionClearTask.cpp index 57a4512..15ba270 100644 --- a/project2/sessionClearTask.cpp +++ b/project2/sessionClearTask.cpp @@ -4,7 +4,7 @@ #include "appEngine.h" #include "session.h" -ElementLoaderImpl sessionclearLoader("sessionclear"); +DECLARE_LOADER("sessionclear", SessionClearTask); SessionClearTask::SessionClearTask(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/sessionSetTask.cpp b/project2/sessionSetTask.cpp index 401604b..4ae344f 100644 --- a/project2/sessionSetTask.cpp +++ b/project2/sessionSetTask.cpp @@ -4,7 +4,7 @@ #include "appEngine.h" #include "session.h" -ElementLoaderImpl sessionsetLoader("sessionset"); +DECLARE_LOADER("sessionset", SessionSetTask); SessionSetTask::SessionSetTask(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp index afb880a..458aa90 100644 --- a/project2/sqlCheck.cpp +++ b/project2/sqlCheck.cpp @@ -7,7 +7,7 @@ #include "commonObjects.h" #include "sqlVariableBinder.h" -ElementLoaderImpl sqlCheckLoader("sqlcheck"); +DECLARE_LOADER("sqlcheck", SqlCheck); SqlCheck::SqlCheck(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp index 0008f72..b37cbf6 100644 --- a/project2/sqlMergeTask.cpp +++ b/project2/sqlMergeTask.cpp @@ -34,8 +34,8 @@ class SqlMergeInsert : public IHaveParameters, public virtual SourceObject, publ ModifyCommand * insert; }; -ElementLoaderImpl sqlmergeLoader("sqlmerge"); -ElementLoaderImpl sqlmergeinsertLoader("sqlmergeinsert"); +DECLARE_LOADER("sqlmerge", SqlMergeTask); +DECLARE_LOADER("sqlmergeinsert", SqlMergeInsert); // Conversion logic SqlMergeTask::SqlMergeTask(const xmlpp::Element * p) : diff --git a/project2/sqlRows.cpp b/project2/sqlRows.cpp index 4758dd4..2a162ab 100644 --- a/project2/sqlRows.cpp +++ b/project2/sqlRows.cpp @@ -12,7 +12,7 @@ #include #include -ElementLoaderImpl sqlviewLoader("sqlrows"); +DECLARE_LOADER("sqlrows", SqlRows); SqlRows::SqlRows(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/sqlTask.cpp b/project2/sqlTask.cpp index eb28d26..e145a3d 100644 --- a/project2/sqlTask.cpp +++ b/project2/sqlTask.cpp @@ -6,7 +6,7 @@ #include "commonObjects.h" #include "sqlVariableBinder.h" -ElementLoaderImpl sqltaskLoader("sqltask"); +DECLARE_LOADER("sqltask", SqlTask); SqlTask::SqlTask(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/urlRows.cpp b/project2/urlRows.cpp index 6032104..b2c247d 100644 --- a/project2/urlRows.cpp +++ b/project2/urlRows.cpp @@ -6,7 +6,7 @@ #include #include -ElementLoaderImpl urlrowsLoader("urlrows"); +DECLARE_LOADER("urlrows", UrlRows); UrlRows::UrlRows(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/xmlObjectLoader.cpp b/project2/xmlObjectLoader.cpp index 4b291da..a40c66c 100644 --- a/project2/xmlObjectLoader.cpp +++ b/project2/xmlObjectLoader.cpp @@ -6,11 +6,17 @@ unsigned int LoaderBase::depth = 0; std::set LoaderBase::loadedObjects; -LoaderBase::ElementLoaderMap & -LoaderBase::getMap() +typedef std::map ElementLoaderMap; +static ElementLoaderMap * objLoaders; +void init_loaders() __attribute__ ((constructor(101))); +void kill_loaders() __attribute__ ((destructor(101))); +void init_loaders() { - static ElementLoaderMap loaders; - return loaders; + objLoaders = new ElementLoaderMap(); +} +void kill_loaders() +{ + delete objLoaders; } LoaderBase::LoaderBase(const Glib::ustring & n, bool r) : @@ -34,7 +40,8 @@ LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly, Unsupport if (!childrenOnly && node->get_namespace_uri() == ns) { Glib::ustring name = node->get_name(); unsigned int stored = 0; - for(ElementLoaderMap::const_iterator i = getMap().lower_bound(name); i != getMap().upper_bound(name); i++) { + ElementLoaderMap::const_iterator i = objLoaders->find(name); + if (i != objLoaders->end()) { SourceObjectPtr o = i->second->go(node); created += 1; loadedObjects.insert(o); @@ -43,18 +50,18 @@ LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly, Unsupport stored += 1; } } + if (stored < 1) { + if (uh == ErrorOnUnsupported) { + throw NotSupported(name); + } + else if (uh == WarnOnUnsupported) { + Logger()->messagef(LOG_WARNING, "'%s' unsupported in this location", name.c_str()); + } + } } - if (created < 1) { + else { throw NotSupported(name); } - if (stored < created) { - if (uh == ErrorOnUnsupported) { - throw NotSupported(name); - } - else if (uh == WarnOnUnsupported) { - Logger()->messagef(LOG_WARNING, "'%s' unsupported in this location", name.c_str()); - } - } } if (created == 0 && (recursive || childrenOnly)) { BOOST_FOREACH(const xmlpp::Node * child, node->get_children()) { @@ -77,10 +84,26 @@ LoaderBase::collectAll(const CommonObjects * co, const xmlpp::Element * node, bo loadedObjects.clear(); } +void +LoaderBase::newLoader(const std::string & n, ElementLoader * l) +{ + objLoaders->insert(ElementLoaderMap::value_type(n, l)); +} + +void +LoaderBase::removeLoader(const std::string & n) +{ + ElementLoaderMap::const_iterator i = objLoaders->find(n); + if (i != objLoaders->end()) { + delete i->second; + } + objLoaders->erase(n); +} + void LoaderBase::onIdle() { - BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders) { l.second->onIdle(); } } @@ -92,7 +115,7 @@ LoaderBase::onIteration() depth = 0; loadedObjects.clear(); - BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders) { l.second->onIteration(); } } @@ -100,7 +123,7 @@ LoaderBase::onIteration() void LoaderBase::onPeriodic() { - BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) { + BOOST_FOREACH(ElementLoaderMap::value_type l, *objLoaders) { l.second->onPeriodic(); } } diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h index aaab310..2ec44e1 100644 --- a/project2/xmlObjectLoader.h +++ b/project2/xmlObjectLoader.h @@ -86,13 +86,10 @@ enum UnsupportedHandling { ErrorOnUnsupported, WarnOnUnsupported, IgnoreUnsuppor class LoaderBase { public: - typedef std::map ElementLoaderMap; - LoaderBase(const Glib::ustring & ns, bool recursive); virtual ~LoaderBase(); void collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly, UnsupportedHandling uh = ErrorOnUnsupported) const; void collectAll(const xmlpp::Element * node, bool childrenOnly, UnsupportedHandling uh = ErrorOnUnsupported) const; - static ElementLoaderMap & getMap(); template static void save(std::map > * map, boost::intrusive_ptr obj); @@ -104,6 +101,9 @@ class LoaderBase { static void onIteration(); static void onPeriodic(); + static void newLoader(const std::string & N, ElementLoader * L); + static void removeLoader(const std::string & N); + private: static unsigned int depth; static std::set loadedObjects; @@ -113,6 +113,17 @@ class LoaderBase { const Glib::ustring ns; }; +#define DECLARE_CUSTOM_LOADER(N, T) \ + static void init_loader_##T() __attribute__ ((constructor(201))); \ + static void kill_loader_##T() __attribute__ ((destructor(201))); \ + static void init_loader_##T() { LoaderBase::newLoader(N, new T()); } \ + static void kill_loader_##T() { LoaderBase::removeLoader(N); } +#define DECLARE_LOADER(N, T) \ + static void init_loader_##T() __attribute__ ((constructor(201))); \ + static void kill_loader_##T() __attribute__ ((destructor(201))); \ + static void init_loader_##T() { LoaderBase::newLoader(N, new ElementLoaderImpl()); } \ + static void kill_loader_##T() { LoaderBase::removeLoader(N); } + class ElementLoader { public: virtual SourceObjectPtr go(const xmlpp::Element * xml) const = 0; @@ -122,26 +133,12 @@ class ElementLoader { }; template -class ElementLoaderImpl : ElementLoader { +class ElementLoaderImpl : public ElementLoader { public: - ElementLoaderImpl(const std::string & x) : - xmlName(x) - { - LoaderBase::getMap()[xmlName] = this; - } - ~ElementLoaderImpl() - { - LoaderBase::getMap().erase(xmlName); - } SourceObjectPtr go(const xmlpp::Element * xml) const { return new X(xml); } - - const Glib::ustring xmlName; - - private: }; - #endif diff --git a/project2/xmlRows.cpp b/project2/xmlRows.cpp index 2f5bb4b..965b8a3 100644 --- a/project2/xmlRows.cpp +++ b/project2/xmlRows.cpp @@ -10,7 +10,7 @@ #include #include -ElementLoaderImpl xmlrowLoader("xmlrows"); +DECLARE_LOADER("xmlrows", XmlRows); XmlRows::XmlRows(const xmlpp::Element * p) : SourceObject(p), diff --git a/project2/xslRows.cpp b/project2/xslRows.cpp index 62b0f74..3742e93 100644 --- a/project2/xslRows.cpp +++ b/project2/xslRows.cpp @@ -9,7 +9,7 @@ #include #include "../libmisc/curlsup.h" -ElementLoaderImpl xslrowLoader("xslrows"); +DECLARE_LOADER("xslrows", XslRows); class XmlParseError : public std::exception { }; class XpathInitError : public std::exception { }; -- cgit v1.2.3