Oops.  Left some name mangling in there.  Fixed now.

On 3 February 2011 12:16, John Ky <newhoggy@gmail.com> wrote:
Hi boost users,

I've discovered that the following doesn't compile.

   using namespace boost::interprocess;
   interprocess_upgradable_mutex mutex;
   interprocess_condition cv;
   boost::posix_time::ptime deadline;

   {
      scoped_lock<interprocess_upgradable_mutex> lock(mutex);
      sharable_lock<interprocess_upgradable_mutex> lock2(mutex);
      cv.wait(lock); // doesn't compile
      cv.timed_wait(lock, deadline); // doesn't compile.
   }

It is failing because boost doesn't define the following methods:

   void interprocess_condition::do_wait(interprocess_upgradable_mutex  &mut);

   bool interprocess_condition::do_timed_wait(const boost::posix_time::ptime &abs_time, interprocess_upgradable_mutex &mut);

I was thinking of making a basic implementation like so:

Define a scoped_unlock class, which behaves just like scoped_lock except the constructor unlocks and the destructor locks.

Then define the following:

inline void interprocess_condition::do_wait(interprocess_upgradable_mutex &mut)
{
   scoped_unlock<interprocess_upgradable_mutex> unlock(mut);
   interprocess_mutex &internal_mutex = mut.m_mut;
   scoped_lock<interprocess_mutex> internal_lock(internal_mutex);
   this->wait(internal_lock);
}

inline bool interprocess_condition::do_timed_wait
   (const boost::posix_time::ptime &abs_time, interprocess_upgradable_mutex &mut)
{
   scoped_unlock<interprocess_upgradable_mutex> unlock(mut);
   interprocess_mutex &internal_mutex = mut.m_mut;
   scoped_lock<interprocess_mutex> internal_lock(internal_mutex);
   return this->timed_wait(internal_lock, abs_time);
}

These functions simply do the following:
  • unlock the exclusive lock on the interprocess_upgradable_mutex (which is emulated with an internal interprocess_mutex)
  • then lock the internal interprocess_mutex
  • Call interprocess_condition::wait or interprocess_condition::time_ wait on the implementation lock which does all the work
  • unlock the internal interprocess_mutex
  • relock the exclusive lock on  the interprocess_upgradable_mutex 
Intuitively, this should work.

Is there anything I missed that would make this an incorrect implementation?

Cheers,

-John