aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog12
-rw-r--r--libstdc++-v3/include/bits/ios_base.h9
-rw-r--r--libstdc++-v3/src/ios.cc2
-rw-r--r--libstdc++-v3/src/ios_init.cc13
-rw-r--r--libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc2
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 9dfde27d..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 }