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