diff options
author | Benjamin Kosnik <bkoz@redhat.com> | 2003-12-15 19:03:13 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-12-15 19:03:13 +0000 |
commit | fa972243f6657d4558a11eb459292d0f6bc03d4b (patch) | |
tree | 7f2287749bdb532c7b8f07d4fdf2b69378b77add | |
parent | adf269c7af5d044cbd7b71e88dea7e04461d19a0 (diff) | |
download | gcc-fa972243f6657d4558a11eb459292d0f6bc03d4b.zip gcc-fa972243f6657d4558a11eb459292d0f6bc03d4b.tar.gz gcc-fa972243f6657d4558a11eb459292d0f6bc03d4b.tar.bz2 |
re PR libstdc++/12855 (Thread safety problems in ios_base::Init)
2003-12-15 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/12855
* include/bits/ios_base.h (Init::_S_ios_base_init): Change to
_S_refcount, make atomic.
* src/ios.cc: Adjust definition.
* src/ios_init.cc (ios_base::Init::Init): Use __exchange_and_add,
and __atomic_add.
(ios_base::Init::~Init): Same.
* testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust line numbers.
* testsuite/27_io/ios_base/cons/copy_neg.cc: Same.
From-SVN: r74642
-rw-r--r-- | libstdc++-v3/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/ios_base.h | 9 | ||||
-rw-r--r-- | libstdc++-v3/src/ios.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/src/ios_init.cc | 13 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc | 2 |
6 files changed, 27 insertions, 13 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e0f17c3..c64b3aa 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2003-12-15 Benjamin Kosnik <bkoz@redhat.com> + + PR libstdc++/12855 + * include/bits/ios_base.h (Init::_S_ios_base_init): Change to + _S_refcount, make atomic. + * src/ios.cc: Adjust definition. + * src/ios_init.cc (ios_base::Init::Init): Use __exchange_and_add, + and __atomic_add. + (ios_base::Init::~Init): Same. + * testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust line numbers. + * testsuite/27_io/ios_base/cons/copy_neg.cc: Same. + 2003-12-15 Paolo Carlini <pcarlini@suse.de> * include/bits/locale_facets.tcc (num_get::do_get(bool&)): diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 5455dd2..e2d3fba 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -493,14 +493,13 @@ namespace std ~Init(); // NB: Allows debugger applications use of the standard streams - // from operator new. _S_ios_base_init must be incremented in - // _S_ios_create _after_ initialization is completed. + // from operator new. static bool - _S_initialized() { return _S_ios_base_init; } + _S_initialized() { return _S_refcount > 0; } private: - static int _S_ios_base_init; - static bool _S_synced_with_stdio; + static _Atomic_word _S_refcount; + static bool _S_synced_with_stdio; }; // [27.4.2.2] fmtflags state functions diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index fdc1f06..b36165e 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -107,7 +107,7 @@ namespace std const int ios_base::_S_local_word_size; - int ios_base::Init::_S_ios_base_init = 0; + _Atomic_word ios_base::Init::_S_refcount; bool ios_base::Init::_S_synced_with_stdio = true; diff --git a/libstdc++-v3/src/ios_init.cc b/libstdc++-v3/src/ios_init.cc index 1645ea7..b402025 100644 --- a/libstdc++-v3/src/ios_init.cc +++ b/libstdc++-v3/src/ios_init.cc @@ -80,7 +80,7 @@ namespace std ios_base::Init::Init() { - if (_S_ios_base_init == 0) + if (__exchange_and_add(&_S_refcount, 1) == 0) { // Standard streams default to synced with "C" operations. _S_synced_with_stdio = true; @@ -110,15 +110,18 @@ namespace std wcin.tie(&wcout); wcerr.flags(ios_base::unitbuf); #endif - - _S_ios_base_init = 1; + + // NB: Have to set refcount above one, so that standard + // streams are not re-initialized with uses of ios_base::Init + // besides <iostream> static object, ie just using <ios> with + // ios_base::Init objects. + __atomic_add(&_S_refcount, 1); } - ++_S_ios_base_init; } ios_base::Init::~Init() { - if (--_S_ios_base_init == 1) + if (__exchange_and_add(&_S_refcount, -1) == 2) { // Catch any exceptions thrown by basic_ostream::flush() try diff --git a/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc b/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc index ae7ba3c..3261c07 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc @@ -41,5 +41,5 @@ void test01() io1 = io2; } // { dg-error "within this context" "" { target *-*-* } 41 } -// { dg-error "is private" "" { target *-*-* } 746 } +// { dg-error "is private" "" { target *-*-* } 745 } // { dg-error "operator=" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc b/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc index 9dfde27..5f8871f 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc @@ -41,5 +41,5 @@ void test02() test_base io2 = io1; } // { dg-error "within this context" "" { target *-*-* } 41 } -// { dg-error "is private" "" { target *-*-* } 743 } +// { dg-error "is private" "" { target *-*-* } 742 } // { dg-error "copy constructor" "" { target *-*-* } 0 } |