Skip to content

Get the modification time of a config file with a higher precision to fix cases when it's not reloaded after modification/replacement #8553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 57 additions & 8 deletions src/common/config/ConfigCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,23 @@ Firebird::PathName ConfigCache::getFileName()
return files->fileName;
}

time_t ConfigCache::File::getTime()
#ifdef WIN_NT
void ConfigCache::File::getTime(DWORD& timeLow, DWORD& timeHigh)
{
WIN32_FILE_ATTRIBUTE_DATA fInfo;

if (!GetFileAttributesEx(fileName.c_str(), GetFileExInfoStandard, &fInfo))
{
timeLow = 0;
timeHigh = 0;
return;
}

timeLow = fInfo.ftLastWriteTime.dwLowDateTime;
timeHigh = fInfo.ftLastWriteTime.dwHighDateTime;
}
#else
void ConfigCache::File::getTime(timespec& time)
{
struct STAT st;

Expand All @@ -91,17 +107,35 @@ time_t ConfigCache::File::getTime()
if (errno == ENOENT)
{
// config file is missing, but this is not our problem
return 0;
time.tv_sec = 0;
time.tv_nsec = 0;
return;
}
system_call_failed::raise("stat");
}

return st.st_mtime;
#ifdef DARWIN
time.tv_sec = st.st_mtimespec.tv_sec;
time.tv_nsec = st.st_mtimespec.tv_nsec;
#else
time.tv_sec = st.st_mtim.tv_sec;
time.tv_nsec = st.st_mtim.tv_nsec;
#endif
}
#endif

ConfigCache::File::File(MemoryPool& p, const PathName& fName)
: PermanentStorage(p), fileName(getPool(), fName), fileTime(0), next(NULL)
{ }
: PermanentStorage(p), fileName(getPool(), fName),
next(NULL)
{
#ifdef WIN_NT
fileTimeLow = 0;
fileTimeHigh = 0;
#else
fileTime.tv_sec = 0;
fileTime.tv_nsec = 0;
#endif
}

ConfigCache::File::~File()
{
Expand All @@ -110,15 +144,30 @@ ConfigCache::File::~File()

bool ConfigCache::File::checkLoadConfig(bool set)
{
time_t newTime = getTime();
if (fileTime == newTime)
#ifdef WIN_NT
DWORD newTimeLow;
DWORD newTimeHigh;
getTime(newTimeLow, newTimeHigh);
if (fileTimeLow == newTimeLow && fileTimeHigh == newTimeHigh)
#else
timespec newTime;
getTime(newTime);
if (fileTime.tv_sec == newTime.tv_sec && fileTime.tv_nsec == newTime.tv_nsec)
#endif
{
return next ? next->checkLoadConfig(set) : true;
}

if (set)
{
fileTime = newTime;
#ifdef WIN_NT
fileTimeLow = newTimeLow;
fileTimeHigh = newTimeHigh;
#else
fileTime.tv_sec = newTime.tv_sec;
fileTime.tv_nsec = newTime.tv_nsec;
#endif

if (next)
{
next->checkLoadConfig(set);
Expand Down
11 changes: 9 additions & 2 deletions src/common/config/ConfigCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,16 @@ class ConfigCache : public Firebird::PermanentStorage
Firebird::PathName fileName;

private:
volatile time_t fileTime;
#ifdef WIN_NT
volatile DWORD fileTimeLow;
volatile DWORD fileTimeHigh;
void getTime(DWORD& timeLow, DWORD& timeHigh);
#else
volatile timespec fileTime;
void getTime(timespec& time);
#endif

File* next;
time_t getTime();
};
File* files;

Expand Down
Loading