@@ -59,6 +59,7 @@ using namespace Firebird;
5959
6060namespace Jrd {
6161
62+ static const int TOUCH_INTERVAL = 60 * 60 ; // in seconds, one hour should be enough
6263
6364void 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
128131ConfigStorage::~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
0 commit comments