This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/12658] Thread safety problems in locale::global() and locale::locale()


------- Additional Comments From bkoz at gcc dot gnu dot org  2003-12-13 06:35 -------

Well......... something like this will work. It's modeled off of the glibc
setlocale bits, and I think it will work. 

Thoughts?

2003-12-13  Benjamin Kosnik  <bkoz@redhat.com>

	PR libstdc++/12658
	* include/Makefile.am (bits_headers): Add concurrence.h.
	* include/Makefile.in: Regenerated.
	* include/bits/concurrence.h: New.
	* src/locale_init.cc: Use it.
	(locale::locale): Lock critical regions.
	(locale::global): Same.
  
Index: include/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/Makefile.am,v
retrieving revision 1.72
diff -c -p -r1.72 Makefile.am
*** include/Makefile.am	11 Nov 2003 20:09:07 -0000	1.72
--- include/Makefile.am	13 Dec 2003 06:32:27 -0000
*************** bits_headers = \
*** 101,106 ****
--- 101,107 ----
  	${bits_srcdir}/char_traits.h \
  	${bits_srcdir}/codecvt.h \
  	${bits_srcdir}/concept_check.h \
+ 	${bits_srcdir}/concurrence.h \
  	${bits_srcdir}/cpp_type_traits.h \
  	${bits_srcdir}/demangle.h \
  	${bits_srcdir}/deque.tcc \
Index: include/bits/concurrence.h
===================================================================
RCS file: include/bits/concurrence.h
diff -N include/bits/concurrence.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- include/bits/concurrence.h	13 Dec 2003 06:32:27 -0000
***************
*** 0 ****
--- 1,54 ----
+ // Support for concurrent programing -*- C++ -*-
+ 
+ // Copyright (C) 2003
+ // Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction.  Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License.  This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+  
+ #ifndef _CONCURRENCE
+ #define _CONCURRENCE 1
+ 
+ // GCC's thread abstraction layer
+ #include "bits/gthr.h"
+ 
+ #if __GTHREADS
+ # ifdef __GTHREAD_MUTEX_INIT
+ #  define __glibcxx_mutex_define_initialized(NAME) \
+ __gthread_mutex_t NAME = __GTHREAD_MUTEX_INIT
+ # else
+ #  define __glibcxx_mutex_define_initialized(NAME) \
+ __gthread_mutex_t NAME; \
+ __GTHREAD_MUTEX_INIT_FUNCTION(&NAME)
+ # endif
+ # define __glibcxx_mutex_lock(LOCK) __gthread_mutex_lock(&LOCK)
+ # define __glibcxx_mutex_unlock(LOCK) __gthread_mutex_unlock(&LOCK)
+ #else
+ # define __glibcxx_mutex_define_initialized(NAME)
+ # define __glibcxx_mutex_lock(LOCK) 
+ # define __glibcxx_mutex_unlock(LOCK) 
+ #endif
+ 
+ #endif
Index: src/locale_init.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale_init.cc,v
retrieving revision 1.3
diff -c -p -r1.3 locale_init.cc
*** src/locale_init.cc	24 Nov 2003 17:24:40 -0000	1.3
--- src/locale_init.cc	13 Dec 2003 06:32:27 -0000
***************
*** 33,38 ****
--- 33,39 ----
  #include <cwctype>     // For towupper, etc.
  #include <locale>
  #include <bits/atomicity.h>
+ #include <bits/concurrence.h>
  
  namespace __gnu_cxx
  {
*************** namespace std 
*** 96,116 ****
    locale::locale() throw()
    { 
      _S_initialize(); 
!     (_M_impl = _S_global)->_M_add_reference(); 
    }
  
    locale
    locale::global(const locale& __other)
    {
      _S_initialize();
! 
!     // XXX MT
      _Impl* __old = _S_global;
      __other._M_impl->_M_add_reference();
      _S_global = __other._M_impl; 
      if (_S_global->_M_check_same_name() 
  	&& (std::strcmp(_S_global->_M_names[0], "*") != 0))
        setlocale(LC_ALL, __other.name().c_str());
  
      // Reference count sanity check: one reference removed for the
      // subsition of __other locale, one added by return-by-value. Net
--- 97,121 ----
    locale::locale() throw()
    { 
      _S_initialize(); 
!     __glibcxx_mutex_define_initialized(lock);
!     __glibcxx_mutex_lock(lock);
!     (_M_impl = _S_global)->_M_add_reference();
!     __glibcxx_mutex_unlock(lock);
    }
  
    locale
    locale::global(const locale& __other)
    {
      _S_initialize();
!     __glibcxx_mutex_define_initialized(lock);
!     __glibcxx_mutex_lock(lock);
      _Impl* __old = _S_global;
      __other._M_impl->_M_add_reference();
      _S_global = __other._M_impl; 
      if (_S_global->_M_check_same_name() 
  	&& (std::strcmp(_S_global->_M_names[0], "*") != 0))
        setlocale(LC_ALL, __other.name().c_str());
+     __glibcxx_mutex_unlock(lock);
  
      // Reference count sanity check: one reference removed for the
      // subsition of __other locale, one added by return-by-value. Net


-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bkoz at redhat dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12658


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]