$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r49324 - in branches/release: boost/thread boost/thread/detail boost/thread/pthread boost/thread/win32 libs/thread/doc libs/thread/src/win32 libs/thread/test
From: anthony_at_[hidden]
Date: 2008-10-13 16:30:14
Author: anthonyw
Date: 2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
New Revision: 49324
URL: http://svn.boost.org/trac/boost/changeset/49324
Log:
Merged Boost.Thread changes from trunk
Text files modified: 
   branches/release/boost/thread/detail/move.hpp                 |     4                                         
   branches/release/boost/thread/detail/thread.hpp               |     4                                         
   branches/release/boost/thread/locks.hpp                       |     6                                         
   branches/release/boost/thread/pthread/recursive_mutex.hpp     |     2                                         
   branches/release/boost/thread/pthread/shared_mutex.hpp        |    46 ++--                                    
   branches/release/boost/thread/win32/basic_recursive_mutex.hpp |    10 -                                       
   branches/release/boost/thread/win32/basic_timed_mutex.hpp     |    10 -                                       
   branches/release/libs/thread/doc/changes.qbk                  |     3                                         
   branches/release/libs/thread/src/win32/thread.cpp             |    22 +                                       
   branches/release/libs/thread/src/win32/tss_pe.cpp             |    46 +++-                                    
   branches/release/libs/thread/test/test_mutex.cpp              |    84 +++++++++                               
   branches/release/libs/thread/test/test_thread_move.cpp        |    47 ++++                                    
   branches/release/libs/thread/test/util.inl                    |   366 ++++++++++++++++++++--------------------
   13 files changed, 395 insertions(+), 255 deletions(-)
Modified: branches/release/boost/thread/detail/move.hpp
==============================================================================
--- branches/release/boost/thread/detail/move.hpp	(original)
+++ branches/release/boost/thread/detail/move.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -41,9 +41,9 @@
 
 #ifndef BOOST_NO_SFINAE
     template<typename T>
-    typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t)
+    typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, T >::type move(T& t)
     {
-        return t;
+        return T(detail::thread_move_t<T>(t));
     }
 #endif
     
Modified: branches/release/boost/thread/detail/thread.hpp
==============================================================================
--- branches/release/boost/thread/detail/thread.hpp	(original)
+++ branches/release/boost/thread/detail/thread.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -339,9 +339,9 @@
         return t;
     }
 #else
-    inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
+    inline thread move(detail::thread_move_t<thread> t)
     {
-        return t;
+        return thread(t);
     }
 #endif
 
Modified: branches/release/boost/thread/locks.hpp
==============================================================================
--- branches/release/boost/thread/locks.hpp	(original)
+++ branches/release/boost/thread/locks.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -234,6 +234,12 @@
         {
             try_lock();
         }
+        template<typename TimeDuration>
+        unique_lock(Mutex& m_,TimeDuration const& target_time):
+            m(&m_),is_locked(false)
+        {
+            timed_lock(target_time);
+        }
         unique_lock(Mutex& m_,system_time const& target_time):
             m(&m_),is_locked(false)
         {
Modified: branches/release/boost/thread/pthread/recursive_mutex.hpp
==============================================================================
--- branches/release/boost/thread/pthread/recursive_mutex.hpp	(original)
+++ branches/release/boost/thread/pthread/recursive_mutex.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -177,7 +177,7 @@
         {
             struct timespec const timeout=detail::get_timespec(abs_time);
             int const res=pthread_mutex_timedlock(&m,&timeout);
-            BOOST_ASSERT(!res || res==EBUSY);
+            BOOST_ASSERT(!res || res==ETIMEDOUT);
             return !res;
         }
 
Modified: branches/release/boost/thread/pthread/shared_mutex.hpp
==============================================================================
--- branches/release/boost/thread/pthread/shared_mutex.hpp	(original)
+++ branches/release/boost/thread/pthread/shared_mutex.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -57,18 +57,18 @@
         void lock_shared()
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
                 
             while(state.exclusive || state.exclusive_waiting_blocked)
             {
-                shared_cond.wait(lock);
+                shared_cond.wait(lk);
             }
             ++state.shared_count;
         }
 
         bool try_lock_shared()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
                 
             if(state.exclusive || state.exclusive_waiting_blocked)
             {
@@ -84,11 +84,11 @@
         bool timed_lock_shared(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
                 
             while(state.exclusive || state.exclusive_waiting_blocked)
             {
-                if(!shared_cond.timed_wait(lock,timeout))
+                if(!shared_cond.timed_wait(lk,timeout))
                 {
                     return false;
                 }
@@ -105,7 +105,7 @@
 
         void unlock_shared()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             bool const last_reader=!--state.shared_count;
                 
             if(last_reader)
@@ -127,12 +127,12 @@
         void lock()
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
                 
             while(state.shared_count || state.exclusive)
             {
                 state.exclusive_waiting_blocked=true;
-                exclusive_cond.wait(lock);
+                exclusive_cond.wait(lk);
             }
             state.exclusive=true;
         }
@@ -140,12 +140,12 @@
         bool timed_lock(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
 
             while(state.shared_count || state.exclusive)
             {
                 state.exclusive_waiting_blocked=true;
-                if(!exclusive_cond.timed_wait(lock,timeout))
+                if(!exclusive_cond.timed_wait(lk,timeout))
                 {
                     if(state.shared_count || state.exclusive)
                     {
@@ -168,7 +168,7 @@
 
         bool try_lock()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
                 
             if(state.shared_count || state.exclusive)
             {
@@ -184,7 +184,7 @@
 
         void unlock()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             state.exclusive=false;
             state.exclusive_waiting_blocked=false;
             release_waiters();
@@ -193,10 +193,10 @@
         void lock_upgrade()
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
-                shared_cond.wait(lock);
+                shared_cond.wait(lk);
             }
             ++state.shared_count;
             state.upgrade=true;
@@ -205,10 +205,10 @@
         bool timed_lock_upgrade(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
-                if(!shared_cond.timed_wait(lock,timeout))
+                if(!shared_cond.timed_wait(lk,timeout))
                 {
                     if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
                     {
@@ -230,7 +230,7 @@
 
         bool try_lock_upgrade()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
                 return false;
@@ -245,7 +245,7 @@
 
         void unlock_upgrade()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             state.upgrade=false;
             bool const last_reader=!--state.shared_count;
                 
@@ -259,11 +259,11 @@
         void unlock_upgrade_and_lock()
         {
             boost::this_thread::disable_interruption do_not_disturb;
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             --state.shared_count;
             while(state.shared_count)
             {
-                upgrade_cond.wait(lock);
+                upgrade_cond.wait(lk);
             }
             state.upgrade=false;
             state.exclusive=true;
@@ -271,7 +271,7 @@
 
         void unlock_and_lock_upgrade()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             state.exclusive=false;
             state.upgrade=true;
             ++state.shared_count;
@@ -281,7 +281,7 @@
         
         void unlock_and_lock_shared()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             state.exclusive=false;
             ++state.shared_count;
             state.exclusive_waiting_blocked=false;
@@ -290,7 +290,7 @@
         
         void unlock_upgrade_and_lock_shared()
         {
-            boost::mutex::scoped_lock lock(state_change);
+            boost::mutex::scoped_lock lk(state_change);
             state.upgrade=false;
             state.exclusive_waiting_blocked=false;
             release_waiters();
Modified: branches/release/boost/thread/win32/basic_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/basic_recursive_mutex.hpp	(original)
+++ branches/release/boost/thread/win32/basic_recursive_mutex.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -64,11 +64,6 @@
                 return timed_lock(get_system_time()+timeout);
             }
 
-            long get_active_count()
-            {
-                return mutex.get_active_count();
-            }
-
             void unlock()
             {
                 if(!--recursion_count)
@@ -78,11 +73,6 @@
                 }
             }
 
-            bool locked()
-            {
-                return mutex.locked();
-            }
-            
         private:
             bool try_recursive_lock(long current_thread_id)
             {
Modified: branches/release/boost/thread/win32/basic_timed_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/basic_timed_mutex.hpp	(original)
+++ branches/release/boost/thread/win32/basic_timed_mutex.hpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -123,11 +123,6 @@
                 return timed_lock(system_time(timeout));
             }
 
-            long get_active_count()
-            {
-                return ::boost::detail::interlocked_read_acquire(&active_count);
-            }
-
             void unlock()
             {
                 long const offset=lock_flag_value;
@@ -141,11 +136,6 @@
                 }
             }
 
-            bool locked()
-            {
-                return get_active_count()>=lock_flag_value;
-            }
-            
         private:
             void* get_event()
             {
Modified: branches/release/libs/thread/doc/changes.qbk
==============================================================================
--- branches/release/libs/thread/doc/changes.qbk	(original)
+++ branches/release/libs/thread/doc/changes.qbk	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -77,4 +77,7 @@
 
 * __mutex__ is now never recursive. For Boost releases prior to 1.35 __mutex__ was recursive on Windows and not on POSIX platforms.
 
+* When using a __recursive_mutex__ with a call to [cond_any_wait_link `boost::condition_variable_any::wait()`], the mutex is only
+  unlocked one level, and not completely. This prior behaviour was not guaranteed and did not feature in the tests.
+
 [endsect]
Modified: branches/release/libs/thread/src/win32/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/thread.cpp	(original)
+++ branches/release/libs/thread/src/win32/thread.cpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -29,13 +29,26 @@
 
         void create_current_thread_tls_key()
         {
+            tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
             current_thread_tls_key=TlsAlloc();
             BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
         }
 
+        void cleanup_tls_key()
+        {
+            if(current_thread_tls_key)
+            {
+                TlsFree(current_thread_tls_key);
+                current_thread_tls_key=0;
+            }
+        }
+
         detail::thread_data_base* get_current_thread_data()
         {
-            boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
+            if(!current_thread_tls_key)
+            {
+                return 0;
+            }
             return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key);
         }
 
@@ -141,8 +154,8 @@
                     }
                 }
                 
+                set_current_thread_data(0);
             }
-            set_current_thread_data(0);
         }
         
         unsigned __stdcall thread_start_function(void* param)
@@ -544,7 +557,6 @@
         
         void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
         {
-            tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
             if(tss_data_node* const current_node=find_tss_data(key))
             {
                 if(cleanup_existing && current_node->func.get())
@@ -572,7 +584,9 @@
 {}
 
 extern "C" BOOST_THREAD_DECL void on_process_exit()
-{}
+{
+    boost::cleanup_tls_key();
+}
 
 extern "C" BOOST_THREAD_DECL void on_thread_exit()
 {
Modified: branches/release/libs/thread/src/win32/tss_pe.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/tss_pe.cpp	(original)
+++ branches/release/libs/thread/src/win32/tss_pe.cpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -26,11 +26,11 @@
     {
         switch (dwReason)
         {
-            case DLL_THREAD_DETACH:
-            {
-                on_thread_exit();
-                break;
-            }
+        case DLL_THREAD_DETACH:
+        {
+            on_thread_exit();
+            break;
+        }
         }
     }
 
@@ -125,10 +125,10 @@
 #pragma section(".CRT$XCU",long,read)
 #pragma section(".CRT$XTU",long,read)
 #pragma section(".CRT$XLC",long,read)
-        static __declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
-        static __declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
-        static __declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
-        static __declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
+        __declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
+        __declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
+        __declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
+        __declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
 #else
         #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
         #   pragma data_seg(push, old_seg)
@@ -168,6 +168,7 @@
 #pragma warning(push)
 #pragma warning(disable:4189)
 #endif
+
         PVAPI on_tls_prepare(void)
         {
             //The following line has an important side effect:
@@ -239,15 +240,32 @@
         {
             switch (dwReason)
             {
-                case DLL_THREAD_DETACH:
-                {
-                    on_thread_exit();
-                    break;
-                }
+            case DLL_THREAD_DETACH:
+                on_thread_exit();
+                break;
             }
         }
+
+        BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
+        {
+            switch (dwReason)
+            {
+            case DLL_THREAD_DETACH:
+                on_thread_exit();
+                break;
+            case DLL_PROCESS_DETACH:
+                on_process_exit();
+                break;
+            }
+            return true;
+        }
     } //namespace
 
+extern "C"
+{
+    extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
+}
+
     extern "C" void tss_cleanup_implemented(void)
     {
         /*
Modified: branches/release/libs/thread/test/test_mutex.cpp
==============================================================================
--- branches/release/libs/thread/test/test_mutex.cpp	(original)
+++ branches/release/libs/thread/test/test_mutex.cpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -7,6 +7,7 @@
 #include <boost/thread/detail/config.hpp>
 
 #include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #include <boost/thread/thread_time.hpp>
 #include <boost/thread/condition.hpp>
@@ -96,6 +97,86 @@
     }
 };
 
+template<typename Mutex>
+struct test_lock_times_out_if_other_thread_has_lock
+{
+    typedef boost::unique_lock<Mutex> Lock;
+    
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_lock_times_out_if_other_thread_has_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m,boost::defer_lock);
+        lock.timed_lock(boost::posix_time::milliseconds(50));
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    void locking_thread_through_constructor()
+    {
+        Lock lock(m,boost::posix_time::milliseconds(50));
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    bool is_done() const
+    {
+        return done;
+    }
+
+    typedef test_lock_times_out_if_other_thread_has_lock<Mutex> this_type;
+    
+    void do_test(void (this_type::*test_func)())
+    {
+        Lock lock(m);
+
+        locked=false;
+        done=false;
+        
+        boost::thread t(test_func,this);
+
+        try
+        {
+            {
+                boost::mutex::scoped_lock lk(done_mutex);
+                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+                                                 boost::bind(&this_type::is_done,this)));
+                BOOST_CHECK(!locked);
+            }
+            
+            lock.unlock();
+            t.join();
+        }
+        catch(...)
+        {
+            lock.unlock();
+            t.join();
+            throw;
+        }
+    }
+    
+
+    void operator()()
+    {
+        do_test(&this_type::locking_thread);
+        do_test(&this_type::locking_thread_through_constructor);
+    }
+};
+
 template <typename M>
 struct test_timedlock
 {
@@ -109,6 +190,8 @@
 
     void operator()()
     {
+        test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
+        
         mutex_type mutex;
         boost::condition condition;
 
@@ -178,6 +261,7 @@
     }
 };
 
+
 void do_test_mutex()
 {
     test_lock<boost::mutex>()();
Modified: branches/release/libs/thread/test/test_thread_move.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread_move.cpp	(original)
+++ branches/release/libs/thread/test/test_thread_move.cpp	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -5,26 +5,59 @@
 #include <boost/thread/thread.hpp>
 #include <boost/test/unit_test.hpp>
 
-void do_nothing()
-{}
+void do_nothing(boost::thread::id* my_id)
+{
+    *my_id=boost::this_thread::get_id();
+}
 
 void test_move_on_construction()
 {
-    boost::thread x=boost::thread(do_nothing);
+    boost::thread::id the_id;
+    boost::thread x=boost::thread(do_nothing,&the_id);
+    boost::thread::id x_id=x.get_id();
     x.join();
+    BOOST_CHECK_EQUAL(the_id,x_id);
 }
 
-boost::thread make_thread()
+boost::thread make_thread(boost::thread::id* the_id)
 {
-    return boost::thread(do_nothing);
+    return boost::thread(do_nothing,the_id);
 }
 
 void test_move_from_function_return()
 {
-    boost::thread x=make_thread();
+    boost::thread::id the_id;
+    boost::thread x=make_thread(&the_id);
+    boost::thread::id x_id=x.get_id();
     x.join();
+    BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+boost::thread make_thread_return_lvalue(boost::thread::id* the_id)
+{
+    boost::thread t(do_nothing,the_id);
+    return boost::move(t);
 }
 
+void test_move_from_function_return_lvalue()
+{
+    boost::thread::id the_id;
+    boost::thread x=make_thread_return_lvalue(&the_id);
+    boost::thread::id x_id=x.get_id();
+    x.join();
+    BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+void test_move_assign()
+{
+    boost::thread::id the_id;
+    boost::thread x(do_nothing,&the_id);
+    boost::thread y;
+    y=boost::move(x);
+    boost::thread::id y_id=y.get_id();
+    y.join();
+    BOOST_CHECK_EQUAL(the_id,y_id);
+}
 
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
@@ -33,5 +66,7 @@
 
     test->add(BOOST_TEST_CASE(test_move_on_construction));
     test->add(BOOST_TEST_CASE(test_move_from_function_return));
+    test->add(BOOST_TEST_CASE(test_move_from_function_return_lvalue));
+    test->add(BOOST_TEST_CASE(test_move_assign));
     return test;
 }
Modified: branches/release/libs/thread/test/util.inl
==============================================================================
--- branches/release/libs/thread/test/util.inl	(original)
+++ branches/release/libs/thread/test/util.inl	2008-10-13 16:30:13 EDT (Mon, 13 Oct 2008)
@@ -1,183 +1,183 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-// Copyright (C) 2007-8 Anthony Williams
-//
-//  Distributed under 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)
-
-#if !defined(UTIL_INL_WEK01242003)
-#define UTIL_INL_WEK01242003
-
-#include <boost/thread/xtime.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition.hpp>
-#include <boost/thread/thread.hpp>
-
-#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
-#   define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
-#endif
-
-// boostinspect:nounnamed
-
-namespace
-{
-inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
-{
-    const int MILLISECONDS_PER_SECOND = 1000;
-    const int NANOSECONDS_PER_SECOND = 1000000000;
-    const int NANOSECONDS_PER_MILLISECOND = 1000000;
-
-    boost::xtime xt;
-    if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))
-        BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");
-
-    nsecs += xt.nsec;
-    msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
-    secs += msecs / MILLISECONDS_PER_SECOND;
-    nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
-    xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
-    xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
-
-    return xt;
-}
-
-inline bool in_range(const boost::xtime& xt, int secs=1)
-{
-    boost::xtime min = delay(-secs);
-    boost::xtime max = delay(0);
-    return (boost::xtime_cmp(xt, min) >= 0) &&
-        (boost::xtime_cmp(xt, max) <= 0);
-}
-
-class execution_monitor
-{
-public:
-    enum wait_type { use_sleep_only, use_mutex, use_condition };
-
-    execution_monitor(wait_type type, int secs)
-        : done(false), type(type), secs(secs) { }
-    void start()
-    {
-        if (type != use_sleep_only) {
-            boost::mutex::scoped_lock lock(mutex); done = false;
-        } else {
-            done = false;
-        }
-    }
-    void finish()
-    {
-        if (type != use_sleep_only) {
-            boost::mutex::scoped_lock lock(mutex);
-            done = true;
-            if (type == use_condition)
-                cond.notify_one();
-        } else {
-            done = true;
-        }
-    }
-    bool wait()
-    {
-        boost::xtime xt = delay(secs);
-        if (type != use_condition)
-            boost::thread::sleep(xt);
-        if (type != use_sleep_only) {
-            boost::mutex::scoped_lock lock(mutex);
-            while (type == use_condition && !done) {
-                if (!cond.timed_wait(lock, xt))
-                    break;
-            }
-            return done;
-        }
-        return done;
-    }
-
-private:
-    boost::mutex mutex;
-    boost::condition cond;
-    bool done;
-    wait_type type;
-    int secs;
-};
-
-template <typename F>
-class indirect_adapter
-{
-public:
-    indirect_adapter(F func, execution_monitor& monitor)
-        : func(func), monitor(monitor) { }
-    void operator()() const
-    {
-        try
-        {
-            boost::thread thrd(func);
-            thrd.join();
-        }
-        catch (...)
-        {
-            monitor.finish();
-            throw;
-        }
-        monitor.finish();
-    }
-
-private:
-    F func;
-    execution_monitor& monitor;
-    void operator=(indirect_adapter&);
-};
-
-template <typename F>
-void timed_test(F func, int secs,
-    execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
-{
-    execution_monitor monitor(type, secs);
-    indirect_adapter<F> ifunc(func, monitor);
-    monitor.start();
-    boost::thread thrd(ifunc);
-    BOOST_REQUIRE_MESSAGE(monitor.wait(),
-        "Timed test didn't complete in time, possible deadlock.");
-}
-
-template <typename F, typename T>
-class thread_binder
-{
-public:
-    thread_binder(const F& func, const T& param)
-        : func(func), param(param) { }
-    void operator()() const { func(param); }
-
-private:
-    F func;
-    T param;
-};
-
-template <typename F, typename T>
-thread_binder<F, T> bind(const F& func, const T& param)
-{
-    return thread_binder<F, T>(func, param);
-}
-
-template <typename R, typename T>
-class thread_member_binder
-{
-public:
-    thread_member_binder(R (T::*func)(), T& param)
-        : func(func), param(param) { }
-    void operator()() const { (param.*func)(); }
-
-private:
-    void operator=(thread_member_binder&);
-    
-    R (T::*func)();
-    T& param;
-};
-
-
-template <typename R, typename T>
-thread_member_binder<R, T> bind(R (T::*func)(), T& param)
-{
-    return thread_member_binder<R, T>(func, param);
-}
-} // namespace
-
-#endif
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  Distributed under 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)
+
+#if !defined(UTIL_INL_WEK01242003)
+#define UTIL_INL_WEK01242003
+
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+
+#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
+#   define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
+#endif
+
+// boostinspect:nounnamed
+
+namespace
+{
+inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
+{
+    const int MILLISECONDS_PER_SECOND = 1000;
+    const int NANOSECONDS_PER_SECOND = 1000000000;
+    const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+    boost::xtime xt;
+    if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))
+        BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");
+
+    nsecs += xt.nsec;
+    msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
+    secs += msecs / MILLISECONDS_PER_SECOND;
+    nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
+    xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
+    xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
+
+    return xt;
+}
+
+inline bool in_range(const boost::xtime& xt, int secs=1)
+{
+    boost::xtime min = delay(-secs);
+    boost::xtime max = delay(0);
+    return (boost::xtime_cmp(xt, min) >= 0) &&
+        (boost::xtime_cmp(xt, max) <= 0);
+}
+
+class execution_monitor
+{
+public:
+    enum wait_type { use_sleep_only, use_mutex, use_condition };
+
+    execution_monitor(wait_type type, int secs)
+        : done(false), type(type), secs(secs) { }
+    void start()
+    {
+        if (type != use_sleep_only) {
+            boost::mutex::scoped_lock lock(mutex); done = false;
+        } else {
+            done = false;
+        }
+    }
+    void finish()
+    {
+        if (type != use_sleep_only) {
+            boost::mutex::scoped_lock lock(mutex);
+            done = true;
+            if (type == use_condition)
+                cond.notify_one();
+        } else {
+            done = true;
+        }
+    }
+    bool wait()
+    {
+        boost::xtime xt = delay(secs);
+        if (type != use_condition)
+            boost::thread::sleep(xt);
+        if (type != use_sleep_only) {
+            boost::mutex::scoped_lock lock(mutex);
+            while (type == use_condition && !done) {
+                if (!cond.timed_wait(lock, xt))
+                    break;
+            }
+            return done;
+        }
+        return done;
+    }
+
+private:
+    boost::mutex mutex;
+    boost::condition cond;
+    bool done;
+    wait_type type;
+    int secs;
+};
+
+template <typename F>
+class indirect_adapter
+{
+public:
+    indirect_adapter(F func, execution_monitor& monitor)
+        : func(func), monitor(monitor) { }
+    void operator()() const
+    {
+        try
+        {
+            boost::thread thrd(func);
+            thrd.join();
+        }
+        catch (...)
+        {
+            monitor.finish();
+            throw;
+        }
+        monitor.finish();
+    }
+
+private:
+    F func;
+    execution_monitor& monitor;
+    void operator=(indirect_adapter&);
+};
+
+template <typename F>
+void timed_test(F func, int secs,
+    execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
+{
+    execution_monitor monitor(type, secs);
+    indirect_adapter<F> ifunc(func, monitor);
+    monitor.start();
+    boost::thread thrd(ifunc);
+    BOOST_REQUIRE_MESSAGE(monitor.wait(),
+        "Timed test didn't complete in time, possible deadlock.");
+}
+
+template <typename F, typename T>
+class thread_binder
+{
+public:
+    thread_binder(const F& func, const T& param)
+        : func(func), param(param) { }
+    void operator()() const { func(param); }
+
+private:
+    F func;
+    T param;
+};
+
+template <typename F, typename T>
+thread_binder<F, T> bind(const F& func, const T& param)
+{
+    return thread_binder<F, T>(func, param);
+}
+
+template <typename R, typename T>
+class thread_member_binder
+{
+public:
+    thread_member_binder(R (T::*func)(), T& param)
+        : func(func), param(param) { }
+    void operator()() const { (param.*func)(); }
+
+private:
+    void operator=(thread_member_binder&);
+    
+    R (T::*func)();
+    T& param;
+};
+
+
+template <typename R, typename T>
+thread_member_binder<R, T> bind(R (T::*func)(), T& param)
+{
+    return thread_member_binder<R, T>(func, param);
+}
+} // namespace
+
+#endif