Click here to Skip to main content
15,896,606 members
Articles / Desktop Programming / Win32

Cross-Platform IPC Event Manager for Interaction with Service Providers

Rate me:
Please Sign up or sign in to vote.
4.40/5 (5 votes)
6 May 2009LGPL35 min read 38.7K   713   38  
This article shows you how to send or post events among processes using shared memory queues for the Windows and Linux platforms.
/* ==============================================================================================================================
 * This notice must be untouched at all times.
 *
 * Copyright  IntelliWizard Inc. 
 * All rights reserved.
 * LICENSE: LGPL. 
 * Redistributions of source code modifications must send back to the Intelliwizard Project and republish them. 
 * Web: http://www.intelliwizard.com
 * eMail: info@intelliwizard.com
 * We provide technical supports for UML StateWizard users.
 * ==============================================================================================================================*/

#include "stdio.h"

#include "shared_memory_queue.h"

#include "SharedMemoryTestCase.h"

	#define SME_ASSERT(BoolExpress)       do { \
		if (!(BoolExpress)) {\
		printf("Assertion fails at %s (%d).\n", __FILE__, __LINE__); while(1); \
		}\
	} while(0)


struct SMBlock
{
	int test;
};

void setUp()
{
}

void tearDown()
{
}

void testShareMemory1()
{
	int blockCount = 10;
	int bIsMasterProcess = true;
	XSharedMemoryQueue* pShareMemBlock = new XSharedMemoryQueue();

	bool ret = pShareMemBlock->Initialize("test memory", sizeof(SMBlock), blockCount, 2);
	SME_ASSERT(ret==true);

	void* pPoint = pShareMemBlock->CreateSharedMemoryQueue();
	SME_ASSERT(pPoint!=0);
	SME_ASSERT(pPoint==pShareMemBlock->GetAt(0));

	SMBlock* pBlock = 0;
	SMBlock* pFirstBlock = 0;
	SMBlock* pLastBlock = 0;

	int i=0;
	for(i=0;i<blockCount;i++)
	{
		pBlock = (SMBlock*)pShareMemBlock->GetAt(i);
		pBlock->test = i;
	}

	pFirstBlock = (SMBlock*)pShareMemBlock->GetQueueHead(0);
	pBlock = pFirstBlock;
	for(i=0;;i++)
	{
		SME_ASSERT(pBlock->test==i);
		pBlock = (SMBlock*)pShareMemBlock->GetNext(pBlock);
		if(pBlock==pFirstBlock) break;
	}

	pFirstBlock = (SMBlock*)pShareMemBlock->GetQueueTail(0);
	pBlock = pFirstBlock;
	for(i=blockCount-1;;i--)
	{
		SME_ASSERT(pBlock->test==i);
		pBlock = (SMBlock*)pShareMemBlock->GetPrev(pBlock);
		if(pBlock==pFirstBlock) break;
	}

	//Move all blocks to the queue 1 one by one
	for(i=0;i<blockCount;i++)
	{
		pBlock = (SMBlock*)pShareMemBlock->GetAt(i);
		SME_ASSERT(pShareMemBlock->GetQueueHead(0)==pBlock);
		if(i==0)
            SME_ASSERT(pShareMemBlock->GetQueueTail(1)==0);
		else
			SME_ASSERT(pShareMemBlock->GetQueueTail(1)==pShareMemBlock->GetAt(i-1));

		pShareMemBlock->MoveToDestQueueTail(pBlock,1);
	}

	SME_ASSERT(pShareMemBlock->GetQueueHead(0)==0);
	SME_ASSERT(pShareMemBlock->GetQueueTail(1)==pShareMemBlock->GetAt(blockCount-1)); //???


	pFirstBlock = (SMBlock*)pShareMemBlock->GetQueueHead(1);
	pBlock = pFirstBlock;
	for(i=0;;i++)
	{
		SME_ASSERT(pBlock->test==i);
		pBlock = (SMBlock*)pShareMemBlock->GetNext(pBlock);
		if(pBlock==pFirstBlock) break;
	}

	//Move the block 0,3,6,.. to queue 0 one by one
	for(i=0;i<blockCount;i++)
	{
		if(i%3!=0) continue;

		pBlock = (SMBlock*)pShareMemBlock->GetAt(i);
		pShareMemBlock->MoveToDestQueueTail(pBlock,0);
	}

	pFirstBlock = (SMBlock*)pShareMemBlock->GetQueueHead(0);
	pBlock = pFirstBlock;
	for(i=0;;i++)
	{
		SME_ASSERT(pBlock->test==i*3);
		pBlock = (SMBlock*)pShareMemBlock->GetNext(pBlock);
		if(pBlock==pFirstBlock) break;
	}

	pFirstBlock = (SMBlock*)pShareMemBlock->GetQueueHead(1);
	pBlock = pFirstBlock;
	for(i=0;;i++)
	{
		SME_ASSERT(pBlock->test==i*3+1);
		pBlock = (SMBlock*)pShareMemBlock->GetNext(pBlock);
		if(pBlock==pFirstBlock) break;
		SME_ASSERT(pBlock->test==i*3+2);
		pBlock = (SMBlock*)pShareMemBlock->GetNext(pBlock);
		if(pBlock==pFirstBlock) break;
	}

	pShareMemBlock->DeleteSharedMemoryQueue();

	delete pShareMemBlock;
	pShareMemBlock = 0;
}

