Skip to content

Commit f7f1def

Browse files
committed
Fixed bug CORE-2917 : Sever Hangs on I/O error during "open" operation for file "/tmp/firebird/fb_trace_ksVDoc".
Posix part will follow soon (by Alex).
1 parent 48e4cc8 commit f7f1def

4 files changed

Lines changed: 81 additions & 1 deletion

File tree

src/jrd/os/os_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace os_utils
4343

4444
void createLockDirectory(const char* pathname);
4545
int openCreateSharedFile(const char* pathname, int flags);
46+
bool touchFile(const char* pathname);
4647

4748
} // namespace os_utils
4849

src/jrd/os/win32/os_utils.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,27 @@ int openCreateSharedFile(const char* pathname, int flags)
241241
return ::open(pathname, flags | O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
242242
}
243243

244+
// set file's last access and modification time to current time
245+
bool touchFile(const char* pathname)
246+
{
247+
FILETIME ft;
248+
SYSTEMTIME st;
249+
250+
HANDLE hFile = CreateFile(pathname,
251+
GENERIC_READ | FILE_WRITE_ATTRIBUTES,
252+
FILE_SHARE_READ | FILE_SHARE_WRITE,
253+
ISC_get_security_desc(),
254+
OPEN_EXISTING,
255+
FILE_ATTRIBUTE_NORMAL,
256+
0);
257+
if (hFile == INVALID_HANDLE_VALUE)
258+
return false;
259+
260+
GetSystemTime(&st);
261+
const bool ret = SystemTimeToFileTime(&st, &ft) && SetFileTime(hFile, NULL, &ft, &ft);
262+
CloseHandle(hFile);
263+
264+
return ret;
265+
}
266+
244267
} // namespace os_utils

src/jrd/trace/TraceConfigStorage.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ using namespace Firebird;
5959

6060
namespace Jrd {
6161

62+
static const int TOUCH_INTERVAL = 60 * 60; // in seconds, one hour should be enough
6263

6364
void checkFileError(const char* filename, const char* operation, ISC_STATUS iscError)
6465
{
@@ -123,10 +124,15 @@ ConfigStorage::ConfigStorage()
123124
StorageGuard guard(this);
124125
checkFile();
125126
++m_base->cnt_uses;
127+
128+
gds__thread_start(touchThread, (void*) this, THREAD_medium, 0, 0);
126129
}
127130

128131
ConfigStorage::~ConfigStorage()
129132
{
133+
// signal touchThread to finish
134+
m_touchSemaphore.release();
135+
130136
::close(m_cfg_file);
131137
m_cfg_file = -1;
132138

@@ -177,6 +183,7 @@ void ConfigStorage::initShMem(void* arg, sh_mem* shmemData, bool initialize)
177183
header->change_number = 0;
178184
header->session_number = 1;
179185
header->cnt_uses = 0;
186+
header->touch_time = 0;
180187
memset(header->cfg_file_name, 0, sizeof(header->cfg_file_name));
181188
#ifndef WIN_NT
182189
checkMutex("init", ISC_mutex_init(&header->mutex));
@@ -281,6 +288,43 @@ void ConfigStorage::checkFile()
281288
fclose(cfgFile);
282289
}
283290
}
291+
292+
touchFile();
293+
}
294+
295+
296+
void ConfigStorage::touchFile()
297+
{
298+
os_utils::touchFile(m_base->cfg_file_name);
299+
}
300+
301+
302+
THREAD_ENTRY_DECLARE ConfigStorage::touchThread(THREAD_ENTRY_PARAM arg)
303+
{
304+
ConfigStorage* storage = (ConfigStorage*) arg;
305+
storage->touchThreadFunc();
306+
return 0;
307+
}
308+
309+
310+
void ConfigStorage::touchThreadFunc()
311+
{
312+
int delay = TOUCH_INTERVAL / 2;
313+
while (!m_touchSemaphore.tryEnter(delay))
314+
{
315+
StorageGuard guard(this);
316+
317+
time_t now;
318+
time(&now);
319+
320+
if (!m_base->touch_time || m_base->touch_time < now)
321+
{
322+
touchFile();
323+
m_base->touch_time = now + TOUCH_INTERVAL;
324+
}
325+
326+
delay = difftime(m_base->touch_time, now);
327+
}
284328
}
285329

286330

src/jrd/trace/TraceConfigStorage.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,24 @@
3131
#include "../../common/classes/array.h"
3232
#include "../../common/classes/fb_string.h"
3333
#include "../../common/classes/init.h"
34+
#include "../../common/classes/semaphore.h"
3435
#include "../../jrd/isc.h"
36+
#include "../../jrd/threaddata.h"
3537
#include "../../jrd/trace/TraceSession.h"
3638

3739
namespace Jrd {
3840

41+
class StorageInstance;
3942

4043
class ConfigStorage : public Firebird::GlobalStorage
4144
{
42-
public:
45+
friend class StorageInstance;
46+
47+
private:
4348
ConfigStorage();
4449
~ConfigStorage();
4550

51+
public:
4652
void addSession(Firebird::TraceSession& session);
4753
bool getNextSession(Firebird::TraceSession& session);
4854
void removeSession(ULONG id);
@@ -60,6 +66,10 @@ class ConfigStorage : public Firebird::GlobalStorage
6066
static void initShMem(void*, sh_mem*, bool);
6167

6268
void checkFile();
69+
void touchFile();
70+
71+
static THREAD_ENTRY_DECLARE touchThread(THREAD_ENTRY_PARAM arg);
72+
void touchThreadFunc();
6373

6474
void checkDirty()
6575
{
@@ -85,6 +95,7 @@ class ConfigStorage : public Firebird::GlobalStorage
8595
volatile ULONG change_number;
8696
volatile ULONG session_number;
8797
ULONG cnt_uses;
98+
time_t touch_time;
8899
char cfg_file_name[MAXPATHLEN];
89100
#ifndef WIN_NT
90101
struct mtx mutex;
@@ -114,6 +125,7 @@ class ConfigStorage : public Firebird::GlobalStorage
114125
#endif
115126
int m_cfg_file;
116127
bool m_dirty;
128+
Firebird::Semaphore m_touchSemaphore;
117129
};
118130

119131

0 commit comments

Comments
 (0)