std::try_lock problems

Jonathan Wakely jwakely.gcc@gmail.com
Fri Dec 3 09:58:00 GMT 2010


I think we need something like the attached patch to fix two problems
in our std::try_lock:

1) exceptions are not caught (leaving the caller no way to know which
locks are held)

2) if a try_lock fails we call unlock on the failed lock, we should
only unlock the ones that succeeded

I need a version of std::lock() so am implementing that too.  In that
case I believe we do want to propagate exceptions, which means we need
to use RAII to do the unlocking.  I'm working on a simpler RAII-based
version of try_lock_impl which can work for both try_lock and lock,
and am writing tests to exercise the exceptional paths.

If anyone has any good ideas for a try-and-back-off algorithm let me
know, my current version is very basic.
-------------- next part --------------
Index: include/std/mutex
===================================================================
--- include/std/mutex	(revision 167396)
+++ include/std/mutex	(working copy)
@@ -663,16 +663,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 	static int
 	__do_try_lock(tuple<_Lock&...>& __locks)
 	{
-	  if(std::get<_Idx>(__locks).try_lock())
-	    {
-	      return __try_lock_impl<_Idx + 1,
-		_Idx + 2 < sizeof...(_Lock)>::__do_try_lock(__locks);
-	    }
-	  else
-	    {
-	      __unlock_impl<_Idx>::__do_unlock(__locks);
-	      return _Idx;
-	    }
+          __try
+            {
+              if(std::get<_Idx>(__locks).try_lock())
+                {
+                  return __try_lock_impl<_Idx + 1,
+                    _Idx + 2 < sizeof...(_Lock)>::__do_try_lock(__locks);
+                }
+            }
+          __catch(...)
+            {
+            }
+          __unlock_impl<_Idx - 1>::__do_unlock(__locks);
+          return _Idx;
 	}
     };
 
@@ -683,13 +686,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 	static int
 	__do_try_lock(tuple<_Lock&...>& __locks)
 	{
-	  if(std::get<_Idx>(__locks).try_lock())
-	    return -1;
-	  else
+          __try
+            {
+	      if(std::get<_Idx>(__locks).try_lock())
+	        return -1;
+	    }
+          __catch(...)
 	    {
-	      __unlock_impl<_Idx>::__do_unlock(__locks);
-	      return _Idx;
 	    }
+	  __unlock_impl<_Idx - 1>::__do_unlock(__locks);
+	  return _Idx;
 	}
     };
 


More information about the Libstdc++ mailing list