Saturday, November 27, 2010

In Linux deal with shared object synchronization events

Manifest 4.ObjectWithEvents.cpp # include # include # include # include # include

*/returnObjectWithEvents::ms_pObjectWithEvents;} ObjectWithEvents::ObjectWithEvents():m_npEI(0){}voidObjectWithEvents::FireEvent(){//iteratethroughthecollectionfor(longi=0;iOnEvent(m_alPID[i],"");}} return;} boolObjectWithEvents::AddEventHandler(IEventSink*pEI){//NULLceckif(NULL==pEI){returnfalse;} //checkifthereisspaceforthiseventhandlerif(MAX_EVENT_HANDLERS==m_npEI){returnfalse;} //Addthiseventhandlertothecollectionm_alPID[m_npEI]=getpid();m_apEI[m_npEI++]=pEI;returntrue;} voidObjectWithEvents::SendMessage(){//Someprocessing//AndthenfiretheeventFireEvent();return;} The code in Listing 4, you can use the following script to compile: g ++-g-oshm_clientshm_client1.cppObjectWithEvents.cpp running shm_client, should see the following output: $./shm_clientshm_client1.cpp: 16Messagefrompid (3920): use of shared memory: no event cache now, in order in shared memory to instantiate ObjectWithEvents, we need to modify ObjectWithEvents implementation. 5. modify ObjectWithEvents.cpp//Toaddadeclarationforthe "new" operator: classObjectWithEvents: publicIObjectWithEvents {public: void * operatornew (unsignedint);};/ /ToincludeanadditionalheaderfortheInitializerclass:#include"Initializer.h"//Tooverloadtheoperator"new":void*ObjectWithEvents::operatornew(unsignedint){returnms_pObjectWithEvents;} //Then,FireEventiscompletelychanged:voidObjectWithEvents::FireEvent(){//WeneedtoserializeallaccesstothecollectionbymorethanoneprocessintiRetVal=Initializer::LockMutex();if(0!=iRetVal){return;} pid_tpid=getpid();//iteratethroughthecollectionandfireonlyeventsbelongingtothecurrentprocessfor(longi=0;i currentprocess.if(pid!=m_alPID[i]){continue;} //RecheckforNULLif(0!=m_apEI[i]){m_apEI[i]->OnEvent(pid,"");}} //releasethemutexif((0==iRetVal)&&(0!=Initializer::UnlockMutex())){//Dealwitherror.} return;} //ThefollowingarechangestoObjectWithEvents::AddEventHandler()://1.Beforeaccessingthecollection,welockthemutex:intbRetVal=Initializer::LockMutex();if(0!=bRetVal){returnfalse;} //2.Afteraccessingthecollection,wereleasethemutex:if((0==bRetVal)&&(0!=Initializer::UnlockMutex())){//Dealwitherror.} The shared memory object is instantiated, define a class Initializer. Manifest 6.Initializer. # ifndef__Initializer___ # define__Initializer__classInitializer {public: intm_smid; staticInitializerms_Initializer; Initializer (); staticpthread_mutex_tms_mutex; staticintLockMutex (); staticintUnlockMutex ();}; # Endif//__Initializer__Initializer defines shared memory idm_shmid and one to handle synchronization events ms_mutex semaphore. Function LockMutex () is responsible for the mutex is unlocked, UnlockMutex () to unlock the mutex. Initializer implementation as shown in Listing 7: Listing 7.Initializer.cpp # include # include # include # include # include #include"ObjectWithEvents.usingnamespacestd;InitializerInitializer::ms_Initializer;pthread_mutex_tInitializer::ms_mutex=PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;Initializer::Initializer():m_shmid(-1){boolbCreated=false;key_tkey=0x1234;m_shmid=shmget(key,sizeof(ObjectWithEvents),0666);if(-1==m_smid){if(ENOENT!=errno){cerr <> m_shmid=shmget(key,sizeof(ObjectWithEvents),IPC_CREAT|0666);if(-1==m_smid){cout <><> bCreated=true;} ObjectWithEvents::ms_pObjectWithEvents=(ObjectWithEvents*)shmat(m_shmid,NULL,0);if(NULL==ObjectWithEvents::ms_pObjectWithEvents){cout <><> if(true==bCreated){ObjectWithEvents*p=newObjectWithEvents();} //Createamutexwithnoinitialowner.pthread_mutex_init(&ms_mutex,NULL);} intInitializer::LockMutex(){//Requestownershipofmutex.pthread_mutex_lock(&ms_mutex);if(EDEADLK==errno){cout <> return0;} intInitializer::UnlockMutex(){returnpthread_mutex_unlock(&ms_mutex);}

No comments:

Post a Comment