Source: classlib/include/classlib/mtsync.h


Annotated List
Files
Globals
Hierarchy
Index
/***************************************************************************
    mtsync.h  -  classi helper per sincronizzazione multithread
                             -------------------
    begin                : ven dic  7 17:40:01 CET 2001
    copyright            : (C) 2001 by Nicola De Nisco
    email                : nicola@winada.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

/* NOTA:
 * Lo scopo di queste classi non e' solo quello di semplificare
 * l'uso dei lock in applicazioni multithread, ma anche di semplificare
 * il porting di applicazioni Windows.
 * Infatti questi oggetti sono stati creati il piu' possibile simili
 * ai loro omonimi in MFC.
 */

#if !defined( __CLASSLIB_MTSYNC_H )
#define __CLASSLIB_MTSYNC_H

#include 
#include 

/////////////////////////////////////////////////////////////////////////////
// CSyncObject

/**

	class CSyncObject

	Base class for syncronization objects.

*/

class CSyncObject
{
  public:
	CSyncObject() {}
	virtual ~CSyncObject() {}

	/** The calling thread try to acquire the object locking ad need.
		Return 0 on success.
	*/
	virtual int Lock()		= 0;

	/** The calling thread unlock the resource for other thread.
		Return 0 on success.
	*/
	virtual int Unlock()	= 0;

	/** Try to acquire the lock but don't lock the calling thread. return -1 if
	    not possible to acquire the object.
		Return 0 on success.
	*/
	virtual int Try()		= 0;
};

/////////////////////////////////////////////////////////////////////////////
// CMutex

/**

	class CMutex

	Class implementing a mutex object.
	A mutex is a sinchronization object for multithread programming.
	Only one thread at a time can take the object.

*/

class CMutex : public CSyncObject
{
  public:
	/** Create a standard mutex object not signaled.
	*/
	CMutex()
	{
		pthread_mutex_init(&mutex, NULL);
	}
	
	/** Create a mutex object with extra parameter.
	*/
	CMutex(const pthread_mutexattr_t *mutexattr)
	{
		pthread_mutex_init(&mutex, mutexattr);
	}
	
	/** Destroy the mutex object.
	*/
	virtual ~CMutex()
	{
		pthread_mutex_destroy(&mutex);
	}
	
	/** The calling thread try to acquire the object. If another thread have called the Lock()
		function on the same object, the calling thread go in suspend mode until someone call
		Unlock() to free the resource. When Unlock() as called the waiting thread restart in
		the call order to Lock().
	*/
	virtual int Lock()
	{
		return pthread_mutex_lock(&mutex);
	}
	
	/** The calling thread release the resource, signaling to other waiting thread to restart.
	*/
	virtual int Unlock()
	{
		return pthread_mutex_unlock(&mutex);
	}
	
	/** Try to acquire the locking without really lock the thread. Not yet implemented.
	*/
	virtual int Try()
	{
		return 0;
		//return pthread_mutex_trylock(&mutex);
	}
	
  protected:
  	pthread_mutex_t	mutex;
};

/////////////////////////////////////////////////////////////////////////////
// CSemaphore

/**

	class CSemaphore

	Class implementing a semaphore object.
	A semaphore is a sinchronization object for multithread programming.
	The semaphore is a counted resource access controller.
	The sempahore is built whith a inital count of concurrent
	thread allowed to take the resource.
	Every time a thread call Lock() the thread claim one unit
	of the resource. When no more unit are available
	a call to Lock() cause the thread wait until another
	thread call Unlock().

*/

class CSemaphore : public CSyncObject
{
  public:

	/** Build the semaphore whit the supplied initialCount ed maxCount parameter.
	*/
  	CSemaphore(long initialCount = 1, long maxCount = 1)
  	{
		pthread_mutex_init(&mutex, NULL);
		pthread_cond_init(&event, NULL);
		iCount = initialCount;
		mCount = maxCount;
  	}
  	
	/** Destroy the semaphore.
	*/
	virtual ~CSemaphore()
	{
		pthread_mutex_destroy(&mutex);
		pthread_cond_destroy(&event);
	}
	
