summaryrefslogtreecommitdiff
path: root/src/ModuleCache.cc
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2014-02-09 22:17:10 (GMT)
committerMarius Kintel <marius@kintel.net>2014-02-09 22:17:10 (GMT)
commit603ce024201b22d722e1bbb41eb5cc2ae682f708 (patch)
treed652cae47d289ca5190729af33f5e182e1235529 /src/ModuleCache.cc
parent65aeb0ad19a17ccb59fc29254142be0855c6e0e8 (diff)
Cleaned up some module cache misbehaviors. Fixes #535
Diffstat (limited to 'src/ModuleCache.cc')
-rw-r--r--src/ModuleCache.cc85
1 files changed, 46 insertions, 39 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 1b7a9e5..595a463 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -25,48 +25,61 @@ ModuleCache *ModuleCache::inst = NULL;
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.
+ The given filename must be absolute.
*/
FileModule *ModuleCache::evaluate(const std::string &filename)
{
- FileModule *lib_mod = (this->entries.find(filename) != this->entries.end()) ?
- &(*this->entries[filename].module) : NULL;
-
+ FileModule *lib_mod = NULL;
+ bool found = false;
+ if (this->entries.find(filename) != this->entries.end()) {
+ found = true;
+ lib_mod = this->entries[filename].module;
+ }
+
// 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
struct stat st;
memset(&st, 0, sizeof(struct stat));
bool valid = (stat(filename.c_str(), &st) == 0);
- // If file isn't there, just return and let the cache retain the old module
+ // If file isn't there, just return and let the cache retain the old module
if (!valid) return NULL;
-
+
+ // If the file is present, we'll always cache some result
std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size);
- // Lookup in cache
- if (lib_mod) {
- if (this->entries[filename].cache_id == cache_id) {
+ cache_entry &entry = this->entries[filename];
+ // Initialize entry, if new
+ if (!found) {
+ entry.module = NULL;
+ entry.cache_id = cache_id;
+ }
+
+ bool shouldCompile = true;
+ if (found) {
+ // Files should only be recompiled if the cache ID changed
+ if (entry.cache_id == cache_id) {
shouldCompile = false;
- if (lib_mod->includesChanged()) {
+ // Recompile if includes changed
+ if (lib_mod && lib_mod->includesChanged()) {
lib_mod = NULL;
shouldCompile = true;
}
}
}
- else {
- shouldCompile = valid;
- }
+
+#ifdef DEBUG
+ // Causes too much debug output
+ //if (!shouldCompile) PRINTB("Using cached library: %s (%p)", filename % lib_mod);
+#endif
// If cache lookup failed (non-existing or old timestamp), compile module
if (shouldCompile) {
#ifdef DEBUG
- if (this->entries.find(filename) != this->entries.end()) {
+ if (found) {
PRINTB("Recompiling cached library: %s (%s)", filename % cache_id);
}
else {
@@ -84,35 +97,25 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
textbuf << ifs.rdbuf();
}
textbuf << "\n" << commandline_commands;
-
+
print_messages_push();
-
- FileModule *oldmodule = NULL;
- cache_entry e = { NULL, cache_id };
- if (this->entries.find(filename) != this->entries.end()) {
- oldmodule = this->entries[filename].module;
- }
- this->entries[filename] = e;
+
+ FileModule *oldmodule = lib_mod;
std::string pathname = boosty::stringy(fs::path(filename).parent_path());
lib_mod = dynamic_cast<FileModule*>(parse(textbuf.str().c_str(), pathname.c_str(), false));
PRINTB_NOCACHE(" compiled module: %p", lib_mod);
- if (lib_mod) {
- // We defer deletion so we can ensure that the new module won't
- // have the same address as the old
- delete oldmodule;
- this->entries[filename].module = lib_mod;
- } else {
- this->entries.erase(filename);
- }
+ // We defer deletion so we can ensure that the new module won't
+ // have the same address as the old
+ if (oldmodule) delete oldmodule;
+ entry.module = lib_mod;
+ entry.cache_id = cache_id;
print_messages_pop();
}
-
- if (lib_mod) {
- lib_mod->handleDependencies();
- }
+
+ if (lib_mod) lib_mod->handleDependencies();
return lib_mod;
}
@@ -124,7 +127,11 @@ void ModuleCache::clear()
FileModule *ModuleCache::lookup(const std::string &filename)
{
- return (this->entries.find(filename) != this->entries.end()) ?
- &(*this->entries[filename].module) : NULL;
+ return isCached(filename) ? this->entries[filename].module : NULL;
+}
+
+bool ModuleCache::isCached(const std::string &filename)
+{
+ return this->entries.find(filename) != this->entries.end();
}
contact: Jan Huwald // Impressum