memory, [...]: Use mutex to make _Sp_counted_base::add_ref_lock() thread-safe.

* include/tr1/memory, include/tr1/boost_shared_ptr.h: Use mutex
	to make _Sp_counted_base::add_ref_lock() thread-safe. Check whether
	to destroy resources by testing for equality, not inequality. Add
	empty critical sections to solve memory visibility issues.
	* testsuite/tr1/2_general_utilities/memory/
	shared_ptr/cons/auto_ptr_neg.cc: Use dg-excess-errors instead of
	explicitly listing line numbers which need to be kept in sync.
	* testsuite/tr1/2_general_utilities/memory/
	shared_ptr/assign/auto_ptr_neg.cc: Same.
	* testsuite/tr1/2_general_utilities/memory/
	shared_ptr/assign/auto_ptr_rvalue_neg.cc: Same.
	* testsuite/tr1/2_general_utilities/memory/
	shared_ptr/cons/weak_ptr_expired.cc: Make XFAIL for consistency when
	-fno-exceptions.
	* testsuite/tr1/2_general_utilities/memory/
	enable_shared_from_this/not_shared.cc: Add explanatory comments.
	* testsuite/tr1/2_general_utilities/memory/
	enable_shared_from_this/not_shared2.cc: Same.
	* testsuite/tr1/2_general_utilities/memory/
	enable_shared_from_this/not_shared3.cc: Same.

From-SVN: r97620
This commit is contained in:
Jonathan Wakely 2005-04-05 12:08:55 +01:00
parent 1de2bc2a00
commit fcec20a758
10 changed files with 52 additions and 14 deletions

View File

@ -1,3 +1,26 @@
2005-04-05 Jonathan Wakely <redi@gcc.gnu.org>
* include/tr1/memory, include/tr1/boost_shared_ptr.h: Use mutex
to make _Sp_counted_base::add_ref_lock() thread-safe. Check whether
to destroy resources by testing for equality, not inequality. Add
empty critical sections to solve memory visibility issues.
* testsuite/tr1/2_general_utilities/memory/
shared_ptr/cons/auto_ptr_neg.cc: Use dg-excess-errors instead of
explicitly listing line numbers which need to be kept in sync.
* testsuite/tr1/2_general_utilities/memory/
shared_ptr/assign/auto_ptr_neg.cc: Same.
* testsuite/tr1/2_general_utilities/memory/
shared_ptr/assign/auto_ptr_rvalue_neg.cc: Same.
* testsuite/tr1/2_general_utilities/memory/
shared_ptr/cons/weak_ptr_expired.cc: Make XFAIL for consistency when
-fno-exceptions.
* testsuite/tr1/2_general_utilities/memory/
enable_shared_from_this/not_shared.cc: Add explanatory comments.
* testsuite/tr1/2_general_utilities/memory/
enable_shared_from_this/not_shared2.cc: Same.
* testsuite/tr1/2_general_utilities/memory/
enable_shared_from_this/not_shared3.cc: Same.
2005-04-05 Kelley Cook <kcook@gcc.gnu.org> 2005-04-05 Kelley Cook <kcook@gcc.gnu.org>
* acconfig.h: Delete macros already ACDEFINED. * acconfig.h: Delete macros already ACDEFINED.

View File

@ -131,19 +131,22 @@ public:
void void
add_ref_lock() add_ref_lock()
{ {
if (_M_use_count <= 0) // TODO not yet MT safe XXX __gnu_cxx::lock lock(_M_mutex);
if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0)
{ {
_M_use_count = 0;
__throw_bad_weak_ptr(); __throw_bad_weak_ptr();
} }
__gnu_cxx::__atomic_add(&_M_use_count, 1);
} }
void void
release() // nothrow release() // nothrow
{ {
if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) <= 1) if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1)
{ {
dispose(); dispose();
__glibcxx_mutex_lock(_M_mutex);
__glibcxx_mutex_unlock(_M_mutex);
weak_release(); weak_release();
} }
} }
@ -157,8 +160,10 @@ public:
void void
weak_release() // nothrow weak_release() // nothrow
{ {
if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) <= 1) if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
{ {
__glibcxx_mutex_lock(_M_mutex);
__glibcxx_mutex_unlock(_M_mutex);
destroy(); destroy();
} }
} }
@ -176,6 +181,7 @@ private:
_Atomic_word _M_use_count; // #shared _Atomic_word _M_use_count; // #shared
_Atomic_word _M_weak_count; // #weak + (#shared != 0) _Atomic_word _M_weak_count; // #weak + (#shared != 0)
__gnu_cxx::mutex_type _M_mutex;
}; };
template <typename _Ptr, typename _Deleter> template <typename _Ptr, typename _Deleter>