	/** The calling thread try to lock one item of the resource. The internal resource
		counter will be decremented. If the counter are 0 the thred go in sleeping state,
		until someone call Unlock().
	*/
	virtual int Lock()
	{
		int rv;
		if((rv = pthread_mutex_lock(&mutex)) != 0)
			return rv;
		while(iCount <= 0) {
			pthread_cond_wait(&event, &mutex);
        }
		iCount--;
		return pthread_mutex_unlock(&mutex);
	}
	
	/** The calling thread release one item of the resource. The internal resource
		counter will be incremented. Every thread waiting for the resource will be
		notified to restart.
	*/
	virtual int Unlock()
	{
		int rv;
		if((rv = pthread_mutex_lock(&mutex)) != 0)
			return rv;
		iCount++;
		if(iCount > mCount)
			iCount = mCount;
		pthread_cond_broadcast(&event);
		return pthread_mutex_unlock(&mutex);
	}
	
	/** Try to acquire the locking without really lock the thread. Not yet implemented.
	*/
	virtual int Try()
	{
		return 0;
		//return pthread_mutex_trylock(&mutex);
	}
		
	long getCount() const {return iCount;}
	long getMax() const {return mCount;}
	
	void setMax(long v) {mCount = v;}
	
  protected:
  	pthread_mutex_t	mutex;
	pthread_cond_t	event;
	long iCount, mCount;
};

/////////////////////////////////////////////////////////////////////////////
// CEvent

/**
	class CEvent

	Class implementing a event object.
	A event is a sinchronization object for multithread programming.
	If the event is not signaled (initial state) the thread calling
	Lock() don't lock. If the event is signaled (ResetEvent as called)
	call to Lock() cause a lock on thread until SetEvent or PulseEvent as called.
	PulseEvent is a one shot function.
*/

class CEvent : public CSyncObject
{
  public:
	/** Build the event with the supplied parameter.
	*/
  	CEvent(BOOL initialLock = FALSE, BOOL manualIgnored = TRUE )
  	{
		pthread_mutex_init(&mutex, NULL);
		pthread_cond_init(&event, NULL);
		locknow = initialLock;
  	}
  	
	/** Destroy the event object.
	*/
	virtual ~CEvent()
	{
		pthread_mutex_destroy(&mutex);
		pthread_cond_destroy(&event);
	}

	/** Set the event signaled. This object don't lock thread now.
		All waiting thread will be notified to restart.
	*/
	virtual void SetEvent()
	{
		locknow = FALSE;
		PulseEvent();
	}
	
	/** Reset the event signaled. This object lock threads now.
	*/
	virtual void ResetEvent()
	{
		locknow = TRUE;
	}
	
	/** It's one shot function: unlock the waiting thread at this
		time, but don't change the state of the object.
	*/
	virtual void PulseEvent()
	{
		pthread_mutex_lock(&mutex);
		pthread_cond_broadcast(&event);
		pthread_mutex_unlock(&mutex);
   	}
	
	/** The calling thread try to authorized itself to execution of
		the following piece of code. If the object is not in signaled state
		the thread will be locked until someone signal it.
	*/
	virtual int Lock()
	{
		int rv;
		if((rv = pthread_mutex_lock(&mutex)) != 0)
			return rv;
		if(locknow)
			pthread_cond_wait(&event, &mutex);
		return pthread_mutex_unlock(&mutex);
	}
	
	/** Not used in this syncronization object.
	*/
	virtual int Unlock() {return 0;}

	/** Try to acquire the locking without really lock the thread. Not yet implemented.
	*/
	virtual int Try() {return 0;}

  protected:
  	pthread_mutex_t	mutex;
	pthread_cond_t	event;
	BOOL			locknow;
};

/////////////////////////////////////////////////////////////////////////////
// CCriticalSection

/**

	class CCriticalSection

	For compatibility with MFC code.
	Is just a new name for CMutex.
	See CMutex for description.

*/

class CCriticalSection : public CMutex
{
  public:
	CCriticalSection() : CMutex()
	{
	}
	
