chanegd wxTlsValue to be pointer-like instead of value-like which doesn't work for UDTs; use __thread keyword with mingw32 >= 4.3 too; use library-based thread-specific variables support in wxString cache now that it is fixed to work there; finally added a unit test for TLS stuff

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55361 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-08-29 23:28:42 +00:00
parent b18f47d002
commit 8b73c5318c
17 changed files with 320 additions and 83 deletions

View File

@@ -13,7 +13,6 @@ datarootdir = @datarootdir@
INSTALL = @INSTALL@
EXEEXT = @EXEEXT@
WINDRES = @WINDRES@
REZ = @REZ@
SETFILE = @SETFILE@
BK_DEPS = @BK_DEPS@
BK_MAKE_PCH = @BK_MAKE_PCH@
@@ -101,6 +100,7 @@ TEST_OBJECTS = \
test_textfiletest.o \
test_atomic.o \
test_queue.o \
test_tls.o \
test_uris.o \
test_vectors.o \
test_evtconnection.o \
@@ -165,20 +165,12 @@ COND_MONOLITHIC_0___WXLIB_XML_p = \
@COND_USE_GUI_1@__test_gui___depname = test_gui$(EXEEXT)
@COND_PLATFORM_MAC_0@__test_gui___mac_setfilecmd = @true
@COND_PLATFORM_MAC_1@__test_gui___mac_setfilecmd = \
@COND_PLATFORM_MAC_1@ $(SETFILE) -a C test_gui$(EXEEXT)
@COND_PLATFORM_MAC_1@__test_gui___mac_rezcmd = $(__MACOSX_RESOURCES_p_1)
@COND_WXUNIV_1@__WXUNIV_DEFINE_p_4 = -d __WXUNIVERSAL__
@COND_PLATFORM_MAC_1@ $(SETFILE) -t APPL test_gui$(EXEEXT)
@COND_WXUNIV_1@__WXUNIV_DEFINE_p_5 = --define __WXUNIVERSAL__
@COND_USE_EXCEPTIONS_0@__EXCEPTIONS_DEFINE_p_4 = -d wxNO_EXCEPTIONS
@COND_USE_EXCEPTIONS_0@__EXCEPTIONS_DEFINE_p_5 = --define wxNO_EXCEPTIONS
@COND_USE_RTTI_0@__RTTI_DEFINE_p_4 = -d wxNO_RTTI
@COND_USE_RTTI_0@__RTTI_DEFINE_p_5 = --define wxNO_RTTI
@COND_USE_THREADS_0@__THREAD_DEFINE_p_4 = -d wxNO_THREADS
@COND_USE_THREADS_0@__THREAD_DEFINE_p_5 = --define wxNO_THREADS
@COND_SHARED_1@__DLLFLAG_p_4 = -d WXUSINGDLL
@COND_SHARED_1@__DLLFLAG_p_5 = --define WXUSINGDLL
@COND_TOOLKIT_MSW@__RCDEFDIR_p = -i \
@COND_TOOLKIT_MSW@ $(LIBDIRNAME)/wx/include/$(TOOLCHAIN_FULLNAME)
@COND_TOOLKIT_MSW@__RCDEFDIR_p_1 = --include-dir \
@COND_TOOLKIT_MSW@ $(LIBDIRNAME)/wx/include/$(TOOLCHAIN_FULLNAME)
@COND_PLATFORM_WIN32_1@__test_gui___win32rc = test_gui_sample_rc.o
@@ -217,12 +209,6 @@ COND_MONOLITHIC_0___WXLIB_CORE_p = \
@COND_ICC_PCH_1@ .pch/testprec_printfbench/testprec.h.gch
@COND_USE_PCH_1@___pch_testprec_printfbench_testprec_h_gch___depname \
@COND_USE_PCH_1@ = .pch/testprec_printfbench/testprec.h.gch
COND_TOOLKIT_MAC___MACOSX_RESOURCES_p_1 = $(REZ) -d __DARWIN__ -t APPL -d \
__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_4) $(__EXCEPTIONS_DEFINE_p_4) \
$(__RTTI_DEFINE_p_4) $(__THREAD_DEFINE_p_4) -i $(srcdir) $(__DLLFLAG_p_4) -i \
$(srcdir)/../samples $(__RCDEFDIR_p) -i $(top_srcdir)/include -o \
test_gui$(EXEEXT) Carbon.r sample.r
@COND_TOOLKIT_MAC@__MACOSX_RESOURCES_p_1 = $(COND_TOOLKIT_MAC___MACOSX_RESOURCES_p_1)
@COND_WXUNIV_1@__WXUNIV_DEFINE_p = -D__WXUNIVERSAL__
@COND_USE_EXCEPTIONS_0@__EXCEPTIONS_DEFINE_p = -DwxNO_EXCEPTIONS
@COND_USE_RTTI_0@__RTTI_DEFINE_p = -DwxNO_RTTI
@@ -274,7 +260,7 @@ test$(EXEEXT): $(TEST_OBJECTS)
@COND_USE_GUI_1@test_gui$(EXEEXT): $(TEST_GUI_OBJECTS) $(__test_gui___win32rc)
@COND_USE_GUI_1@ $(CXX) -o $@ $(TEST_GUI_OBJECTS) $(LDFLAGS) -L$(LIBDIRNAME) $(SAMPLES_RPATH_FLAG) $(CPPUNIT_LIBS) $(LIBS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) $(EXTRALIBS_FOR_GUI) $(__LIB_ZLIB_p) $(__LIB_REGEX_p) $(__LIB_EXPAT_p) $(EXTRALIBS_FOR_BASE)
@COND_USE_GUI_1@ $(__test_gui___mac_rezcmd)
@COND_USE_GUI_1@
@COND_USE_GUI_1@ $(__test_gui___mac_setfilecmd)
@COND_USE_GUI_1@ $(SAMPLES_RPATH_POSTLINK)
@@ -486,6 +472,9 @@ test_atomic.o: $(srcdir)/thread/atomic.cpp $(TEST_ODEP)
test_queue.o: $(srcdir)/thread/queue.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/thread/queue.cpp
test_tls.o: $(srcdir)/thread/tls.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/thread/tls.cpp
test_uris.o: $(srcdir)/uris/uris.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/uris/uris.cpp

