8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:40:38 +01:00

Refactored TimerImpl to use std::function as Adriano suggested.

This commit is contained in:
hvlad 2020-05-22 11:54:38 +03:00
parent f90d011217
commit e018f7541f
6 changed files with 61 additions and 49 deletions

View File

@ -52,7 +52,8 @@ void TimerImpl::handler()
m_expTime = 0;
}
onTimer(this);
if (m_onTimer)
m_onTimer(this);
}
int TimerImpl::release()

View File

@ -28,11 +28,22 @@
#ifndef FB_CLASSES_TIMER_IMPL
#define FB_CLASSES_TIMER_IMPL
#include <functional>
#include "../../common/classes/ImplementHelper.h"
#include "../../common/classes/locks.h"
namespace Firebird {
class TimerImpl;
// Signature of free function to call by timer
typedef void (OnTimerFunc)(TimerImpl*);
// Signature of member function of class T to call by timer
template <typename T>
using OnTimerMember = void (T::*)(TimerImpl*);
class TimerImpl :
public RefCntIface<ITimerImpl<TimerImpl, CheckStatusWrapper> >
{
@ -46,6 +57,19 @@ public:
void handler();
int release();
// Set timer handler function
void setOnTimer(std::function<OnTimerFunc> onTimer)
{
m_onTimer = onTimer;
}
// Set member function as timer handler
template <typename T>
void setOnTimer(T* obj, OnTimerMember<T> onTimer)
{
m_onTimer = std::bind(onTimer, obj, std::placeholders::_1);
}
// Set timeout, seconds
void reset(unsigned int timeout);
void stop();
@ -55,50 +79,31 @@ public:
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
std::function<OnTimerFunc> m_onTimer;
};
// Call member function of some class T::Fn()
template <typename T, void (T::*Fn)(TimerImpl*)>
class TimerTmpl : public TimerImpl
// Call member function and keep reference on class instance
template <typename T>
class TimerWithRef : public TimerImpl
{
public:
TimerTmpl(T* obj) : m_obj(obj) {}
TimerWithRef(T* obj) :
TimerImpl(),
m_ref(obj)
{}
protected:
void onTimer(TimerImpl* arg)
void setOnTimer(OnTimerMember<T> onTimer)
{
(m_obj->*Fn)(arg);
TimerImpl::setOnTimer(m_ref.getPtr(), onTimer);
}
private:
T* m_obj;
};
// Call static function with argument - instance of some RefCounted class T
template <typename T, void (Fn)(TimerImpl*, T*)>
class TimerTmplRef : public TimerImpl
{
public:
TimerTmplRef(T* obj) : m_obj(obj) {}
protected:
void onTimer(TimerImpl* arg1)
{
Fn(arg1, m_obj);
}
private:
RefPtr<T> m_obj;
RefPtr<T> m_ref;
};
} // namespace Firebird

View File

@ -964,6 +964,19 @@ void StableAttachmentPart::manualAsyncUnlock(ULONG& flags)
}
}
void StableAttachmentPart::onIdleTimer(TimerImpl*)
{
// Ensure attachment is still alive and still idle
MutexEnsureUnlock guard(*this->getMutex(), FB_FUNCTION);
if (!guard.tryEnter())
return;
Attachment* att = this->getHandle();
att->signalShutdown(isc_att_shut_idle);
JRD_shutdown_attachment(att);
}
JAttachment* Attachment::getInterface() throw()
{
return att_stable->getInterface();
@ -989,25 +1002,15 @@ void Attachment::setupIdleTimer(bool clear)
else
{
if (!att_idle_timer)
{
att_idle_timer = FB_NEW IdleTimer(getStable());
att_idle_timer->setOnTimer(&StableAttachmentPart::onIdleTimer);
}
att_idle_timer->reset(timeout);
}
}
void Attachment::onIdleTimer(TimerImpl*, StableAttachmentPart* stable)
{
// Ensure attachment is still alive and still idle
MutexEnsureUnlock guard(*stable->getMutex(), FB_FUNCTION);
if (!guard.tryEnter())
return;
Attachment* att = stable->getHandle();
att->signalShutdown(isc_att_shut_idle);
JRD_shutdown_attachment(att);
}
UserId* Attachment::getUserId(const MetaName& userName)
{
// It's necessary to keep specified sql role of user

View File

@ -266,6 +266,8 @@ public:
return shutError;
}
void onIdleTimer(Firebird::TimerImpl*);
private:
Attachment* att;
JAttachment* jAtt;
@ -653,12 +655,10 @@ private:
Attachment(MemoryPool* pool, Database* dbb);
~Attachment();
static void onIdleTimer(Firebird::TimerImpl*, StableAttachmentPart*);
unsigned int att_idle_timeout; // seconds
unsigned int att_stmt_timeout; // milliseconds
typedef Firebird::TimerTmplRef<StableAttachmentPart, onIdleTimer> IdleTimer;
typedef Firebird::TimerWithRef<StableAttachmentPart> IdleTimer;
Firebird::RefPtr<IdleTimer> att_idle_timer;
Firebird::Array<JBatch*> att_batches;

View File

@ -261,7 +261,10 @@ void PluginLogWriter::setupIdleTimer(bool clear)
else
{
if (!m_idleTimer)
m_idleTimer = FB_NEW IdleTimer(this);
{
m_idleTimer = FB_NEW IdleTimer();
m_idleTimer->setOnTimer(this, &PluginLogWriter::onIdleTimer);
}
m_idleTimer->reset(timeout);
}

View File

@ -122,7 +122,7 @@ private:
int m_fileHandle;
size_t m_maxSize;
typedef Firebird::TimerTmpl<PluginLogWriter, &PluginLogWriter::onIdleTimer> IdleTimer;
typedef Firebird::TimerImpl IdleTimer;
Firebird::RefPtr<IdleTimer> m_idleTimer;
};