diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ad7afa1f20ad21c0218a90fc499b0eb3f2349515..1096742ba030880a92b05b03e710cd5f32b676a8 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2010-12-04  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+	* include/std/mutex (try_lock, __try_lock_impl): Fix.
+	(lock): Implement using __try_lock_impl.
+	* testsuite/30_threads/try_lock/2.cc: Fix logic.
+	* testsuite/30_threads/try_lock/4.cc: New.
+	* testsuite/30_threads/lock/1.cc: New.
+	* testsuite/30_threads/lock/2.cc: New.
+	* testsuite/30_threads/lock/3.cc: New.
+	* testsuite/30_threads/lock/4.cc: New.
+
 2010-12-02  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
 	* src/future.cc (future_category): Export compatibility symbol.
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index b9b924c4650530294ea8546ee6b6e63a0411b4a6..4c155113625f4d52d82cecd50fe36a3363056039 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -656,23 +656,27 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 	{ }
     };
 
+  template<typename _Lock>
+    unique_lock<_Lock>
+    __try_to_lock(_Lock& __l)
+    { return unique_lock<_Lock>(__l, try_to_lock); }
+
   template<int _Idx, bool _Continue = true>
     struct __try_lock_impl
     {
       template<typename... _Lock>
-	static int
-	__do_try_lock(tuple<_Lock&...>& __locks)
+	static void
+	__do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
 	{
-	  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;
-	    }
+          __idx = _Idx;
+          auto __lock = __try_to_lock(std::get<_Idx>(__locks));
+          if (__lock.owns_lock())
+            {
+              __try_lock_impl<_Idx + 1, _Idx + 2 < sizeof...(_Lock)>::
+                __do_try_lock(__locks, __idx);
+              if (__idx == -1)
+                __lock.release();
+            }
 	}
     };
 
@@ -680,16 +684,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
     struct __try_lock_impl<_Idx, false>
     {
       template<typename... _Lock>
-	static int
-	__do_try_lock(tuple<_Lock&...>& __locks)
+	static void
+	__do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
 	{
-	  if(std::get<_Idx>(__locks).try_lock())
-	    return -1;
-	  else
-	    {
-	      __unlock_impl<_Idx>::__do_unlock(__locks);
-	      return _Idx;
-	    }
+          __idx = _Idx;
+          auto __lock = __try_to_lock(std::get<_Idx>(__locks));
+          if (__lock.owns_lock())
+            {
+              __idx = -1;
+              __lock.release();
+            }
 	}
     };
 
@@ -707,14 +711,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
     int
     try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3)
     {
-      tuple<_Lock1&, _Lock2&, _Lock3&...> __locks(__l1, __l2, __l3...);
-      return __try_lock_impl<0>::__do_try_lock(__locks);
+      int __idx;
+      auto __locks = std::tie(__l1, __l2, __l3...);
+      __try
+      { __try_lock_impl<0>::__do_try_lock(__locks, __idx); }
+      __catch(...)
+      { }
+      return __idx;
     }
 
-  /// lock
+  /** @brief Generic lock.
+   *  @param __l1 Meets Mutex requirements (try_lock() may throw).
+   *  @param __l2 Meets Mutex requirements (try_lock() may throw).
+   *  @param __l3 Meets Mutex requirements (try_lock() may throw).
+   *  @throw An exception thrown by an argument's lock() or try_lock() member.
+   *  @post All arguments are locked.
+   *
+   *  All arguments are locked via a sequence of calls to lock(), try_lock()
+   *  and unlock().  If the call exits via an exception any locks that were
+   *  obtained will be released.
+   */
   template<typename _L1, typename _L2, typename ..._L3>
     void
-    lock(_L1&, _L2&, _L3&...);
+    lock(_L1& __l1, _L2& __l2, _L3&... __l3)
+    {
+      while (true)
+        {
+          unique_lock<_L1> __first(__l1);
+          int __idx;
+          auto __locks = std::tie(__l2, __l3...);
+          __try_lock_impl<0, sizeof...(_L3)>::__do_try_lock(__locks, __idx);
+          if (__idx == -1)
+            {
+              __first.release();
+              return;
+            }
+        }
+    }
 
   /// once_flag
   struct once_flag
