Home / Open source / Timer
Timer class uses thread class
This is an example how to use thread class to build timer class.
/*
* The Software License
* ====================================================================
* Copyright (c) 2003 The Terimber Corporation. All rights
* reserved.
* ====================================================================
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE TERIMBER CORPORATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
// Header file begins
#ifndef _terimber_timer_h_
#define _terimber_timer_h_
#include "thread.h"
// class implement callback for timer event firing
class timer_callback
{
public:
virtual void notify(size_t ident, size_t interval, size_t multiplier) = 0;
};
// All public function can be called from different threads
// class timer
class timer : public job_employer
{
public:
//
// constructor
//
timer();
//
// destructor
//
~timer();
//
// activate timer
// set callback, ident (one timer_callback object can handle multiple timers), interval in msec,
// interval multiplier (to support long time interval days, years, ...),
// reactivate flag (repeat firing timer events)
//
void activate(timer_callback* callback, size_t ident, size_t interval, size_t multiplier = 1, bool reactivate = true);
//
// deactivate
// stop timer
//
void deactivate();
protected:
// job_employer
virtual bool v_has_job(size_t ident, void* user_data);
virtual void v_do_job(size_t ident, void* user_data);
private:
thread _thread; // thread that will fire events
mutex _mtx; // multithreaded mutex
size_t _ident; // ident of timer
size_t _interval; // interval of timer events in msec
size_t _multiplier; // multiplier of timer interval
size_t _trigger; // keep the remain interval before firing timer event
bool _reactivate; // flag od reactivation
bool _first; // flag of first firing
timer_callback* _callback; // keep callback object pointer
};
#endif // _terimber_timer_h_
// Source file begins
#include "timer.h"
timer::timer() :
_ident(0),
_interval(INFINITE),
_multiplier(1),
_trigger(1),
_reactivate(false),
_first(false),
_callback(0)
{
}
timer::~timer()
{
deactivate();
}
void
timer::activate(timer_callback* callback, size_t ident, size_t interval, size_t multiplier, bool reactivate)
{
assert(callback);
// deactivate timer
deactivate();
// set new parameters
mutex_keeper keeper(_mtx);
_callback = callback;
_ident = ident;
_interval = interval;
_reactivate = reactivate;
// check zero value of multiplier
_multiplier = multiplier == 0 ? 1 : multiplier;
// set trigger
_trigger = _multiplier;
_first = false;
// prepare task for timer
job_task task(this, 0, _interval, 0);
// strat thread
_thread.start();
// assign job
_thread.assign_job(task);
}
void
timer::deactivate()
{
mutex_keeper keeper(_mtx);
// cancel job
_thread.cancel_job();
// stop thread
_thread.stop();
}
// virtual
bool
timer::v_has_job(size_t ident, void* user_data)
{
return !_trigger--; // return current trigger value and then decrement
}
// virtual
void
timer::v_do_job(size_t ident, void* user_data)
{
// will fire event if first time or reactivate flag is set
if (!_first || _reactivate)
_callback->notify(_ident, _interval, _multiplier);
if (!_first) // flip first firing flag
_first = true;
// reset trigger
_trigger = _multiplier;
}
|
|