	CCriticalSection(const pthread_mutexattr_t *mutexattr) : CMutex(mutexattr)
	{
	}
};

/////////////////////////////////////////////////////////////////////////////
// CSingleLock

#define INFINITE 0

/**
	
	class CSingleLock

	It's a locker object.
	The class CSingleLock try to acquire the object passed as parameter.
	
	
	Example:
	
	...
	...
	CMutex mtx;
	...
	...
	// this function acquire the mutex and release it before return to the caller.
	int mySynchronizedFun()
	{
	    CSingleLock lck(mtx, TRUE);
	    ...
	    ...
	    if(someCondition)
	        return -1;
	    ...
	    ...
	    return 0;
	}
	...
	...

*/

class CSingleLock
{
// Constructors
public:

	/** Build the locker. If bInitialLock is TRUE try to acquire immediately
		the synchronization object.
	*/
	CSingleLock(CSyncObject* pObject, BOOL bInitialLock = FALSE)
	{
		m_pObject = pObject;
		if(bInitialLock)
			Lock();
	}
	
	/** Destroy the locker, releasing the synchronization object.
	*/
	virtual ~CSingleLock()
	{
		Unlock();
	}

// Operations
public:
	/** Lock the synchronization object.
	*/
	BOOL Lock(DWORD dwTimeOut = INFINITE)
	{
		if(!m_pObject->Lock()) {
			m_bAcquired = TRUE;
			return TRUE;
		}
		return FALSE;
	}
	
	/** Unlock the synchronization object.
	*/
	BOOL Unlock()
	{
		if(m_bAcquired && m_pObject->Unlock() == 0) {
			m_bAcquired = FALSE;
			return TRUE;
		}
		return FALSE;
	}
	
	/** Lock the synchronization object.
	*/
	BOOL Unlock(LONG /*lCount*/, LPLONG /*lPrevCount*/ = NULL)
	{
		return Unlock();
	}
	
	/** Return TRUE if the synchronization object is locked.
	*/
	BOOL IsLocked() {return m_bAcquired;}
	
protected:
	CSyncObject* m_pObject;
	BOOL	m_bAcquired;
};

/////////////////////////////////////////////////////////////////////////////
// CMultiLock

/**
	
	class CMultiLock

	It's a locker object.
	The class CMultiLock try to acquire ALL the object passed as parameter.
	
	
	Example:
	
	...
	...
	CMutex mtx1;
	...
	...
	CMutex mtx2;
	...
	...
	// this function acquire the mutexes and release them before return to the caller.
	int mySynchronizedFun()
	{
	    CSyncObject* lobj[] = {&mtx1, &mtx2};
	    CMultiLock mlck(lobj, 2, TRUE);
	    ...
	    ...
	    if(someCondition)
	        return -1;
	    ...
	    ...
	    return 0;
	}
	...
	...

*/

class CMultiLock
{
// Constructor
public:

	/** Build the locker. If bInitialLock is TRUE try to acquire immediately
		all synchronization objects.
	*/
	CMultiLock(CSyncObject* ppObjects[], DWORD dwCount, BOOL bInitialLock = FALSE);

	/** Destroy the locker, releasing all synchronization objects.
	*/
	virtual ~CMultiLock();

// Operations
public:

	/** Lock all synchronization objects.
	*/
	DWORD Lock(DWORD dwTimeOut = INFINITE, BOOL bWaitForAll = TRUE, DWORD dwWakeMask = 0);

	/** Unlock all synchronization objects.
	*/
	BOOL Unlock();

	/** Unlock all synchronization objects.
	*/
	BOOL Unlock(LONG lCount, LPLONG lPrevCount = NULL);

	/** Return TRUE if the specifid item is locked.
	*/
	BOOL IsLocked(DWORD dwItem) const {return m_bLockedArray[dwItem];}

protected:
	CSyncObject** m_ppObjectArray;
	BOOL*   m_bLockedArray;
	DWORD   m_dwCount;
};

#endif // __CLASSLIB_MTSYNC_H


Generated by: nicola on gulliver.wadahome.it on Sun May 25 13:54:34 2003, using kdoc 2.0a53.