1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. 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)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
#include <boost/interprocess/detail/intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
#include <boost/interprocess/exceptions.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
class windows_mutex
{
windows_mutex(const windows_mutex &);
windows_mutex &operator=(const windows_mutex &);
public:
windows_mutex();
~windows_mutex();
void lock();
bool try_lock();
bool timed_lock(const boost::posix_time::ptime &abs_time);
void unlock();
void take_ownership(){};
private:
const sync_id id_;
};
inline windows_mutex::windows_mutex()
: id_()
{
sync_handles &handles =
intermodule_singleton<sync_handles>::get();
//Create mutex with the initial count
bool open_or_created;
handles.obtain_mutex(this->id_, &open_or_created);
//The mutex must be created, never opened
assert(open_or_created);
assert(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
(void)open_or_created;
}
inline windows_mutex::~windows_mutex()
{
sync_handles &handles =
intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_mutex::lock(void)
{
sync_handles &handles =
intermodule_singleton<sync_handles>::get();
//This can throw
void *hnd = handles.obtain_mutex(this->id_);
unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
if(ret == winapi::wait_failed){
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
}
inline bool windows_mutex::try_lock(void)
{
sync_handles &handles =
intermodule_singleton<sync_handles>::get();
//This can throw
void *hnd = handles.obtain_mutex(this->id_);
unsigned long ret = winapi::wait_for_single_object(hnd, 0);
if(ret == winapi::wait_failed){
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
return ret != winapi::wait_timeout;
}
inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
boost::posix_time::ptime now
= boost::posix_time::microsec_clock::universal_time();
unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
intermodule_singleton<sync_handles>::get();
//This can throw
void *hnd = handles.obtain_mutex(this->id_);
unsigned long ret = winapi::wait_for_single_object(hnd, ms);
if(ret == winapi::wait_failed){
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
return ret != winapi::wait_timeout;
}
inline void windows_mutex::unlock(void)
{
sync_handles &handles =
intermodule_singleton<sync_handles>::get();
//This can throw
void *hnd = handles.obtain_mutex(this->id_);
int ret = winapi::release_mutex(hnd);
(void)ret;
assert(ret);
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
#endif //BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
|