Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75806 - trunk/boost/thread/win32
From: vicente.botet_at_[hidden]
Date: 2011-12-04 18:06:24


Author: viboes
Date: 2011-12-04 18:06:24 EST (Sun, 04 Dec 2011)
New Revision: 75806
URL: http://svn.boost.org/trac/boost/changeset/75806

Log:
Thread: #5859 win32 shared_mutex constructor leaks on exceptions
Text files modified:
   trunk/boost/thread/win32/shared_mutex.hpp | 55 ++++++++++++++++++++++++----------------
   trunk/boost/thread/win32/thread_primitives.hpp | 43 ++++++++++++++++++------------
   2 files changed, 59 insertions(+), 39 deletions(-)

Modified: trunk/boost/thread/win32/shared_mutex.hpp
==============================================================================
--- trunk/boost/thread/win32/shared_mutex.hpp (original)
+++ trunk/boost/thread/win32/shared_mutex.hpp 2011-12-04 18:06:24 EST (Sun, 04 Dec 2011)
@@ -23,7 +23,7 @@
     {
     private:
         shared_mutex(shared_mutex const&);
- shared_mutex& operator=(shared_mutex const&);
+ shared_mutex& operator=(shared_mutex const&);
     private:
         struct state_data
         {
@@ -39,7 +39,7 @@
                 return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
             }
         };
-
+
 
         template<typename T>
         T interlocked_compare_exchange(T* target,T new_value,T comparand)
@@ -67,20 +67,31 @@
             {
                 BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
             }
-
+
             if(old_state.shared_waiting || old_state.exclusive_waiting)
             {
                 BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
             }
         }
-
+
 
     public:
         shared_mutex()
         {
             semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
+ if (!semaphores[exclusive_sem])
+ {
+ detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
+ boost::throw_exception(thread_resource_error());
+ }
+ upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
+ if (!upgrade_sem)
+ {
+ detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
+ detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
+ boost::throw_exception(thread_resource_error());
+ }
             state_data state_={0};
             state=state_;
         }
@@ -106,7 +117,7 @@
                         return false;
                     }
                 }
-
+
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
                 if(current_state==old_state)
                 {
@@ -165,7 +176,7 @@
                 {
                     return true;
                 }
-
+
                 unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until));
                 if(res==detail::win32::timeout)
                 {
@@ -202,7 +213,7 @@
                     }
                     return false;
                 }
-
+
                 BOOST_ASSERT(res==0);
             }
         }
@@ -214,7 +225,7 @@
             {
                 state_data new_state=old_state;
                 bool const last_reader=!--new_state.shared_count;
-
+
                 if(last_reader)
                 {
                     if(new_state.upgrade)
@@ -232,7 +243,7 @@
                         new_state.shared_waiting=0;
                     }
                 }
-
+
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
                 if(current_state==old_state)
                 {
@@ -278,7 +289,7 @@
                 {
                     new_state.exclusive=true;
                 }
-
+
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
                 if(current_state==old_state)
                 {
@@ -306,7 +317,7 @@
                         {
                             boost::throw_exception(boost::lock_error());
                         }
-
+
                         new_state.exclusive_waiting_blocked=true;
                     }
                     else
@@ -426,7 +437,7 @@
                 {
                     return;
                 }
-
+
                 BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite));
             }
         }
@@ -450,7 +461,7 @@
                     }
                     new_state.upgrade=true;
                 }
-
+
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
                 if(current_state==old_state)
                 {
@@ -469,7 +480,7 @@
                 state_data new_state=old_state;
                 new_state.upgrade=false;
                 bool const last_reader=!--new_state.shared_count;
-
+
                 if(last_reader)
                 {
                     if(new_state.exclusive_waiting)
@@ -479,7 +490,7 @@
                     }
                     new_state.shared_waiting=0;
                 }
