re PR libstdc++/12855 (Thread safety problems in ios_base::Init)
authorBenjamin Kosnik <bkoz@redhat.com>
Mon, 15 Dec 2003 19:03:13 +0000 (19:03 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Mon, 15 Dec 2003 19:03:13 +0000 (19:03 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/ios_base.h
libstdc++-v3/src/ios.cc
libstdc++-v3/src/ios_init.cc
libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc
libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc

index e0f17c3..c64b3aa 100644 (file)
@@ -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&)):
index 5455dd2..e2d3fba 100644 (file)
@@ -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
index fdc1f06..b36165e 100644 (file)
@@ -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;
 
index 1645ea7..b402025 100644 (file)
@@ -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
index ae7ba3c..3261c07 100644 (file)
@@ -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 } 
index 9dfde27..5f8871f 100644 (file)
@@ -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 }