1 #ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
2 #define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
4 // basic_timed_mutex_win32.hpp
6 // (C) Copyright 2006-8 Anthony Williams
8 // Distributed under the Boost Software License, Version 1.0. (See
9 // accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
12 #include <boost/assert.hpp>
13 #include "thread_primitives.hpp"
14 #include "interlocked_read.hpp"
15 #include <boost/thread/thread_time.hpp>
16 #include <boost/thread/xtime.hpp>
17 #include <boost/detail/interlocked.hpp>
19 #include <boost/config/abi_prefix.hpp>
25 struct basic_timed_mutex
27 BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit
=31);
28 BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit
=30);
29 BOOST_STATIC_CONSTANT(long,lock_flag_value
=1<<lock_flag_bit
);
30 BOOST_STATIC_CONSTANT(long,event_set_flag_value
=1<<event_set_flag_bit
);
44 #pragma warning(disable:4312)
46 void* const old_event
=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event
,0);
52 win32::CloseHandle(old_event
);
59 return !win32::interlocked_bit_test_and_set(&active_count
,lock_flag_bit
);
64 BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
66 bool timed_lock(::boost::system_time
const& wait_until
)
68 if(!win32::interlocked_bit_test_and_set(&active_count
,lock_flag_bit
))
72 long old_count
=active_count
;
75 long const new_count
=(old_count
&lock_flag_value
)?(old_count
+1):(old_count
|lock_flag_value
);
76 long const current
=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count
,new_count
,old_count
);
77 if(current
==old_count
)
84 if(old_count
&lock_flag_value
)
86 bool lock_acquired
=false;
87 void* const sem
=get_event();
91 if(win32::WaitForSingleObject(sem
,::boost::detail::get_milliseconds_until(wait_until
))!=0)
93 BOOST_INTERLOCKED_DECREMENT(&active_count
);
96 old_count
&=~lock_flag_value
;
97 old_count
|=event_set_flag_value
;
100 long const new_count
=((old_count
&lock_flag_value
)?old_count
:((old_count
-1)|lock_flag_value
))&~event_set_flag_value
;
101 long const current
=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count
,new_count
,old_count
);
102 if(current
==old_count
)
108 lock_acquired
=!(old_count
&lock_flag_value
);
110 while(!lock_acquired
);
115 template<typename Duration
>
116 bool timed_lock(Duration
const& timeout
)
118 return timed_lock(get_system_time()+timeout
);
121 bool timed_lock(boost::xtime
const& timeout
)
123 return timed_lock(system_time(timeout
));
128 long const offset
=lock_flag_value
;
129 long const old_count
=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count
,lock_flag_value
);
130 if(!(old_count
&event_set_flag_value
) && (old_count
>offset
))
132 if(!win32::interlocked_bit_test_and_set(&active_count
,event_set_flag_bit
))
134 win32::SetEvent(get_event());
142 void* current_event
=::boost::detail::interlocked_read_acquire(&event
);
146 void* const new_event
=win32::create_anonymous_event(win32::auto_reset_event
,win32::event_initially_reset
);
148 #pragma warning(push)
149 #pragma warning(disable:4311)
150 #pragma warning(disable:4312)
152 void* const old_event
=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event
,new_event
,0);
158 win32::CloseHandle(new_event
);
166 return current_event
;
174 #define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
176 #include <boost/config/abi_suffix.hpp>