diff --git a/src/common/config/ConfigCache.cpp b/src/common/config/ConfigCache.cpp index 50117e60134..d47a05a0c3b 100644 --- a/src/common/config/ConfigCache.cpp +++ b/src/common/config/ConfigCache.cpp @@ -82,8 +82,16 @@ Firebird::PathName ConfigCache::getFileName() return files->fileName; } -time_t ConfigCache::File::getTime() +ConfigCache::File::PreciseTime ConfigCache::File::getTime() { +#ifdef WIN_NT + WIN32_FILE_ATTRIBUTE_DATA fInfo; + + if (!GetFileAttributesEx(fileName.c_str(), GetFileExInfoStandard, &fInfo)) + return PreciseTime(); + + return PreciseTime(fInfo.ftLastWriteTime); +#else struct STAT st; if (os_utils::stat(fileName.c_str(), &st) != 0) @@ -91,16 +99,21 @@ time_t ConfigCache::File::getTime() if (errno == ENOENT) { // config file is missing, but this is not our problem - return 0; + return PreciseTime(); } system_call_failed::raise("stat"); } - return st.st_mtime; +#ifdef DARWIN + return PreciseTime(st.st_mtimespec); +#else + return PreciseTime(st.st_mtim); +#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) { } ConfigCache::File::~File() @@ -110,7 +123,7 @@ ConfigCache::File::~File() bool ConfigCache::File::checkLoadConfig(bool set) { - time_t newTime = getTime(); + const PreciseTime newTime = getTime(); if (fileTime == newTime) { return next ? next->checkLoadConfig(set) : true; diff --git a/src/common/config/ConfigCache.h b/src/common/config/ConfigCache.h index e3be1b80260..18d2fec50cd 100644 --- a/src/common/config/ConfigCache.h +++ b/src/common/config/ConfigCache.h @@ -25,8 +25,8 @@ * */ -#ifndef COMMON_CONFIG_CASHE_H -#define COMMON_CONFIG_CASHE_H +#ifndef COMMON_CONFIG_CACHE_H +#define COMMON_CONFIG_CACHE_H #include "../common/classes/alloc.h" #include "../common/classes/fb_string.h" @@ -48,6 +48,39 @@ class ConfigCache : public Firebird::PermanentStorage private: class File : public Firebird::PermanentStorage { + class PreciseTime + { +#ifdef WIN_NT + using TimeType = FILETIME; +#else + using TimeType = timespec; +#endif + + public: + PreciseTime() + { + } + + PreciseTime(TimeType time) + : m_time(time) + { + } + + bool operator==(const PreciseTime& other) const + { +#ifdef WIN_NT + return m_time.dwLowDateTime == other.m_time.dwLowDateTime && + m_time.dwHighDateTime == other.m_time.dwHighDateTime; +#else + return m_time.tv_sec == other.m_time.tv_sec && + m_time.tv_nsec == other.m_time.tv_nsec; +#endif + } + + private: + TimeType m_time = {}; + }; + public: File(Firebird::MemoryPool& p, const Firebird::PathName& fName); ~File(); @@ -60,9 +93,9 @@ class ConfigCache : public Firebird::PermanentStorage Firebird::PathName fileName; private: - volatile time_t fileTime; + PreciseTime fileTime; File* next; - time_t getTime(); + PreciseTime getTime(); }; File* files; @@ -70,4 +103,4 @@ class ConfigCache : public Firebird::PermanentStorage Firebird::RWLock rwLock; }; -#endif // COMMON_CONFIG_CASHE_H +#endif // COMMON_CONFIG_CACHE_H