diff --git a/libstdc++-v3/testsuite/30_threads/lock/1.cc b/libstdc++-v3/testsuite/30_threads/lock/1.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3f4f657aaf65ed176acb74f8de09bf7db7c39a3d
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/lock/1.cc
@@ -0,0 +1,65 @@
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+  typedef std::mutex mutex_type;
+  typedef std::unique_lock<mutex_type> lock_type;
+
+  try
+    {
+      mutex_type m1, m2, m3;
+      lock_type l1(m1, std::defer_lock), 
+	l2(m2, std::defer_lock),
+	l3(m3, std::defer_lock);
+
+      try
+	{
+	  std::lock(l1, l2, l3);
+	  VERIFY( l1.owns_lock() );
+	  VERIFY( l2.owns_lock() );
+	  VERIFY( l3.owns_lock() );
+	}
+      catch (const std::system_error& e)
+	{
+	  VERIFY( false );
+	}
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/lock/2.cc b/libstdc++-v3/testsuite/30_threads/lock/2.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bf3c8a86aca85ed18288356f5ea0ed09492f6cd6
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/lock/2.cc
@@ -0,0 +1,58 @@
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <mutex>
+#include <thread>
+#include <testsuite_hooks.h>
+
+void locker(std::mutex& m1, std::mutex& m2, std::mutex& m3)
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unique_lock<std::mutex> lock_type;
+
+  lock_type l1(m1, std::defer_lock);
+  lock_type l2(m2, std::defer_lock);
+  lock_type l3(m3, std::defer_lock);
+  std::lock(l1, l2, l3);
+  VERIFY( l1.owns_lock() );
+  VERIFY( l2.owns_lock() );
+  VERIFY( l3.owns_lock() );
+}
+
+void test01()
+{
+  std::mutex m1, m2, m3;
+  std::thread t1(locker, std::ref(m1), std::ref(m2), std::ref(m3));
+  std::thread t2(locker, std::ref(m3), std::ref(m2), std::ref(m1));
+  t1.join();
+  t2.join();
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/lock/3.cc b/libstdc++-v3/testsuite/30_threads/lock/3.cc
new file mode 100644
index 0000000000000000000000000000000000000000..18681c0d708fbec5a0e53fe93afeb122b282950d
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/lock/3.cc
@@ -0,0 +1,90 @@
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <mutex>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+struct user_lock
+{
+  user_lock() : is_locked(false) { }
+  ~user_lock() = default;
+  user_lock(const user_lock&) = default;
+
+  void lock()
+  {
+    bool test __attribute__((unused)) = true;
+    VERIFY( !is_locked );
+    is_locked = true;
+  }
+
+  bool try_lock() 
+  { return is_locked ? false : (is_locked = true); }
+
+  void unlock()
+  {
+    bool test __attribute__((unused)) = true;
+    VERIFY( is_locked );
+    is_locked = false;
+  }
+
+private:
+  bool is_locked;
+};
+
+int main()
+{
+  bool test __attribute__((unused)) = true;
+
+  try
+    {
+      std::mutex m1;
+      std::recursive_mutex m2;
+      user_lock m3;
+
+      try
+	{
+	  //heterogeneous types
+	  std::lock(m1, m2, m3);
+	  m1.unlock();
+	  m2.unlock();
+	  m3.unlock();
+	}
+      catch (const std::system_error& e)
+	{
+	  VERIFY( false );
+	}
+    }
+  catch (const std::system_error& e)
+    {
+      VERIFY( false );
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/lock/4.cc b/libstdc++-v3/testsuite/30_threads/lock/4.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c71a8a0aeaceb5ff25c038c023e1196d83bedbed
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/lock/4.cc
@@ -0,0 +1,152 @@
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <mutex>
+#include <testsuite_hooks.h>
+
+struct unreliable_lock
+{
+  std::mutex m;
+  std::unique_lock<std::mutex> l;
+
+  static int count;
+  static int throw_on;
+  static int lock_on;
+
+  unreliable_lock() : l(m, std::defer_lock) { }
+
+  ~unreliable_lock()
+  {
+    bool test __attribute__((unused)) = true;
+    VERIFY( !l.owns_lock() );
+  }
+
+  void lock()
+  {
+    if (count == throw_on)
+      throw throw_on;
+    ++count;
+    l.lock();
+  }
+  bool try_lock()
+  {
+    if (count == throw_on)
+      throw throw_on;
+    std::unique_lock<std::mutex> l2(m, std::defer_lock);
+    if (count == lock_on)
+      l2.lock();
+    ++count;
+    return l.try_lock();
+  }
+
+  void unlock()
+  {
+    bool test __attribute__((unused)) = true;
+    VERIFY( l.owns_lock() );
+    l.unlock();
+  }
+
+};
+
+int unreliable_lock::count = 0;
+int unreliable_lock::throw_on = -1;
+int unreliable_lock::lock_on = -1;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  unreliable_lock l1, l2, l3;
+
+  try
+    {
+      unreliable_lock::count = 0;
+      std::lock(l1, l2, l3);
+      VERIFY( unreliable_lock::count == 3 );
+      l1.unlock();
+      l2.unlock();
+      l3.unlock();
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  // test behaviour when a lock is already held
+  try
+    {
+      unreliable_lock::lock_on = 1;
+      while (unreliable_lock::lock_on < 3)
+      {
+        unreliable_lock::count = 0;
+        unreliable_lock l1, l2, l3;
+        std::lock(l1, l2, l3);
+        VERIFY( unreliable_lock::count > 3 );
+        l1.unlock();
+        l2.unlock();
+        l3.unlock();
+        ++unreliable_lock::lock_on;
+      }
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+void test03()
+{
+  // test behaviour when an exception is thrown
+  unreliable_lock::throw_on = 0;
+  while (unreliable_lock::throw_on < 3)
+  {
+    unreliable_lock::count = 0;
+    unreliable_lock l1, l2, l3;
+    bool test = false;
+    try
+      {
+        std::lock(l1, l2, l3);
+      }
+    catch (...)
+      {
+        test = true;
+      }
+    VERIFY( test );
+    ++unreliable_lock::throw_on;
+  }
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/try_lock/2.cc b/libstdc++-v3/testsuite/30_threads/try_lock/2.cc
index f1fa099eab0da328ea541e7e969ddaf4c6124e2d..b24e7e396571f357099a4b373a8bca72b4272931 100644
--- a/libstdc++-v3/testsuite/30_threads/try_lock/2.cc
+++ b/libstdc++-v3/testsuite/30_threads/try_lock/2.cc
@@ -27,6 +27,8 @@
 #include <system_error>
 #include <testsuite_hooks.h>
 
+typedef std::unique_lock<std::mutex> lock_type;
+
 void test01()
 {
   bool test __attribute__((unused)) = true;
@@ -34,12 +36,12 @@ void test01()
   try
     {
       std::mutex m1, m2, m3;
-      m1.lock();
+      lock_type l1(m1);
       int result = std::try_lock(m1, m2, m3);
       VERIFY( result == 0 );
-      m1.lock();
-      m2.lock();
-      m3.lock();
+      VERIFY( l1.owns_lock() );
+      lock_type l2(m2);
+      lock_type l3(m3);
     }
   catch (const std::system_error& e)
     {
@@ -58,12 +60,12 @@ void test02()
   try
     {
       std::mutex m1, m2, m3;
-      m2.lock();
+      lock_type l2(m2);
       int result = std::try_lock(m1, m2, m3);
       VERIFY( result == 1 );
-      m1.lock();
-      m2.lock();
-      m3.lock();
+      VERIFY( l2.owns_lock() );
+      lock_type l1(m1);
+      lock_type l3(m3);
     }
   catch (const std::system_error& e)
     {
@@ -82,12 +84,12 @@ void test03()
   try
     {
       std::mutex m1, m2, m3;
-      m3.lock();
+      lock_type l3(m3);
       int result = std::try_lock(m1, m2, m3);
       VERIFY( result == 2 );
-      m1.lock();
-      m2.lock();
-      m3.lock();
+      VERIFY( l3.owns_lock() );
+      lock_type l1(m1);
+      lock_type l2(m2);
     }
   catch (const std::system_error& e)
     {
diff --git a/libstdc++-v3/testsuite/30_threads/try_lock/4.cc b/libstdc++-v3/testsuite/30_threads/try_lock/4.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7750fc92478aeb2543daa384f0c75fa89e0e64d9
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/try_lock/4.cc
@@ -0,0 +1,153 @@
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
+// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <mutex>
+#include <testsuite_hooks.h>
+
+struct unreliable_lock
+{
+  std::mutex m;
+  std::unique_lock<std::mutex> l;
+
+  static int count;
+  static int throw_on;
+  static int lock_on;
+
+  unreliable_lock() : l(m, std::defer_lock) { }
+
+  ~unreliable_lock()
+  {
+    bool test __attribute__((unused)) = true;
+    VERIFY( !l.owns_lock() );
+  }
+
+  void lock()
+  {
+    if (count == throw_on)
+      throw throw_on;
+    ++count;
+    l.lock();
+  }
+  bool try_lock()
+  {
+    if (count == throw_on)
+      throw throw_on;
+    std::unique_lock<std::mutex> l2(m, std::defer_lock);
+    if (count == lock_on)
+      l2.lock();
+    ++count;
+    return l.try_lock();
+  }
+
+  void unlock()
+  {
+    bool test __attribute__((unused)) = true;
+    VERIFY( l.owns_lock() );
+    l.unlock();
+  }
+
+};
+
+int unreliable_lock::count = 0;
+int unreliable_lock::throw_on = -1;
+int unreliable_lock::lock_on = -1;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  unreliable_lock l1, l2, l3;
+
+  try
+    {
+      unreliable_lock::count = 0;
+      int result = std::try_lock(l1, l2, l3);
+      VERIFY( result == -1 );
+      VERIFY( unreliable_lock::count == 3 );
+      l1.unlock();
+      l2.unlock();
+      l3.unlock();
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  unreliable_lock l1, l2, l3;
+
+  try
+    {
+      // test behaviour when a lock is already held
+      unreliable_lock::lock_on = 0;
+      while (unreliable_lock::lock_on < 3)
+      {
+        unreliable_lock::count = 0;
+        int failed = std::try_lock(l1, l2, l3);
+        VERIFY( failed == unreliable_lock::lock_on );
+        ++unreliable_lock::lock_on;
+      }
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  unreliable_lock l1, l2, l3;
+
+  try
+    {
+      // test behaviour when an exception is thrown
+      unreliable_lock::throw_on = 0;
+      while (unreliable_lock::throw_on < 3)
+      {
+        unreliable_lock::count = 0;
+        int failed = std::try_lock(l1, l2, l3);
+        VERIFY( failed == unreliable_lock::throw_on );
+        ++unreliable_lock::throw_on;
+      }
+    }
+  catch (...)
+    {
+      VERIFY( false );
+    }
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}