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 e0f17c36b839434858c37adafd2eada8e1c88f38..c64b3aa5f9fc9e2268e6192d2e49e6db93449b4f 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 5455dd26f19512f317a6ed734c148c1cc46836be..e2d3fbab62ec86684cb8ceaca2df24febd7e55ab 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 fdc1f06c1cba820c2bd55142dc9142e3d33a02a0..b36165e7497bdf93d5d5c7312e090fd95fc55ec5 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 1645ea7b38160f24631ab363fcebe1669b615fd2..b40202553e53a4fd6795fec70df5f68068891476 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 ae7ba3c87fb5e63199b9aceb72332d2a27126660..3261c07be9c300c6accfe3fb09d0b7e7ae882ef0 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 9dfde27d710a6d5acb383634af4584789c262150..5f8871fa5c9a78254eb6be4b5ab7545d51670181 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 }