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
parent
748299c155
commit
19f3ddb901
|
@ -51,7 +51,8 @@ void RuntimeModuleManager::LoadModule(RuntimeModule* module) {
|
||||||
if ( stat_result == 0 &&
|
if ( stat_result == 0 &&
|
||||||
(module->id != attr.st_ino || module->mtime != attr.st_mtime)
|
(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);
|
void *handle = dlopen(module->name.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
||||||
if (handle) {
|
if (handle) {
|
||||||
module->handle = handle;
|
module->handle = handle;
|
||||||
|
@ -94,17 +95,43 @@ void RuntimeModuleManager::Update(float dt) {
|
||||||
bool RuntimeModuleManager::CheckModulesChanged() {
|
bool RuntimeModuleManager::CheckModulesChanged() {
|
||||||
struct stat attr;
|
struct stat attr;
|
||||||
|
|
||||||
|
double current_time = gGetTimeSinceStart();
|
||||||
|
mNumUpdatesSinceLastModuleChange++;
|
||||||
|
|
||||||
for (int i = 0; i < mModules.size(); i++) {
|
for (int i = 0; i < mModules.size(); i++) {
|
||||||
RuntimeModule* module = mModules[i];
|
RuntimeModule* module = mModules[i];
|
||||||
bool stat_result = stat(module->name.c_str(), &attr);
|
bool stat_result = stat(module->name.c_str(), &attr);
|
||||||
|
|
||||||
if ( stat_result == 0 &&
|
if (stat_result != 0) {
|
||||||
(module->id != attr.st_ino || module->mtime != attr.st_mtime)
|
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
|
||||||
) {
|
) {
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ struct RuntimeModule {
|
||||||
void *data = nullptr;
|
void *data = nullptr;
|
||||||
int mtime = 0;
|
int mtime = 0;
|
||||||
int mtimensec = 0;
|
int mtimensec = 0;
|
||||||
|
off_t fsize = 0;
|
||||||
|
|
||||||
struct module_api api;
|
struct module_api api;
|
||||||
struct module_state *state = nullptr;
|
struct module_state *state = nullptr;
|
||||||
|
@ -21,6 +22,7 @@ struct RuntimeModule {
|
||||||
|
|
||||||
struct RuntimeModuleManager {
|
struct RuntimeModuleManager {
|
||||||
std::vector<RuntimeModule*> mModules;
|
std::vector<RuntimeModule*> mModules;
|
||||||
|
int mNumUpdatesSinceLastModuleChange = 0;
|
||||||
|
|
||||||
void RegisterModule(const char* name);
|
void RegisterModule(const char* name);
|
||||||
void UnregisterModules();
|
void UnregisterModules();
|
||||||
|
|
|
@ -135,7 +135,6 @@ int main(void)
|
||||||
std::cout << "Detected module update. Unloading all modules." << std::endl;
|
std::cout << "Detected module update. Unloading all modules." << std::endl;
|
||||||
module_manager.UnloadModules();
|
module_manager.UnloadModules();
|
||||||
// We need to sleep to make sure we load the new files
|
// We need to sleep to make sure we load the new files
|
||||||
usleep(300000);
|
|
||||||
module_manager.LoadModules();
|
module_manager.LoadModules();
|
||||||
// We need to update our last timestamp to ignore the delay due
|
// We need to update our last timestamp to ignore the delay due
|
||||||
// to reloading of the modules.
|
// to reloading of the modules.
|
||||||
|
|
Loading…
Reference in New Issue