http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50862

--- Comment #11 from bartek 'basz' szurgot <bartosz.szurgot at pwr dot wroc.pl> 
2011-10-26 12:41:34 UTC ---
i'm not sure about uncaught_exception(). i remember reading in Herb Sutter's
that it's usage should be avoided, since it has some flaw, that makes it's
return value unsure. but this was written in times of C++03 and i can't
remember what was the reasoning behind it (threading perhaps?), so i do not
know if it still holds for C++11 as well or not. any way there is still a
possibility of exception throwing from d-tor, which would be better to avoid.

for now my proposal to overcome this is something like:

struct _Unlock
{
  explicit _Unlock(_Lock& __lk) : _M_lock(&__lk) { __lk.unlock(); }
  ~_Unlock()
  {
    try
    {
      if(_M_lock)
        _M_lock->lock();
    }
    catch(...){}
  }
  _Lock &release(void)
  {
     _Lock* tmp=_M_Lock;
     _M_Lock=nullptr;
     return *tmp;
  }
private:
  _Lock* _M_lock;
};

unique_lock<mutex> __my_lock(_M_mutex);
_Unlock __unlock(__lock);
unique_lock<mutex> __my_lock2(std::move(__my_lock));
_M_cond.wait(__my_lock2);
__unlock.release().lock(); // if no exception so far - may throw here

general idea is to call lock() in d-tor inside the try-catch block, in case of
any exception, anywhere in the method, and if there was no one risen until the
last line we take responsibility for calling lock() from __unlock and call it
explicitly, so that exception can always be safely thrown from that call.

but perhaps we'd be able to come out with some better/cleaner/shorter solution
for this problem?

Reply via email to