|
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