Click here to Skip to main content
15,895,777 members
Articles / Programming Languages / Objective C

Producer/Consumer Implementation Using Thread, Semaphore and Event

Rate me:
Please Sign up or sign in to vote.
4.64/5 (45 votes)
6 Jul 200415 min read 203.3K   3.5K   91  
Using thread, semaphore and event classes to implement a specific version of Producer/Consumer model
#include "mySemaphore.h"
#include "..\myException\myException.h"

mySemaphore::mySemaphore(string& sName,long initialCount,long maximumCount,int accessMode,BOOL canInherit)
{
	// initialization
	sa = NULL;
	semaphore = NULL;
	semaphoreName = "";
	initCount = 0;
	maxCount  = 0;
	inherit   = TRUE;

	// create it
	if ( accessMode == CREATE )
    {
		// security handling
		sa = (LPSECURITY_ATTRIBUTES)HeapAlloc(GetProcessHeap(),0,sizeof(SECURITY_ATTRIBUTES));
        sa->nLength = sizeof(SECURITY_ATTRIBUTES);
        sa->lpSecurityDescriptor = NULL; //no restrictions
        sa->bInheritHandle = canInherit;

		// make sure the count is legal
		// normally, you want to create the semaphore will an initialcount = 0;
		// therefore, the original state of the semaphore is locked.
		// once the system finishes all the initialization work, it can
		// call unlock() to increase it to be 1, so other threads can
		// start to use it
		if ( maximumCount < initialCount ) 
		{
			maximumCount = 1;
			initialCount = 0;
		}

		// create the semaphore
        if ( (semaphore = CreateSemaphore(sa,initialCount,maximumCount,sName.c_str())) == NULL)
        {
			int errCode = 0;
			string header = "CreateSemaphore failed";
			getErrorDetail(errCode,header);
			myException excp(errCode,header);
            throw excp;
            return;
        }

		// save the key values
		initCount = initialCount;
		maxCount  = maximumCount;
		inherit   = canInherit;

		// save the name, if specified
		if ( sName.compare("") ) semaphoreName.append(sName);

	}

	// open it
    else
    {
        if ((semaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS,canInherit,sName.c_str())) == NULL)
        {
			int errCode;
			string header = "OpenSemaphore failed";
			getErrorDetail(errCode,header);
            myException excp(errCode,header);
			throw excp;
            return;
        }
    }
}

mySemaphore::~mySemaphore()
{
	if (sa) HeapFree(GetProcessHeap(),0,sa);
	if ( semaphore ) closeSemaphore();
}

void mySemaphore::getErrorDetail(int& errCode,string& header)
{
	char buf[256];
	LPVOID lpDetailMsgBuf;
	UINT errorCode;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
				  NULL,errorCode=GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
				  (LPTSTR)&lpDetailMsgBuf,0,NULL);

	memset(buf,0,sizeof(buf));
	wsprintf(buf,": %s",(LPTSTR)lpDetailMsgBuf);
    LocalFree(lpDetailMsgBuf);	
	
	header.append(string(buf));
	errCode = errorCode;
}

void mySemaphore::closeSemaphore()
{
    if ( !CloseHandle(semaphore) )
    {
		int errCode = 0;
		string header = "CloseHandle failed";
		getErrorDetail(errCode,header);
        myException excp(errCode,header);
		throw excp;
    }
	semaphore = NULL;
}

BOOL mySemaphore::lock(BOOL wait)
{
	if ( wait == TRUE )
	{
		if ( WaitForSingleObject(semaphore,INFINITE) == WAIT_FAILED )
		{
			int errCode = 0;
			string header = "WaitForSingleObject failed";
			getErrorDetail(errCode,header);
			myException excp(errCode,header);
			throw excp;
		}
		return TRUE;
	}
	else 
	{
		DWORD retVal = WaitForSingleObject(semaphore,0);

		if ( retVal == WAIT_TIMEOUT ) return FALSE;
		if ( retVal == WAIT_OBJECT_0) return TRUE;

		if ( retVal == WAIT_FAILED )
		{
			int errCode = 0;
			string header = "WaitForSingleObject failed";
			getErrorDetail(errCode,header);
			myException excp(errCode,header);
			throw excp;
		}
	}

	return FALSE;
}

void mySemaphore::unlock()
{
	if ( !ReleaseSemaphore(semaphore,1,NULL) )
	{
		int errCode = 0;
		string header = "ReleaseSemaphore failed: ";
		header.append(semaphoreName);
		getErrorDetail(errCode,header);
		myException excp(errCode,header);
		throw excp;
	}
}

/*
long mySemaphore::getSemaphoreCount()
{
	long currCount = 0;

	if ( !ReleaseSemaphore(semaphore,0,&currCount) )
	{
		int errCode = 0;
		string header = "ReleaseSemaphore failed";
		getErrorDetail(errCode,header);
		myException excp(errCode,header);
		throw excp;
	}
    return currCount;
}
*/

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Web Developer
United States United States
I love to tell jokes and today, I finally came up with my own joke. here it goes:

I decide to make my first son a medical doctor so later on when I am old and sick, I can get medical care any time I need and for free..., in fact, better to make my second son a medical doctor too so I can get a second opinion.

here is another version of this joke:

I decide to make my first son a medical doctor so later on when I am old and sick, I can get medical care any time I need and for free..., in fact, better to make my second son a medical doctor too so I can get a second opinion. well, perhaps my third son should be a lawyer - in case something is wrong with my medical care, I can sue the first two for free.

if you happen to visit this page and read these two jokes, tell me which one you like...

Comments and Discussions