-
+
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
                 if(current_state==old_state)
                 {
@@ -500,13 +511,13 @@
             {
                 state_data new_state=old_state;
                 bool const last_reader=!--new_state.shared_count;
-
+
                 if(last_reader)
                 {
                     new_state.upgrade=false;
                     new_state.exclusive=true;
                 }
-
+
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
                 if(current_state==old_state)
                 {
@@ -545,7 +556,7 @@
             }
             release_waiters(old_state);
         }
-
+
         void unlock_and_lock_shared()
         {
             state_data old_state=state;
@@ -570,7 +581,7 @@
             }
             release_waiters(old_state);
         }
-
+
         void unlock_upgrade_and_lock_shared()
         {
             state_data old_state=state;
@@ -594,7 +605,7 @@
             }
             release_waiters(old_state);
         }
-
+
     };
 }
 

Modified: trunk/boost/thread/win32/thread_primitives.hpp
==============================================================================
--- trunk/boost/thread/win32/thread_primitives.hpp (original)
+++ trunk/boost/thread/win32/thread_primitives.hpp 2011-12-04 18:06:24 EST (Sun, 04 Dec 2011)
@@ -3,8 +3,8 @@
 
 // win32_thread_primitives.hpp
 //
-// (C) Copyright 2005-7 Anthony Williams
-// (C) Copyright 2007 David Deakins
+// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2007 David Deakins
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -94,7 +94,7 @@
     {
         namespace win32
         {
-
+
 # ifdef _WIN64
             typedef unsigned __int64 ulong_ptr;
 # else
@@ -170,20 +170,20 @@
                 auto_reset_event=false,
                 manual_reset_event=true
             };
-
+
             enum initial_event_state
             {
                 event_initially_reset=false,
                 event_initially_set=true
             };
-
+
             inline handle create_anonymous_event(event_type type,initial_event_state state)
             {
-#if !defined(BOOST_NO_ANSI_APIS)
+#if !defined(BOOST_NO_ANSI_APIS)
                 handle const res=win32::CreateEventA(0,type,state,0);
 #else
                 handle const res=win32::CreateEventW(0,type,state,0);
-#endif
+#endif
                 if(!res)
                 {
                     boost::throw_exception(thread_resource_error());
@@ -193,17 +193,26 @@
 
             inline handle create_anonymous_semaphore(long initial_count,long max_count)
             {
-#if !defined(BOOST_NO_ANSI_APIS)
+#if !defined(BOOST_NO_ANSI_APIS)
                 handle const res=CreateSemaphoreA(0,initial_count,max_count,0);
 #else
                 handle const res=CreateSemaphoreW(0,initial_count,max_count,0);
-#endif
+#endif
                 if(!res)
                 {
                     boost::throw_exception(thread_resource_error());
                 }
                 return res;
             }
+ inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
+ {
+#if !defined(BOOST_NO_ANSI_APIS)
+ handle const res=CreateSemaphoreA(0,initial_count,max_count,0);
+#else
+ handle const res=CreateSemaphoreW(0,initial_count,max_count,0);
+#endif
+ return res;
+ }
 
             inline handle duplicate_handle(handle source)
             {
@@ -237,7 +246,7 @@
                         BOOST_VERIFY(CloseHandle(handle_to_manage));
                     }
                 }
-
+
             public:
                 explicit handle_manager(handle handle_to_manage_):
                     handle_to_manage(handle_to_manage_)
@@ -245,7 +254,7 @@
                 handle_manager():
                     handle_to_manage(0)
                 {}
-
+
                 handle_manager& operator=(handle new_handle)
                 {
                     cleanup();
@@ -279,13 +288,13 @@
                 {
                     return !handle_to_manage;
                 }
-
+
                 ~handle_manager()
                 {
                     cleanup();
                 }
             };
-
+
         }
     }
 }
@@ -318,7 +327,7 @@
             {
                 return _interlockedbittestandreset(x,bit)!=0;
             }
-
+
         }
     }
 }
@@ -337,7 +346,7 @@
                     mov edx,x;
                     lock bts [edx],eax;
                     setc al;
- };
+ };
             }
 
             inline bool interlocked_bit_test_and_reset(long* x,long bit)
@@ -347,9 +356,9 @@
                     mov edx,x;
                     lock btr [edx],eax;
                     setc al;
- };
+ };
             }
-
+
         }
     }
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk