c++ - critical section for a queue inside a thread -


i have singleton event class has queue , thread on it. implementation like, there several modules/object subscribes event(s) , able post multiple events.

the purpose of event class receive event on push on queue , thread inside class needs pop event , send same respective subscribed modules/objects.

the idea behind creating c++ bases eventaggregator available on c#.

the implementation

    void c_eventaggregator::postevent(event_uid eventuid) {     c_criticalregion criticalregion(easyncobj);     queue.push_back(eventuid);     criticalregion.~c_criticalregion(); }  void c_eventaggregator::dispatcheventtoclients(event_uid eventuid) {     eventclientslist eclist = _eventidsubslist[eventuid];      (eventclientslist::iterator iter = eclist.begin(); iter != eclist.end(); iter++) {         iter->second->receiveevent(eventuid);     }  }  int c_eventaggregator::subscribeevent(event_clientid clientid, c_eventclient *ecptr, event_uid eventuid) {     try     {         _eventidsubslist[eventuid].insert(make_pair(clientid, ecptr));     }     catch (int exception)     {         return exception;     }     return zero_value; }  void c_eventaggregator::run(void) {     event_uid eventuid;      while (isalive())     {         while (queue.size())         {             if (!queue.empty())             {                 c_criticalregion criticalregion(easyncobj);                 eventuid = queue[0];                 queue.pop_front();                  dispatcheventtoclients(eventuid);                 criticalregion.~c_criticalregion();             }         }     } } 

i using critical section between push , pop, queue doesn't overwritten when multiple modules/object write @ same time. (not sure whether correct).

my critical section handler like

class c_criticalregion{   public:     c_criticalregion(c_syncobject &pasyncobject) : msyncobject(pasyncobject){       msyncobject.lock();     }      ~c_criticalregion(){       msyncobject.unlock();     }    private:     c_syncobject &msyncobject;  }; 

synchronization object sync.cpp,

c_syncobject::c_syncobject(){     initializecriticalsection(&m_omutexhandle); }  c_syncobject::~c_syncobject(){     deletecriticalsection(&m_omutexhandle); } 

synch.h:

class c_syncobject{ private: protected:     //! win32 critical_section handle of operating system.     critical_section m_omutexhandle;  public:     c_syncobject();     ~c_syncobject();     /*!\brief lock resource coming after lock command     *     * function blocks until lock coming critical section.     */     void lock(void){         entercriticalsection(&m_omutexhandle);         //todo handle return value     };     //!free resource coming after lock command       void unlock(void){         leavecriticalsection(&m_omutexhandle);         //todo handle return value     }; }; 

issue face here code doesn't work sometime unless comment criticalregion.~c_criticalregion() inside postevent(). similarly, when there event send postevent, queue inside run() still shows size zero.

this kind of trivial end getting same situation on other files has similar kind of implementation.

also know, when release critical section, after completing task dispatcheventtoclients() or before.

you mustn't call destructor explicitly in case. actually, there little cases when should call it, won't ever face 1 of them (i've 1 in life , dirty hack).

here problem:

void c_eventaggregator::postevent(event_uid eventuid) {     c_criticalregion criticalregion(easyncobj);     queue.push_back(eventuid);     criticalregion.~c_criticalregion();    // <<< wrong } 

by code criticalregion destructor called twice - once , once compiler.

this kind of classes called guards , avoid explicit call "clean-up" (leavecriticalsection in case). in case it's not big deal, there lot of returns in function , it's mess put everywhere. , explicit call won't called in case of exception.

you can check simple example with explicit call , w/o explicit call


Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

How to get the ip address of VM and use it to configure SSH connection dynamically in Ansible -

javascript - Get parameter of GET request -