A templated, threadsafe message-queue class that enforces constraints on time-depth.
A templated, threadsafe message-queue class that enforces constraints on time-depth.
#ifndef RESIP_TimeLimitFifo_hxx
#define RESIP_TimeLimitFifo_hxx
#include <memory>
#include <iostream>
#if defined( WIN32 )
#include <time.h>
#endif
{
template<typename Payload>
class Timestamped
{
public:
Timestamped(const Payload& msg, time_t n)
: mMsg(msg),
mTime(n)
{}
inline const Payload&
getMsg()
const {
return mMsg;}
inline void setMsg(
const Payload& pMsg) { mMsg = pMsg;}
inline const time_t&
getTime()
const {
return mTime;}
private:
Payload mMsg;
time_t mTime;
};
template <class Msg>
class TimeLimitFifo : public AbstractFifo< Timestamped<Msg*> >
{
public:
TimeLimitFifo(unsigned int maxDurationSecs,
unsigned int maxSize);
private:
time_t timeDepthInternal() const;
TimeLimitFifo(const TimeLimitFifo& rhs);
TimeLimitFifo& operator=(const TimeLimitFifo& rhs);
time_t mMaxDurationSecs;
unsigned int mMaxSize;
unsigned int mUnreservedMaxSize;
};
template <class Msg>
unsigned int maxSize)
: AbstractFifo< Timestamped<Msg*> >(),
mMaxDurationSecs(maxDurationSecs),
mMaxSize(maxSize),
mUnreservedMaxSize((int)((maxSize*8)/10))
{}
template <class Msg>
{
clear();
}
template <class Msg>
bool
{
Lock lock(mMutex); (void)lock;
if (wouldAcceptInteral(
usage))
{
time_t n = time(0);
mFifo.push_back(Timestamped<Msg*>(msg, n));
onMessagePushed(1);
mCondition.notify_one();
return true;
}
else
{
return false;
}
}
template <class Msg>
bool
{
Lock lock(mMutex); (void)lock;
return wouldAcceptInteral(
usage);
}
template <class Msg>
Msg*
{
Timestamped<Msg*> tm(AbstractFifo< Timestamped<Msg*> >::getNext());
return tm.getMsg();
}
template <class Msg>
Msg*
{
Timestamped<Msg*> tm(0,0);
if(AbstractFifo< Timestamped<Msg*> >::getNext(ms, tm))
{
return tm.getMsg();
}
return 0;
}
template <class Msg>
time_t
TimeLimitFifo<Msg>::timeDepthInternal() const
{
if(mFifo.empty())
{
return 0;
}
return time(0) - mFifo.front().getTime();
}
template <class Msg>
bool
TimeLimitFifo<Msg>::wouldAcceptInteral(DepthUsage
usage)
const
{
if ((mMaxSize != 0 &&
mFifo.size() >= mMaxSize))
{
return false;
}
if (
usage == InternalElement)
{
return true;
}
if (mUnreservedMaxSize != 0 &&
mFifo.size() >= mUnreservedMaxSize)
{
return false;
}
if (
usage == IgnoreTimeDepth)
{
return true;
}
if (mFifo.size() == 0 ||
mMaxDurationSecs == 0 ||
timeDepthInternal() < mMaxDurationSecs)
{
return true;
}
return false;
}
template <class Msg>
time_t
{
Lock lock(mMutex); (void)lock;
return timeDepthInternal();
}
template <class Msg>
void
{
Lock lock(mMutex); (void)lock;
while (!mFifo.empty())
{
delete mFifo.front().getMsg();
mFifo.pop_front();
}
}
template <class Msg>
size_t
{
return size();
}
template <class Msg>
size_t
{
return mUnreservedMaxSize;
}
template <class Msg>
time_t
{
return timeDepth();
}
template <class Msg>
time_t
{
return mMaxDurationSecs;
}
template <class Msg>
void
{
Lock lock(mMutex); (void)lock;
mUnreservedMaxSize=int(maxCount * 0.8);
}
template <class Msg>
void
{
Lock lock(mMutex); (void)lock;
mMaxDurationSecs=maxSecs;
}
}
#endif
virtual unsigned int size() const
get the current size of the fifo.
Condition mCondition
condition for waiting on new queue items
bool empty() const
is the queue empty?
AbstractFifo()
Constructor.
Messages mFifo
container for FIFO items
Mutex mMutex
access serialization lock
virtual void onMessagePushed(int num)
virtual void setCountDepthTolerance(unsigned int max)
set the count depth tolerance of the FIFO
bool wouldAccept(DepthUsage usage) const
would an add called now work?
virtual size_t getCountDepth() const
gets the depth of the FIFO
Msg * getNext()
Returns the first message available.
virtual void setTimeDepthTolerance(unsigned int maxSecs)
set the time depth tolerance of the FIFO
virtual time_t getTimeDepth() const
Return the time depth of the queue.
TimeLimitFifo(unsigned int maxDurationSecs, unsigned int maxSize)
After it runs out of the lesser of these limits it will start to refuse messages.
void clear()
removes all items from the FIFO
virtual size_t getCountDepthTolerance() const
returns the FIFO count depth tolerance
virtual time_t timeDepth() const
Return the time depth of the queue.
virtual time_t getTimeDepthTolerance() const
returns the FIFO time depth tolerance
bool add(Msg *msg, DepthUsage usage)
Add a message to the fifo.
const Payload & getMsg() const
void setMsg(const Payload &pMsg)
const time_t & getTime() const
dcm! – add UnusedChecking(_enum) below;
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...