Iterating a map in ACE

STL containers are not thread safe but ACE containers support synchronization.
Consider you are using containers like std::map in multi threaded environment.
Normally there must be a critical section or a mutex which protects access to the container.
STL implementations do not provide such mechanism by default so C++ programmers must implement it.
ACE library has very flexible way of specifying needed level of synchronization.
For example a hash map with no synchronization code would look like:

typedef ACE_Map_Manager<unsigned long, std::string, ACE_Null_Mutex> StringMap;

For including synchronization primitives one must use one of the following instead of ACE_Null_Mutex:

  1. ACE_Thread_Mutex
  2. ACE_Recursive_Thread_Mutex
  3. ACE_RW_Mutex

Each of these primitives has its own area of application is often implemented differently on
Windows and Linux platforms. For example ACE_Thread_Mutex is a critical section on Windows, while
Linux version uses a kernel object.
But what if there is a need in traversing a map or hash map in multi threaded environment.
For such cases ACE provide a public method to access internal synchronization object stored inside a container.
The following code shows the idea
suppose we have somewhere:

 typedef ACE_Map_Manager<unsigned long, std::string, ACE_Thread_Mutex> StringMap;
 StringMap m_MapInstance;

A common code which iterates this container without depending on synchronization type would look like:

{
 typedef StringMap::lock_type ACE_MAP_LOCK_TYPE;
 ACE_Guard<ACE_MAP_LOCK_TYPE> l(m_MapInstance.mutex());
 for(StringMap::iterator it = m_MapInstance.begin(), end = m_MapInstance.end(); it!=end; ++it)
 {
  const std::string & strContent = (*it).int_id_;
  const unsigned long & ulID = (*it).ext_id_;
               //do something with the element here
 }
}

One must make sure there are no nested find, insert and erase commands inside such synchronized block. Otherwise there will be a deadlock situation since ACE container itself tries to guard access inside each read and write operation with specified synchronization primitive.

Leave a Reply