Commit fa972243 by Benjamin Kosnik Committed by Benjamin Kosnik

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
parent adf269c7
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> 2003-12-15 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (num_get::do_get(bool&)): * include/bits/locale_facets.tcc (num_get::do_get(bool&)):
......
...@@ -493,14 +493,13 @@ namespace std ...@@ -493,14 +493,13 @@ namespace std
~Init(); ~Init();
// NB: Allows debugger applications use of the standard streams // NB: Allows debugger applications use of the standard streams
// from operator new. _S_ios_base_init must be incremented in // from operator new.
// _S_ios_create _after_ initialization is completed.
static bool static bool
_S_initialized() { return _S_ios_base_init; } _S_initialized() { return _S_refcount > 0; }
private: private:
static int _S_ios_base_init; static _Atomic_word _S_refcount;
static bool _S_synced_with_stdio; static bool _S_synced_with_stdio;
}; };
// [27.4.2.2] fmtflags state functions // [27.4.2.2] fmtflags state functions
......
...@@ -107,7 +107,7 @@ namespace std ...@@ -107,7 +107,7 @@ namespace std
const int ios_base::_S_local_word_size; 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; bool ios_base::Init::_S_synced_with_stdio = true;
......
...@@ -80,7 +80,7 @@ namespace std ...@@ -80,7 +80,7 @@ namespace std
ios_base::Init::Init() 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. // Standard streams default to synced with "C" operations.
_S_synced_with_stdio = true; _S_synced_with_stdio = true;
...@@ -110,15 +110,18 @@ namespace std ...@@ -110,15 +110,18 @@ namespace std
wcin.tie(&wcout); wcin.tie(&wcout);
wcerr.flags(ios_base::unitbuf); wcerr.flags(ios_base::unitbuf);
#endif #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() 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() // Catch any exceptions thrown by basic_ostream::flush()
try try
......
...@@ -41,5 +41,5 @@ void test01() ...@@ -41,5 +41,5 @@ void test01()
io1 = io2; io1 = io2;
} }
// { dg-error "within this context" "" { target *-*-* } 41 } // { dg-error "within this context" "" { target *-*-* } 41 }
// { dg-error "is private" "" { target *-*-* } 746 } // { dg-error "is private" "" { target *-*-* } 745 }
// { dg-error "operator=" "" { target *-*-* } 0 } // { dg-error "operator=" "" { target *-*-* } 0 }
...@@ -41,5 +41,5 @@ void test02() ...@@ -41,5 +41,5 @@ void test02()
test_base io2 = io1; test_base io2 = io1;
} }
// { dg-error "within this context" "" { target *-*-* } 41 } // { 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 } // { dg-error "copy constructor" "" { target *-*-* } 0 }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment