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

Reply via email to