gcc 2.95.2 bug(?): bastring::Rep not threadsafe?

Koen Deforche koen@easics.be
Wed May 10 05:54:00 GMT 2000


Hi,

is it possible that bastring::Rep::grab() is non-thread safe
(in gcc 2.95.2 / Sparc) ?

observe bastring.h:

charT* grab () { if (selfish) return clone (); ++ref; return data (); }

It seems that you rely on the fact that ++ref is executed
as a single instruction? However, I observe random coredumps
because release() tries to delete &nilRep, and therefore I
suspect that (at least on Sparc) this incremeting
should be protected by a lock, or written using some assembly
code?

Anyway, since I modified it with the attached patch (which works
only for pthreads), I have not noticed anymore core dumps.

cheers,
koen.
--- bastring.original.h	Wed May 10 11:02:19 2000
+++ bastring.h	Wed May 10 11:03:44 2000
@@ -38,6 +38,14 @@
 // NOTE : This does NOT conform to the draft standard and is likely to change
 #include <alloc.h>
 
+#ifdef __STL_PTHREADS
+#   include <pthread.h>
+#   define __REF_LOCK \
+        pthread_mutex_lock(&_S_ref_lock)
+#   define __REF_UNLOCK \
+        pthread_mutex_unlock(&_S_ref_lock)
+#endif
+
 extern "C++" {
 class istream; class ostream;
 
@@ -72,7 +80,8 @@
 
     charT* data () { return reinterpret_cast<charT *>(this + 1); }
     charT& operator[] (size_t s) { return data () [s]; }
-    charT* grab () { if (selfish) return clone (); ++ref; return data (); }
+    charT* grab () { if (selfish) return clone (); __REF_LOCK; ++ref;
+		     __REF_UNLOCK; return data (); }
 #if defined __i486__ || defined __i586__ || defined __i686__
     void release ()
       {
@@ -123,6 +132,10 @@
 
   private:
     Rep &operator= (const Rep &);
+
+#ifdef __STL_PTHREADS
+    static pthread_mutex_t _S_ref_lock;
+#endif
   };
 
 public:
@@ -646,6 +659,15 @@
 operator<< (ostream&, const basic_string <charT, traits, Allocator>&);
 template <class charT, class traits, class Allocator> istream&
 getline (istream&, basic_string <charT, traits, Allocator>&, charT delim = '\n');
+
+#ifdef __STL_PTHREADS
+template <class charT, class traits, class Allocator>
+pthread_mutex_t
+basic_string<charT, traits, Allocator>::Rep::_S_ref_lock
+  = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+
 
 } // extern "C++"
 


More information about the Gcc-bugs mailing list