View File

@ -43,6 +43,7 @@
#include <bits/gthr.h> #include <bits/gthr.h>
#include <bits/atomicity.h> #include <bits/atomicity.h>
#include <bits/functexcept.h> #include <bits/functexcept.h>
#include <bits/concurrence.h>
#include <debug/debug.h> #include <debug/debug.h>
#include <tr1/boost_shared_ptr.h> #include <tr1/boost_shared_ptr.h>

View File

@ -39,10 +39,12 @@ test01()
} }
catch (const std::tr1::bad_weak_ptr&) catch (const std::tr1::bad_weak_ptr&)
{ {
// Expected.
__throw_exception_again; __throw_exception_again;
} }
catch (...) catch (...)
{ {
// Failed.
} }
return 0; return 0;

View File

@ -41,8 +41,13 @@ test01()
} }
catch (const std::tr1::bad_weak_ptr&) catch (const std::tr1::bad_weak_ptr&)
{ {
// Expected.
__throw_exception_again; __throw_exception_again;
} }
catch (...)
{
// Failed.
}
return 0; return 0;
} }

View File

@ -42,8 +42,13 @@ test01()
} }
catch (const std::tr1::bad_weak_ptr&) catch (const std::tr1::bad_weak_ptr&)
{ {
// Expected.
__throw_exception_again; __throw_exception_again;
} }
catch (...)
{
// Failed.
}
return 0; return 0;
} }

View File

@ -47,6 +47,4 @@ main()
test01(); test01();
return 0; return 0;
} }
// { dg-error "In constructor" "" { target *-*-* } 0 } // { dg-excess-errors "In constructor" }
// { dg-error "cannot convert" "" { target *-*-* } 0 }
// { dg-error "instantiated from" "" { target *-*-* } 0 }

View File

@ -46,5 +46,4 @@ main()
test01(); test01();
return 0; return 0;
} }
// { dg-error "auto_ptr" "" { target *-*-* } 0 } // { dg-excess-errors "candidates are" }
// { dg-error "shared_ptr" "" { target *-*-* } 0 }

View File

@ -45,6 +45,4 @@ main()
test01(); test01();
return 0; return 0;
} }
// { dg-error "shared_ptr" "candidates are" { target *-*-* } 478 } // { dg-excess-errors "candidates are" }
// { dg-error "shared_ptr" "" { target *-*-* } 468 }

View File

@ -1,3 +1,4 @@
// { dg-do run { xfail *-*-* } }
// Copyright (C) 2005 Free Software Foundation // Copyright (C) 2005 Free Software Foundation
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
@ -34,6 +35,7 @@ test01()
std::tr1::shared_ptr<A> a1(new A); std::tr1::shared_ptr<A> a1(new A);
std::tr1::weak_ptr<A> wa(a1); std::tr1::weak_ptr<A> wa(a1);
a1.reset(); a1.reset();
VERIFY( wa.expired() );
try try
{ {
std::tr1::shared_ptr<A> a2(wa); std::tr1::shared_ptr<A> a2(wa);
@ -41,13 +43,12 @@ test01()
catch (const std::tr1::bad_weak_ptr&) catch (const std::tr1::bad_weak_ptr&)
{ {
// Expected. // Expected.
__throw_exception_again;
} }
catch (...) catch (...)
{ {
// Failed. // Failed.
__throw_exception_again;
} }
VERIFY( wa.expired() );
return 0; return 0;
} }