diff options
author | Marius Kintel <marius@kintel.net> | 2013-06-18 05:46:48 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2013-06-18 05:46:48 (GMT) |
commit | 6d91540e4cc3f9fe0caaea63ac64518a5626d28b (patch) | |
tree | ca7034453a1f55124e4b7378aaab22985aff6a21 /src/ModuleCache.cc | |
parent | 95947a877b8e88521a7f00348d56c89e9b7c2a79 (diff) | |
parent | 6c7d386a3338039416ced323bf1aa75edbb43d19 (diff) |
Merge branch 'master' into epec-kernel
Diffstat (limited to 'src/ModuleCache.cc')
-rw-r--r-- | src/ModuleCache.cc | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 4944495..99c0b20 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -14,50 +14,58 @@ #include <time.h> #include <sys/stat.h> +//#include "parsersettings.h" /*! FIXME: Implement an LRU scheme to avoid having an ever-growing module cache */ ModuleCache *ModuleCache::inst = NULL; -static bool is_modified(const std::string &filename, const time_t &mtime) -{ - struct stat st; - memset(&st, 0, sizeof(struct stat)); - stat(filename.c_str(), &st); - return (st.st_mtime > mtime); -} +/*! + Reevaluate the given file and recompile if necessary. + Returns NULL on any error (e.g. compile error or file not found) + If the given filename is relative, it means that the module hasn't been + previously located. +*/ FileModule *ModuleCache::evaluate(const std::string &filename) { - FileModule *lib_mod = NULL; + FileModule *lib_mod = (this->entries.find(filename) != this->entries.end()) ? + &(*this->entries[filename].module) : NULL; + + // Don't try to recursively evaluate - if the file changes + // during evaluation, that would be really bad. + if (lib_mod && lib_mod->isHandlingDependencies()) return lib_mod; + + bool shouldCompile = true; - // Create cache ID + // Create cache ID struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(filename.c_str(), &st); + bool valid = (stat(filename.c_str(), &st) == 0); + // If file isn't there, just return and let the cache retain the old module + if (!valid) return NULL; + std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size); - // Lookup in cache - if (this->entries.find(filename) != this->entries.end() && - this->entries[filename].cache_id == cache_id) { -#ifdef DEBUG -// Causes too much debug output -// PRINTB("Using cached library: %s (%s)", filename % cache_id); -#endif - lib_mod = &(*this->entries[filename].module); + // Lookup in cache + if (lib_mod) { + if (this->entries[filename].cache_id == cache_id) { + shouldCompile = false; - BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, lib_mod->includes) { - if (is_modified(item.first, item.second)) { + if (lib_mod->includesChanged()) { lib_mod = NULL; - break; + shouldCompile = true; } } } + else { + shouldCompile = valid; + } - // If cache lookup failed (non-existing or old timestamp), compile module - if (!lib_mod) { + // If cache lookup failed (non-existing or old timestamp), compile module + if (shouldCompile) { #ifdef DEBUG if (this->entries.find(filename) != this->entries.end()) { PRINTB("Recompiling cached library: %s (%s)", filename % cache_id); @@ -91,7 +99,7 @@ FileModule *ModuleCache::evaluate(const std::string &filename) if (lib_mod) { // We defer deletion so we can ensure that the new module won't - // have the same address as the old + // have the same address as the old delete oldmodule; this->entries[filename].module = lib_mod; } else { @@ -101,7 +109,9 @@ FileModule *ModuleCache::evaluate(const std::string &filename) print_messages_pop(); } - if (lib_mod) lib_mod->handleDependencies(); + if (lib_mod) { + lib_mod->handleDependencies(); + } return lib_mod; } @@ -111,3 +121,9 @@ void ModuleCache::clear() this->entries.clear(); } +FileModule *ModuleCache::lookup(const std::string &filename) +{ + return (this->entries.find(filename) != this->entries.end()) ? + &(*this->entries[filename].module) : NULL; +} + |