Thread portable class


Gate portable class


Timer class


Pool class


Terimber 2.0


About C++


Downloads Products & Services Support Clients Open Source About



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;
}



© Copyright Terimber 2003-.