#include "ext_ipc_event.h"

void testIPCEventMaster1()
{
	printf("Master Process:\n");
	printf("Waiting for IPC events ........\n");

	int ret= XExtIPCEventCreate(0, TRUE);

	do 
	{
		IPCEventInfo EventInfo;
		EventInfo.EventID=0;
		
		ret= XExtIPCEventQueryIPCEvent(&EventInfo, NULL);
		
		if (ret >0 )
		{
			printf("An external IPC event is available: ID=%d P1=%d P2=%d \n", EventInfo.EventID, EventInfo.ulParameter1, EventInfo.ulParameter2);
			if (EventInfo.EventID<0)
				break;
		}

		SleepInMilliseconds(1000);
	} while (1);
	


	XExtIPCEventRelease(TRUE);

	/*
	int XExtIPCEventSend(IPCEventInfo* pInEventInfo, IPCEventInfo* pOutEventInfo, int nTimeout = -1 );
	int XExtIPCEventPost(IPCEventInfo* pInEventInfo);
	int (IPCEventInfo* pOutEventInfo, SME_IPC_EVENT_CALLBACK_T pfnCallbak);
	void XExtIPCEventRecycleEvent(int idProcess);
	*/
}

void testIPCEventSlave1()
{
	printf("Slave Process:\n");

	int ret = XExtIPCEventCreate(1, FALSE); //Slave Process. Process ID is 1

	if (ret<0)
	{
		printf("Error");
		return;
	}

	IPCEventInfo EventInfo;
	EventInfo.EventID=1;
	EventInfo.DestProcessID =0;
	EventInfo.ulParameter1 =100;
	EventInfo.ulParameter2 =200;

	IPCEventInfo OutEventInfo;
	
	ret= XExtIPCEventSend(&EventInfo, &OutEventInfo);

	if (ret ==0 )
	{
		printf("An external IPC event is sent.\n");
	}

	EventInfo.EventID=2;
	EventInfo.DestProcessID =0;
	EventInfo.ulParameter1 =100;
	EventInfo.ulParameter2 =200;

	ret= XExtIPCEventPost(&EventInfo);
	
	if (ret ==0 )
	{
		printf("An external IPC event is post.\n");
	}

	EventInfo.EventID=-1;
	EventInfo.DestProcessID =0;
	EventInfo.ulParameter1 =100;
	EventInfo.ulParameter2 =200;
	
	ret= XExtIPCEventPost(&EventInfo);
	
	if (ret ==0 )
	{
		printf("An external IPC event (EXIT) is post.\n");
	}


	XExtIPCEventRelease(FALSE);

	/*
	int XExtIPCEventSend(IPCEventInfo* pInEventInfo, IPCEventInfo* pOutEventInfo, int nTimeout = -1 );
	int XExtIPCEventPost(IPCEventInfo* pInEventInfo);
	int (IPCEventInfo* pOutEventInfo, SME_IPC_EVENT_CALLBACK_T pfnCallbak);
	void XExtIPCEventRecycleEvent(int idProcess);
	*/

}

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.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer (Senior)
United States United States
Alex "Question is more important than the answer."

Comments and Discussions