diff --git a/builds/win32/msvc12/common.vcxproj b/builds/win32/msvc12/common.vcxproj
index 49fe82043f..a85f310ee8 100644
--- a/builds/win32/msvc12/common.vcxproj
+++ b/builds/win32/msvc12/common.vcxproj
@@ -46,6 +46,7 @@
+
@@ -88,6 +89,7 @@
+
@@ -152,6 +154,7 @@
+
@@ -199,6 +202,7 @@
+
diff --git a/builds/win32/msvc12/common.vcxproj.filters b/builds/win32/msvc12/common.vcxproj.filters
index 8e383410b6..600d50df14 100644
--- a/builds/win32/msvc12/common.vcxproj.filters
+++ b/builds/win32/msvc12/common.vcxproj.filters
@@ -228,12 +228,15 @@
common
-
- classes
+
+ common
common
+
+ classes
+
classes
@@ -243,6 +246,9 @@
common
+
+ classes
+
@@ -566,10 +572,7 @@
headers
-
- headers
-
-
+
headers
@@ -578,11 +581,20 @@
headers
+
+ headers
+
headers
+
+ headers
+
headers
+
+ headers
+
\ No newline at end of file
diff --git a/builds/win32/msvc14/common.vcxproj b/builds/win32/msvc14/common.vcxproj
index 92535eb870..b4b02644f1 100644
--- a/builds/win32/msvc14/common.vcxproj
+++ b/builds/win32/msvc14/common.vcxproj
@@ -46,6 +46,7 @@
+
@@ -153,6 +154,7 @@
+
diff --git a/builds/win32/msvc14/common.vcxproj.filters b/builds/win32/msvc14/common.vcxproj.filters
index 16fd5664eb..600d50df14 100644
--- a/builds/win32/msvc14/common.vcxproj.filters
+++ b/builds/win32/msvc14/common.vcxproj.filters
@@ -246,6 +246,9 @@
common
+
+ classes
+
@@ -590,5 +593,8 @@
headers
+
+ headers
+
-
+
\ No newline at end of file
diff --git a/builds/win32/msvc15/common.vcxproj b/builds/win32/msvc15/common.vcxproj
index b2f779e8a6..baffdd1a30 100644
--- a/builds/win32/msvc15/common.vcxproj
+++ b/builds/win32/msvc15/common.vcxproj
@@ -46,6 +46,7 @@
+
@@ -153,6 +154,7 @@
+
diff --git a/builds/win32/msvc15/common.vcxproj.filters b/builds/win32/msvc15/common.vcxproj.filters
index 4eed236250..600d50df14 100644
--- a/builds/win32/msvc15/common.vcxproj.filters
+++ b/builds/win32/msvc15/common.vcxproj.filters
@@ -246,6 +246,9 @@
common
+
+ classes
+
@@ -590,5 +593,8 @@
headers
+
+ headers
+
\ No newline at end of file
diff --git a/src/common/classes/TimerImpl.cpp b/src/common/classes/TimerImpl.cpp
new file mode 100644
index 0000000000..10760e37cb
--- /dev/null
+++ b/src/common/classes/TimerImpl.cpp
@@ -0,0 +1,124 @@
+/*
+* PROGRAM: Firebird interface.
+* MODULE: TimerImpl.cpp
+* DESCRIPTION: ITimer implementaton
+*
+* The contents of this file are subject to the Initial
+* Developer's Public License Version 1.0 (the "License");
+* you may not use this file except in compliance with the
+* License. You may obtain a copy of the License at
+* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
+*
+* Software distributed under the License is distributed AS IS,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied.
+* See the License for the specific language governing rights
+* and limitations under the License.
+*
+* The Original Code was created by Khorsun Vladyslav
+* for the Firebird Open Source RDBMS project.
+*
+* Copyright (c) 2020 Khorsun Vladyslav
+* and all contributors signed below.
+*
+* All Rights Reserved.
+* Contributor(s): ______________________________________.
+*
+*/
+
+#include "../../common/classes/TimerImpl.h"
+#include "../../common/StatusHolder.h"
+#include "../../common/utils_proto.h"
+
+namespace Firebird {
+
+void TimerImpl::handler()
+{
+ {
+ MutexLockGuard guard(m_mutex, FB_FUNCTION);
+
+ m_fireTime = 0;
+ if (!m_expTime) // Timer was reset to zero, do nothing
+ return;
+
+ // If timer was reset to fire later, restart ITimer
+
+ const SINT64 curTime = fb_utils::query_performance_counter() / fb_utils::query_performance_frequency();
+
+ if (m_expTime > curTime)
+ {
+ reset(m_expTime - curTime);
+ return;
+ }
+ m_expTime = 0;
+ }
+
+ onTimer(this);
+}
+
+int TimerImpl::release()
+{
+ if (--refCounter == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return 1;
+}
+
+void TimerImpl::reset(unsigned int timeout)
+{
+ LocalStatus ls;
+ CheckStatusWrapper s(&ls);
+ ITimerControl* timerCtrl = TimerInterfacePtr();
+
+ MutexLockGuard guard(m_mutex, FB_FUNCTION);
+
+ // Start timer if necessary. If timer was already started, don't restart
+ // (or stop) it - handler() will take care about it.
+
+ if (!timeout)
+ {
+ m_expTime = 0;
+ return;
+ }
+
+ const SINT64 curTime = fb_utils::query_performance_counter() / fb_utils::query_performance_frequency();
+ m_expTime = curTime + timeout;
+
+ if (m_fireTime)
+ {
+ if (m_fireTime <= m_expTime)
+ return;
+
+ timerCtrl->stop(&s, this);
+ check(&s);
+ }
+
+ m_fireTime = m_expTime;
+
+ // new ITimer timeout, ms
+ SINT64 tout = (m_expTime - curTime) * (1000 * 1000);
+
+ timerCtrl->start(&s, this, tout);
+ check(&s);
+}
+
+void TimerImpl::stop()
+{
+ MutexLockGuard guard(m_mutex, FB_FUNCTION);
+
+ if (!m_fireTime)
+ return;
+
+ m_fireTime = 0;
+
+ LocalStatus ls;
+ CheckStatusWrapper s(&ls);
+
+ ITimerControl* timerCtrl = TimerInterfacePtr();
+ timerCtrl->stop(&s, this);
+ check(&s);
+}
+
+} // namespace Firebird
diff --git a/src/common/classes/TimerImpl.h b/src/common/classes/TimerImpl.h
new file mode 100644
index 0000000000..c4f96a4157
--- /dev/null
+++ b/src/common/classes/TimerImpl.h
@@ -0,0 +1,106 @@
+/*
+* PROGRAM: Firebird interface.
+* MODULE: TimerImpl.h
+* DESCRIPTION: ITimer implementaton
+*
+* The contents of this file are subject to the Initial
+* Developer's Public License Version 1.0 (the "License");
+* you may not use this file except in compliance with the
+* License. You may obtain a copy of the License at
+* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
+*
+* Software distributed under the License is distributed AS IS,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied.
+* See the License for the specific language governing rights
+* and limitations under the License.
+*
+* The Original Code was created by Khorsun Vladyslav
+* for the Firebird Open Source RDBMS project.
+*
+* Copyright (c) 2020 Khorsun Vladyslav
+* and all contributors signed below.
+*
+* All Rights Reserved.
+* Contributor(s): ______________________________________.
+*
+*/
+
+#ifndef FB_CLASSES_TIMER_IMPL
+#define FB_CLASSES_TIMER_IMPL
+
+#include "../../common/classes/ImplementHelper.h"
+#include "../../common/classes/locks.h"
+
+namespace Firebird {
+
+class TimerImpl :
+ public RefCntIface >
+{
+public:
+ TimerImpl() :
+ m_fireTime(0),
+ m_expTime(0)
+ { }
+
+ // ITimer implementation
+ void handler();
+ int release();
+
+ // Set timeout, seconds
+ void reset(unsigned int timeout);
+ void stop();
+
+ SINT64 getExpireClock() const
+ {
+ return m_expTime;
+ }
+
+protected:
+ // Descendants must override it
+ virtual void onTimer(TimerImpl*) = 0;
+
+private:
+ Mutex m_mutex;
+ SINT64 m_fireTime; // when ITimer will fire, could be less than m_expTime
+ SINT64 m_expTime; // when actual idle timeout will expire
+};
+
+
+// Call member function of some class T::Fn()
+template
+class TimerTmpl : public TimerImpl
+{
+public:
+ TimerTmpl(T* obj) : m_obj(obj) {}
+
+protected:
+ void onTimer(TimerImpl* arg)
+ {
+ (m_obj->*Fn)(arg);
+ }
+
+private:
+ T* m_obj;
+};
+
+
+// Call static function with argument - instance of some RefCounted class T
+template
+class TimerTmplRef : public TimerImpl
+{
+public:
+ TimerTmplRef(T* obj) : m_obj(obj) {}
+
+protected:
+ void onTimer(TimerImpl* arg1)
+ {
+ Fn(arg1, m_obj);
+ }
+
+private:
+ RefPtr m_obj;
+};
+
+} // namespace Firebird
+
+#endif
\ No newline at end of file