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 / Gate

Gate portable class

This is example how to create more complicated synchronization object - gate

/*
 * 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 starts here.
// gate.h

#ifndef _terimber_gate_h_
#define _terimber_gate_h_

#include "thread.h"

// class supports free-thread restrict source access
// there are two sides: server (1) and clients (N)
//
class gate
{
	// prevent copy objects
	gate(const gate& src);
	gate& operator=(const gate& src);
public:
	//
	// constructor
	//
	gate(size_t max_count);
	//
	// client calls when start using resource
	//
	bool entry(size_t timeout = INFINITE) const;
	//
	// client calls when finish using resource
	//
	void leave() const;
	//
	// server call to prevent entries of new clients 
	// and wait untill all clients will leave resource
	//
	bool lock(size_t timeout = INFINITE) const;
	//
	// allows new client to come
	//
	void unlock() const;
private:
	semaphore	_sema;		// semaphore
	size_t		_max_count; 	// max visitors
};

// automatic gate keeper for server side
class gate_keeper
{
public:
	//
	// constructor
	//
	gate_keeper(const gate& gate_, size_t timeout = INFINITE) : _gate(gate_)
	{ _locked = _gate.lock(timeout); }
	//
	// destructor
	//
	~gate_keeper()
	{ if (_locked) _gate.unlock(); }
	//
	// check the locked state
	//
	inline operator bool() const { return _locked; }
	inline bool operator!() const { return !_locked; }
private:
	bool		_locked; // flag that gate was locked
	const gate&	_gate; // gate
};

// class supports automatic entry/leave of gate for the clients
class gate_client
{
public:
	//
	// constructor
	//
	gate_client(const gate& gate_, size_t timeout = INFINITE) : _gate(gate_) 
	{ _inside = _gate.entry(timeout); }
	//
	// destructor
	//
	~gate_client()
	{ if (_inside) _gate.leave(); }
	// check access flag
	inline operator bool() const { return _inside; }
	inline bool operator!() const { return !_inside; }
private:
	bool		_inside; // flag that client was allowed to enter to the gate
	const gate&	_gate; // gate
};


// Source file begins
// gate.cpp

#include "gate.h"

gate::gate(size_t max_count) :
	_sema(max_count, max_count),
	_max_count(max_count)
{ 
}

// client calls when start using resource
bool 
gate::entry(size_t timeout) const
{ 
	return WAIT_OBJECT_0 == _sema.wait(timeout);
}

// client calls when finish using resource
void 
gate::leave() const
{ 
	_sema.release(); 
}

// server call to prevent entries of new clients 
// and wait untill all clients will leave resource
bool 
gate::lock(size_t timeout) const
{ 
	size_t count = 0;
	for (; count < _max_count && WAIT_OBJECT_0 == _sema.wait(timeout); ++count); 
	return count == _max_count;
}

// free resource for client entries
void 
gate::unlock() const
{ 
	_sema.release(_max_count); 
}



© Copyright Terimber 2003-.