Refactored reload heuristic of modified modules

Previously I used a fixed time offset when a file change was detected.
Now I trigger a reload no module file size has changed over the last
5 updates.
master
Martin Felis 2017-02-05 10:37:49 +01:00
parent 748299c155
commit 19f3ddb901
3 changed files with 33 additions and 5 deletions

View File

@ -51,7 +51,8 @@ void RuntimeModuleManager::LoadModule(RuntimeModule* module) {
if ( stat_result == 0 &&
(module->id != attr.st_ino || module->mtime != attr.st_mtime)
) {
std::cout << "Opening module " << module->name << std::endl;
std::cout << "Opening module " << module->name
<< " (size = " << attr.st_size << ")" << std::endl;
void *handle = dlopen(module->name.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (handle) {
module->handle = handle;
@ -94,16 +95,42 @@ void RuntimeModuleManager::Update(float dt) {
bool RuntimeModuleManager::CheckModulesChanged() {
struct stat attr;
double current_time = gGetTimeSinceStart();
mNumUpdatesSinceLastModuleChange++;
for (int i = 0; i < mModules.size(); i++) {
RuntimeModule* module = mModules[i];
bool stat_result = stat(module->name.c_str(), &attr);
if ( stat_result == 0 &&
(module->id != attr.st_ino || module->mtime != attr.st_mtime)
if (stat_result != 0) {
gLog ("Error: could not stat module %s", module->name.c_str());
abort();
}
if ( module->id != attr.st_ino
|| module->mtime != attr.st_mtime
|| module->fsize != attr.st_size
|| module->fsize == 0
) {
module->id = attr.st_ino;
module->mtime = attr.st_mtime;
module->mtimensec = attr.st_mtim.tv_nsec;
module->fsize = attr.st_size;
mNumUpdatesSinceLastModuleChange = 0;
gLog ("Detected file change of %s: new size %d",
module->name.c_str(), attr.st_size);
}
}
// We have to delay the actual reload trigger to make
// sure all writes to the dynamic libraries are complete.
if (mNumUpdatesSinceLastModuleChange == 5) {
gLog ("Triggering reload");
return true;
}
}
return false;
}

View File

@ -14,6 +14,7 @@ struct RuntimeModule {
void *data = nullptr;
int mtime = 0;
int mtimensec = 0;
off_t fsize = 0;
struct module_api api;
struct module_state *state = nullptr;
@ -21,6 +22,7 @@ struct RuntimeModule {
struct RuntimeModuleManager {
std::vector<RuntimeModule*> mModules;
int mNumUpdatesSinceLastModuleChange = 0;
void RegisterModule(const char* name);
void UnregisterModules();

View File

@ -135,7 +135,6 @@ int main(void)
std::cout << "Detected module update. Unloading all modules." << std::endl;
module_manager.UnloadModules();
// We need to sleep to make sure we load the new files
usleep(300000);
module_manager.LoadModules();
// We need to update our last timestamp to ignore the delay due
// to reloading of the modules.