This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
gcc 2.95.2 bug(?): bastring::Rep not threadsafe?
- To: gcc-bugs at gcc dot gnu dot org
- Subject: gcc 2.95.2 bug(?): bastring::Rep not threadsafe?
- From: Koen Deforche <koen at easics dot be>
- Date: Wed, 10 May 2000 14:54:17 +0200
- Organization: Easics nv, Leuven, Belgium, http://www.easics.com
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++"