View File

@@ -176,7 +176,8 @@ BENCHMARK_FUNC(BoostTLS)
BENCHMARK_FUNC(wxTLS)
{
static wxTLS_TYPE(int) s_global;
static wxTLS_TYPE(int) s_globalVar;
#define s_global wxTLS_VALUE(s_globalVar)
for ( int n = 0; n < NUM_ITER; n++ )
{

View File

@@ -87,6 +87,7 @@ TEST_OBJECTS = \
$(OBJS)\test_textfiletest.obj \
$(OBJS)\test_atomic.obj \
$(OBJS)\test_queue.obj \
$(OBJS)\test_tls.obj \
$(OBJS)\test_uris.obj \
$(OBJS)\test_vectors.obj \
$(OBJS)\test_evtconnection.obj \
@@ -515,6 +516,9 @@ $(OBJS)\test_atomic.obj: .\thread\atomic.cpp
$(OBJS)\test_queue.obj: .\thread\queue.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\thread\queue.cpp
$(OBJS)\test_tls.obj: .\thread\tls.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\thread\tls.cpp
$(OBJS)\test_uris.obj: .\uris\uris.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\uris\uris.cpp

View File

@@ -79,6 +79,7 @@ TEST_OBJECTS = \
$(OBJS)\test_textfiletest.o \
$(OBJS)\test_atomic.o \
$(OBJS)\test_queue.o \
$(OBJS)\test_tls.o \
$(OBJS)\test_uris.o \
$(OBJS)\test_vectors.o \
$(OBJS)\test_evtconnection.o \
@@ -493,6 +494,9 @@ $(OBJS)\test_atomic.o: ./thread/atomic.cpp
$(OBJS)\test_queue.o: ./thread/queue.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_tls.o: ./thread/tls.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_uris.o: ./uris/uris.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<

View File

@@ -80,6 +80,7 @@ TEST_OBJECTS = \
$(OBJS)\test_textfiletest.obj \
$(OBJS)\test_atomic.obj \
$(OBJS)\test_queue.obj \
$(OBJS)\test_tls.obj \
$(OBJS)\test_uris.obj \
$(OBJS)\test_vectors.obj \
$(OBJS)\test_evtconnection.obj \
@@ -600,6 +601,9 @@ $(OBJS)\test_atomic.obj: .\thread\atomic.cpp
$(OBJS)\test_queue.obj: .\thread\queue.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\thread\queue.cpp
$(OBJS)\test_tls.obj: .\thread\tls.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\thread\tls.cpp
$(OBJS)\test_uris.obj: .\uris\uris.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\uris\uris.cpp

View File

@@ -292,6 +292,7 @@ TEST_OBJECTS = &
$(OBJS)\test_textfiletest.obj &
$(OBJS)\test_atomic.obj &
$(OBJS)\test_queue.obj &
$(OBJS)\test_tls.obj &
$(OBJS)\test_uris.obj &
$(OBJS)\test_vectors.obj &
$(OBJS)\test_evtconnection.obj &
@@ -546,6 +547,9 @@ $(OBJS)\test_atomic.obj : .AUTODEPEND .\thread\atomic.cpp
$(OBJS)\test_queue.obj : .AUTODEPEND .\thread\queue.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_tls.obj : .AUTODEPEND .\thread\tls.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_uris.obj : .AUTODEPEND .\uris\uris.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<

View File

@@ -73,6 +73,7 @@
textfile/textfiletest.cpp
thread/atomic.cpp
thread/queue.cpp
thread/tls.cpp
uris/uris.cpp
vectors/vectors.cpp
weakref/evtconnection.cpp

View File

@@ -413,6 +413,10 @@ SOURCE=.\streams\textstreamtest.cpp
# End Source File
# Begin Source File
SOURCE=.\thread\tls.cpp
# End Source File
# Begin Source File
SOURCE=.\strings\tokenizer.cpp
# End Source File
# Begin Source File

View File

@@ -786,6 +786,8 @@
RelativePath=".\textfile\textfiletest.cpp"/>
<File
RelativePath=".\streams\textstreamtest.cpp"/>
<File
RelativePath=".\thread\tls.cpp"/>
<File
RelativePath=".\strings\tokenizer.cpp"/>
<File

View File

@@ -1004,6 +1004,9 @@
<File
RelativePath=".\streams\textstreamtest.cpp"
/>
<File
RelativePath=".\thread\tls.cpp"
/>
<File
RelativePath=".\strings\tokenizer.cpp"
/>

128
tests/thread/tls.cpp Normal file
View File

@@ -0,0 +1,128 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/thread/tls.cpp
// Purpose: wxTlsValue unit test
// Author: Vadim Zeitlin
// Created: 2008-08-28
// RCS-ID: $Id$
// Copyright: (c) 2008 Vadim Zeitlin
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#endif // WX_PRECOMP
#include "wx/thread.h"
#include "wx/tls.h"
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
namespace
{
// NB: this struct must be a POD, so don't use wxString as its member
struct PerThreadData
{
const char *name;
int number;
};
wxTLS_TYPE(PerThreadData) gs_threadDataVar;
#define gs_threadData wxTLS_VALUE(gs_threadDataVar)
wxTLS_TYPE(int) gs_threadIntVar;
#define gs_threadInt wxTLS_VALUE(gs_threadIntVar)
// ----------------------------------------------------------------------------
// test thread
// ----------------------------------------------------------------------------
// this thread arbitrarily modifies all global thread-specific variables to
// make sure that the changes in it are not visible from the main thread
class TLSTestThread : public wxThread
{
public:
// ctor both creates and starts the thread
TLSTestThread() : wxThread(wxTHREAD_JOINABLE) { Create(); Run(); }
virtual void *Entry()
{
gs_threadInt = 17;
gs_threadData.name = "worker";
gs_threadData.number = 2;
CPPUNIT_ASSERT_EQUAL( "worker", gs_threadData.name );
CPPUNIT_ASSERT_EQUAL( 2, gs_threadData.number );
return NULL;
}
};
} // anonymous namespace
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
class TLSTestCase : public CppUnit::TestCase
{
public:
TLSTestCase() { }
private:
CPPUNIT_TEST_SUITE( TLSTestCase );
CPPUNIT_TEST( TestInt );
CPPUNIT_TEST( TestStruct );
CPPUNIT_TEST_SUITE_END();
void TestInt();
void TestStruct();
DECLARE_NO_COPY_CLASS(TLSTestCase)
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( TLSTestCase );
// also include in it's own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TLSTestCase, "TLSTestCase" );
void TLSTestCase::TestInt()
{
CPPUNIT_ASSERT_EQUAL( 0, gs_threadInt );
gs_threadInt++;
CPPUNIT_ASSERT_EQUAL( 1, gs_threadInt );
TLSTestThread().Wait();
CPPUNIT_ASSERT_EQUAL( 1, gs_threadInt );
}
void TLSTestCase::TestStruct()
{
CPPUNIT_ASSERT_EQUAL( "", gs_threadData.name );
CPPUNIT_ASSERT_EQUAL( 0, gs_threadData.number );
gs_threadData.name = "main";
gs_threadData.number = 1;
CPPUNIT_ASSERT_EQUAL( 1, gs_threadData.number );
TLSTestThread().Wait();
CPPUNIT_ASSERT_EQUAL( "main", gs_threadData.name );
CPPUNIT_ASSERT_EQUAL( 1, gs_threadData.number );
}