zoneminder/src/zm_timer.cpp

120 lines
2.7 KiB
C++

//
// ZoneMinder Timer Class Implementation, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
#include "zm_timer.h"
#include "zm_logger.h"
int Timer::TimerThread::mNextTimerId = 0;
Timer::TimerThread::TimerThread( Timer &timer, int duration, bool repeat ) :
mTimerId( 0 ),
mTimer( timer ),
mDuration( duration ),
mRepeat( repeat ),
mReset( false ),
mExpiryFlag( true )
{
mAccessMutex.lock();
mTimerId = mNextTimerId++;
Debug( 5, "Creating timer %d for %d seconds%s", mTimerId, mDuration, mRepeat?", repeating":"" );
mAccessMutex.unlock();
}
Timer::TimerThread::~TimerThread()
{
cancel();
}
void Timer::TimerThread::cancel()
{
mAccessMutex.lock();
if ( mRunning )
{
Debug( 4, "Cancelling timer %d", mTimerId );
mRepeat = false;
mReset = false;
mExpiryFlag.updateValueSignal( false );
}
mAccessMutex.unlock();
}
void Timer::TimerThread::reset()
{
mAccessMutex.lock();
if ( mRunning )
{
Debug( 4, "Resetting timer" );
mReset = true;
mExpiryFlag.updateValueSignal( false );
}
else
{
Error( "Attempting to reset expired timer %d", mTimerId );
}
mAccessMutex.unlock();
}
int Timer::TimerThread::run()
{
Debug( 4, "Starting timer %d for %d seconds", mTimerId, mDuration );
bool timerExpired = false;
do
{
mAccessMutex.lock();
mReset = false;
mExpiryFlag.setValue( true );
mAccessMutex.unlock();
timerExpired = mExpiryFlag.getUpdatedValue( mDuration );
mAccessMutex.lock();
if ( timerExpired )
{
Debug( 4, "Timer %d expired", mTimerId );
mTimer.expire();
}
else
{
Debug( 4, "Timer %d %s", mTimerId, mReset?"reset":"cancelled" );
}
mAccessMutex.unlock();
} while ( mRepeat || (mReset && !timerExpired) );
return( timerExpired );
}
Timer::Timer( int timeout, bool repeat ) : mTimerThread( *this, timeout, repeat )
{
mTimerThread.start();
}
Timer::~Timer()
{
//cancel();
}
void Timer::Timer::cancel()
{
mTimerThread.cancel();
}
void Timer::Timer::reset()
{
mTimerThread.reset();
}