Update of /cvsroot/boost/boost/libs/thread/src
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv7391
Modified Files:
tss_hooks.cpp
Log Message:
Simplification, avoids a false leak report
Index: tss_hooks.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/tss_hooks.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- tss_hooks.cpp 6 Aug 2004 15:31:08 -0000 1.3
+++ tss_hooks.cpp 24 Jul 2006 19:00:30 -0000 1.4
@@ -1,4 +1,6 @@
// (C) Copyright Michael Glassford 2004.
+// Copyright (c) 2006 Peter Dimov
+//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,178 +9,148 @@
#if defined(BOOST_HAS_WINTHREADS)
- #include <boost/thread/detail/tss_hooks.hpp>
+#include <boost/thread/detail/tss_hooks.hpp>
- #include <boost/assert.hpp>
- #include <boost/thread/mutex.hpp>
- #include <boost/thread/once.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/once.hpp>
- #include <list>
+#include <list>
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
- namespace
- {
- typedef std::list<thread_exit_handler> thread_exit_handlers;
+namespace
+{
- boost::once_flag once_init_threadmon_mutex = BOOST_ONCE_INIT;
- boost::mutex* threadmon_mutex;
- void init_threadmon_mutex(void)
- {
- threadmon_mutex = new boost::mutex;
- if (!threadmon_mutex)
- throw boost::thread_resource_error();
- }
+typedef std::list<thread_exit_handler> thread_exit_handlers;
- const DWORD invalid_tls_key = TLS_OUT_OF_INDEXES;
- DWORD tls_key = invalid_tls_key;
+const DWORD invalid_tls_key = TLS_OUT_OF_INDEXES;
+DWORD tls_key = invalid_tls_key;
- unsigned long attached_thread_count = 0;
- }
+boost::once_flag once_init_tls_key = BOOST_ONCE_INIT;
- /*
- Calls to DllMain() and tls_callback() are serialized by the OS;
- however, calls to at_thread_exit are not, so it must be protected
- by a mutex. Since we already need a mutex for at_thread_exit(),
- and since there is no guarantee that on_process_enter(),
- on_process_exit(), on_thread_enter(), and on_thread_exit()
- will be called only from DllMain() or tls_callback(), it makes
- sense to protect those, too.
- */
+void init_tls_key()
+{
+ tls_key = TlsAlloc();
+}
- extern "C" BOOST_THREAD_DECL int at_thread_exit(
- thread_exit_handler exit_handler
- )
- {
- boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
- boost::mutex::scoped_lock lock(*threadmon_mutex);
+} // unnamed namespace
- //Allocate a tls slot if necessary.
+extern "C" BOOST_THREAD_DECL int at_thread_exit( thread_exit_handler
exit_handler )
+{
+ boost::call_once( init_tls_key, once_init_tls_key );
- if (tls_key == invalid_tls_key)
- tls_key = TlsAlloc();
+ if( tls_key == invalid_tls_key )
+ {
+ return -1;
+ }
- if (tls_key == invalid_tls_key)
- return -1;
+ // Get the exit handlers list for the current thread from tls.
- //Get the exit handlers list for the current thread from tls.
+ thread_exit_handlers* exit_handlers =
+ static_cast< thread_exit_handlers* >( TlsGetValue( tls_key ) );
- thread_exit_handlers* exit_handlers =
- static_cast<thread_exit_handlers*>(TlsGetValue(tls_key));
+ if( exit_handlers == 0 )
+ {
+ // No exit handlers list was created yet.
- if (!exit_handlers)
+ try
{
- //No exit handlers list was created yet.
-
- try
- {
- //Attempt to create a new exit handlers list.
-
- exit_handlers = new thread_exit_handlers;
- if (!exit_handlers)
- return -1;
+ // Attempt to create a new exit handlers list.
- //Attempt to store the list pointer in tls.
+ exit_handlers = new thread_exit_handlers;
- if (TlsSetValue(tls_key, exit_handlers))
- ++attached_thread_count;
- else
- {
- delete exit_handlers;
- return -1;
- }
- }
- catch (...)
+ if( exit_handlers == 0 )
{
return -1;
}
- }
- //Like the C runtime library atexit() function,
- //functions should be called in the reverse of
- //the order they are added, so push them on the
- //front of the list.
+ // Attempt to store the list pointer in tls.
- try
- {
- exit_handlers->push_front(exit_handler);
+ if( !TlsSetValue( tls_key, exit_handlers ) )
+ {
+ delete exit_handlers;
+ return -1;
+ }
}
- catch (...)
+ catch( ... )
{
return -1;
}
-
- //Like the atexit() function, a result of zero
- //indicates success.
-
- return 0;
}
- extern "C" BOOST_THREAD_DECL void on_process_enter(void)
- {
- boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
- boost::mutex::scoped_lock lock(*threadmon_mutex);
+ // Like the C runtime library atexit() function,
+ // functions should be called in the reverse of
+ // the order they are added, so push them on the
+ // front of the list.
- BOOST_ASSERT(attached_thread_count == 0);
+ try
+ {
+ exit_handlers->push_front( exit_handler );
}
-
- extern "C" BOOST_THREAD_DECL void on_process_exit(void)
+ catch( ... )
{
- boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
- boost::mutex::scoped_lock lock(*threadmon_mutex);
-
- BOOST_ASSERT(attached_thread_count == 0);
+ return -1;
+ }
- //Free the tls slot if one was allocated.
+ // Like the atexit() function, a result of zero
+ // indicates success.
- if (tls_key != invalid_tls_key)
- {
- TlsFree(tls_key);
- tls_key = invalid_tls_key;
- }
- }
+ return 0;
+}
- extern "C" BOOST_THREAD_DECL void on_thread_enter(void)
- {
- //boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
- //boost::mutex::scoped_lock lock(*threadmon_mutex);
- }
+extern "C" BOOST_THREAD_DECL void on_process_enter()
+{
+}
- extern "C" BOOST_THREAD_DECL void on_thread_exit(void)
- {
- boost::call_once(init_threadmon_mutex, once_init_threadmon_mutex);
- boost::mutex::scoped_lock lock(*threadmon_mutex);
+extern "C" BOOST_THREAD_DECL void on_process_exit()
+{
+}
- //Get the exit handlers list for the current thread from tls.
+extern "C" BOOST_THREAD_DECL void on_thread_enter()
+{
+}
- if (tls_key == invalid_tls_key)
- return;
+extern "C" BOOST_THREAD_DECL void on_thread_exit()
+{
+ // Initializing tls_key here ensures its proper visibility
+ boost::call_once( init_tls_key, once_init_tls_key );
- thread_exit_handlers* exit_handlers =
- static_cast<thread_exit_handlers*>(TlsGetValue(tls_key));
+ // Get the exit handlers list for the current thread from tls.
- //If a handlers list was found, use it.
+ if( tls_key == invalid_tls_key )
+ {
+ return;
+ }
- if (exit_handlers && TlsSetValue(tls_key, 0))
- {
- BOOST_ASSERT(attached_thread_count > 0);
- --attached_thread_count;
+ thread_exit_handlers* exit_handlers =
+ static_cast< thread_exit_handlers* >( TlsGetValue( tls_key ) );
- lock.unlock();
+ // If a handlers list was found, invoke its handlers.
- //Call each handler and remove it from the list
+ if( exit_handlers != 0 )
+ {
+ // Call each handler and remove it from the list
- while (!exit_handlers->empty())
+ while( !exit_handlers->empty() )
+ {
+ if( thread_exit_handler exit_handler = *exit_handlers->begin() )
{
- if (thread_exit_handler exit_handler = *exit_handlers->begin())
- (*exit_handler)();
- exit_handlers->pop_front();
+ (*exit_handler)();
}
+ exit_handlers->pop_front();
+ }
+
+ // If TlsSetValue fails, we can't delete the list,
+ // since a second call to on_thread_exit will try
+ // to access it.
+
+ if( TlsSetValue( tls_key, 0 ) )
+ {
delete exit_handlers;
- exit_handlers = 0;
}
}
+}
#endif //defined(BOOST_HAS_WINTHREADS)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs