Skip to content

Commit 5ea7020

Browse files
authored
Get the modification time of a config file with a higher precision to fix cases when it's not reloaded after modification/replacement (#8553)
* Get the modification time of a config file with a higher precision to fix cases when it's not reloaded after modification/replacement The fix is needed to avoid potential problems in Firebird QA. * Use GetFileAttributesEx to get the config file attributes * Fix macOS build * Unify the return type of File::getTime() to make the code cleaner * Correct the old typo
1 parent 4cb87d9 commit 5ea7020

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

src/common/config/ConfigCache.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,38 @@ Firebird::PathName ConfigCache::getFileName()
8282
return files->fileName;
8383
}
8484

85-
time_t ConfigCache::File::getTime()
85+
ConfigCache::File::PreciseTime ConfigCache::File::getTime()
8686
{
87+
#ifdef WIN_NT
88+
WIN32_FILE_ATTRIBUTE_DATA fInfo;
89+
90+
if (!GetFileAttributesEx(fileName.c_str(), GetFileExInfoStandard, &fInfo))
91+
return PreciseTime();
92+
93+
return PreciseTime(fInfo.ftLastWriteTime);
94+
#else
8795
struct STAT st;
8896

8997
if (os_utils::stat(fileName.c_str(), &st) != 0)
9098
{
9199
if (errno == ENOENT)
92100
{
93101
// config file is missing, but this is not our problem
94-
return 0;
102+
return PreciseTime();
95103
}
96104
system_call_failed::raise("stat");
97105
}
98106

99-
return st.st_mtime;
107+
#ifdef DARWIN
108+
return PreciseTime(st.st_mtimespec);
109+
#else
110+
return PreciseTime(st.st_mtim);
111+
#endif
112+
#endif
100113
}
101114

102115
ConfigCache::File::File(MemoryPool& p, const PathName& fName)
103-
: PermanentStorage(p), fileName(getPool(), fName), fileTime(0), next(NULL)
116+
: PermanentStorage(p), fileName(getPool(), fName), next(NULL)
104117
{ }
105118

106119
ConfigCache::File::~File()
@@ -110,7 +123,7 @@ ConfigCache::File::~File()
110123

111124
bool ConfigCache::File::checkLoadConfig(bool set)
112125
{
113-
time_t newTime = getTime();
126+
const PreciseTime newTime = getTime();
114127
if (fileTime == newTime)
115128
{
116129
return next ? next->checkLoadConfig(set) : true;

src/common/config/ConfigCache.h

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
*
2626
*/
2727

28-
#ifndef COMMON_CONFIG_CASHE_H
29-
#define COMMON_CONFIG_CASHE_H
28+
#ifndef COMMON_CONFIG_CACHE_H
29+
#define COMMON_CONFIG_CACHE_H
3030

3131
#include "../common/classes/alloc.h"
3232
#include "../common/classes/fb_string.h"
@@ -48,6 +48,39 @@ class ConfigCache : public Firebird::PermanentStorage
4848
private:
4949
class File : public Firebird::PermanentStorage
5050
{
51+
class PreciseTime
52+
{
53+
#ifdef WIN_NT
54+
using TimeType = FILETIME;
55+
#else
56+
using TimeType = timespec;
57+
#endif
58+
59+
public:
60+
PreciseTime()
61+
{
62+
}
63+
64+
PreciseTime(TimeType time)
65+
: m_time(time)
66+
{
67+
}
68+
69+
bool operator==(const PreciseTime& other) const
70+
{
71+
#ifdef WIN_NT
72+
return m_time.dwLowDateTime == other.m_time.dwLowDateTime &&
73+
m_time.dwHighDateTime == other.m_time.dwHighDateTime;
74+
#else
75+
return m_time.tv_sec == other.m_time.tv_sec &&
76+
m_time.tv_nsec == other.m_time.tv_nsec;
77+
#endif
78+
}
79+
80+
private:
81+
TimeType m_time = {};
82+
};
83+
5184
public:
5285
File(Firebird::MemoryPool& p, const Firebird::PathName& fName);
5386
~File();
@@ -60,14 +93,14 @@ class ConfigCache : public Firebird::PermanentStorage
6093
Firebird::PathName fileName;
6194

6295
private:
63-
volatile time_t fileTime;
96+
PreciseTime fileTime;
6497
File* next;
65-
time_t getTime();
98+
PreciseTime getTime();
6699
};
67100
File* files;
68101

69102
public:
70103
Firebird::RWLock rwLock;
71104
};
72105

73-
#endif // COMMON_CONFIG_CASHE_H
106+
#endif // COMMON_CONFIG_CACHE_H

0 commit comments

Comments
 (0)