From 979e2c8f8b9325a5c75bfc1f388aa8f69b988d2c Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Fri, 30 Sep 2011 15:36:14 +0200 Subject: [PATCH] -fthreadsafe-statics uses a single lock on Mac OS X and thus leads to deadlock. --- configure.in | 53 +++++++++++++++++++++++++++++++- sal/inc/rtl/instance.hxx | 2 +- set_soenv.in | 1 + solenv/gbuild/gbuild.mk | 4 +++ solenv/gbuild/platform/macosx.mk | 4 +++ solenv/inc/settings.mk | 4 +++ solenv/inc/unxmacx.mk | 3 ++ 7 files changed, 69 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 2bf85ec55ee4..ac307042efa5 100644 --- a/configure.in +++ b/configure.in @@ -3470,6 +3470,57 @@ fi AC_SUBST(WITH_STLPORT) +dnl =================================================================== +dnl thread-safe statics +dnl =================================================================== +AC_MSG_CHECKING([whether $CXX supports thread safe statics]) +unset HAVE_THREADSAFE_STATICS +if test "$GCC" = "yes"; then + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS -fthreadsafe-statics" + AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,)],[HAVE_THREADSAFE_STATICS=TRUE],[]) + AC_LANG_POP([C++]) + CXXFLAGS=$save_CXXFLAGS + if test "$HAVE_THREADSAFE_STATICS" = "TRUE"; then + dnl Some C++ runtimes use a single lock for all static variables, which + dnl can cause deadlock in multi-threaded applications. This is not + dnl easily tested here; for POSIX-based systems, if executing the + dnl following C++ program does not terminate then the tool chain + dnl apparently has this problem: + dnl + dnl #include + dnl int h() { return 0; } + dnl void * g(void * unused) { + dnl static int n = h(); + dnl return &n; + dnl } + dnl int f() { + dnl pthread_t t; + dnl pthread_create(&t, 0, g, 0); + dnl pthread_join(t, 0); + dnl return 0; + dnl } + dnl int main() { + dnl static int n = f(); + dnl return n; + dnl } + dnl + dnl Mac OS X up to at least 10.7.1 is known to have this problem: + if test "$_os" = "Darwin"; then + unset HAVE_THREADSAFE_STATICS + AC_MSG_RESULT([broken (i.e., no)]) + else + AC_MSG_RESULT([yes]) + fi + else + AC_MSG_RESULT([no]) + fi +else + AC_MSG_RESULT([unknown (assuming no)]) +fi +AC_SUBST(HAVE_THREADSAFE_STATICS) + dnl =================================================================== dnl visibility and c++0x features dnl =================================================================== @@ -3508,7 +3559,7 @@ if test "$GCC" = "yes"; then fi AC_MSG_CHECKING([whether $CC supports -std=c++0x without Language Defect 757]) - save_CXXFLAGS=$CFLAGS + save_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS -std=c++0x" AC_LANG_PUSH([C++]) diff --git a/sal/inc/rtl/instance.hxx b/sal/inc/rtl/instance.hxx index 7080cecda44e..bcb1791e364b 100644 --- a/sal/inc/rtl/instance.hxx +++ b/sal/inc/rtl/instance.hxx @@ -386,7 +386,7 @@ namespace rtl { using the outer class (the one that derives from this base class) */ -#if (__GNUC__ >= 4) +#if defined HAVE_THREADSAFE_STATICS template class Static { public: diff --git a/set_soenv.in b/set_soenv.in index 5e05ab19a65c..036e2826adfd 100755 --- a/set_soenv.in +++ b/set_soenv.in @@ -1773,6 +1773,7 @@ ToFile( "HAVE_LD_HASH_STYLE","@HAVE_LD_HASH_STYLE@","e" ); ToFile( "WITH_LINKER_HASH_STYLE","@WITH_LINKER_HASH_STYLE@","e" ); ToFile( "HAVE_LD_BSYMBOLIC_FUNCTIONS", "@HAVE_LD_BSYMBOLIC_FUNCTIONS@","e" ); +ToFile( "HAVE_THREADSAFE_STATICS", "@HAVE_THREADSAFE_STATICS@", "e" ); ToFile( "HAVE_CXX0X", "@HAVE_CXX0X@", "e" ); ToFile( "CXX", $CXX, "e" ); ToFile( "MINGWCXX", "@MINGWCXX@", "e" ); diff --git a/solenv/gbuild/gbuild.mk b/solenv/gbuild/gbuild.mk index 88a15885e70e..393a25760877 100644 --- a/solenv/gbuild/gbuild.mk +++ b/solenv/gbuild/gbuild.mk @@ -259,6 +259,10 @@ ifeq ($(strip $(ENABLE_GRAPHITE)),TRUE) gb_GLOBALDEFS += -DENABLE_GRAPHITE endif +ifeq ($(HAVE_THREADSAFE_STATICS),TRUE) +gb_GLOBALDEFS += -DHAVE_THREADSAFE_STATICS +endif + gb_GLOBALDEFS := $(sort $(gb_GLOBALDEFS)) include $(GBUILDDIR)/Deliver.mk diff --git a/solenv/gbuild/platform/macosx.mk b/solenv/gbuild/platform/macosx.mk index b9347d194130..ba1438a80fad 100644 --- a/solenv/gbuild/platform/macosx.mk +++ b/solenv/gbuild/platform/macosx.mk @@ -109,6 +109,10 @@ ifeq ($(HAVE_GCC_NO_LONG_DOUBLE),TRUE) gb_CXXFLAGS += -Wno-long-double endif +ifneq ($(HAVE_THREADSAFE_STATICS),TRUE) +gb_CXXFLAGS += -fno-threadsafe-statics +endif + # these are to get g++ to switch to Objective-C++ mode # (see toolkit module for a case where it is necessary to do it this way) gb_OBJCXXFLAGS := -x objective-c++ -fobjc-exceptions diff --git a/solenv/inc/settings.mk b/solenv/inc/settings.mk index 6030f138a5a5..553d6650ecfe 100644 --- a/solenv/inc/settings.mk +++ b/solenv/inc/settings.mk @@ -1195,6 +1195,10 @@ CFLAGS+=-DENABLE_LAYOUT_EXPERIMENTAL=0 CDEFS+=-DGSTREAMER .ENDIF +.IF "$(HAVE_THREADSAFE_STATICS)" == "TRUE" +CDEFS += -DHAVE_THREADSAFE_STATICS +.END + # compose flags and defines for GUI .IF "$(TARGETTYPE)"=="GUI" CDEFS+= $(CDEFSGUI) diff --git a/solenv/inc/unxmacx.mk b/solenv/inc/unxmacx.mk index 17575ad741f5..18fd01e78f22 100644 --- a/solenv/inc/unxmacx.mk +++ b/solenv/inc/unxmacx.mk @@ -113,6 +113,9 @@ CFLAGSCXX=-pipe -malign-natural -fsigned-char $(ARCH_FLAGS) -Wno-ctor-dtor-priva .IF "$(HAVE_GCC_NO_LONG-DOUBLE)" == "TRUE" CFLAGSCXX+= -Wno-long-double .ENDIF +.IF "$(HAVE_THREADSAFE_STATICS)" != "TRUE" +CFLAGSCXX += -fno-threadsafe-statics +.ENDIF PICSWITCH:=-fPIC # Other flags