• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //////////////////////////////////////////////////////////////////////////////
2  //
3  // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4  // Software License, Version 1.0. (See accompanying file
5  // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  //
7  // See http://www.boost.org/libs/interprocess for documentation.
8  //
9  //////////////////////////////////////////////////////////////////////////////
10  //
11  // Parts of the pthread code come from Boost Threads code.
12  //
13  //////////////////////////////////////////////////////////////////////////////
14  
15  #ifndef BOOST_INTERPROCESS_MUTEX_HPP
16  #define BOOST_INTERPROCESS_MUTEX_HPP
17  
18  #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
19  
20  #ifndef BOOST_CONFIG_HPP
21  #  include <boost/config.hpp>
22  #endif
23  #
24  #if defined(BOOST_HAS_PRAGMA_ONCE)
25  #  pragma once
26  #endif
27  
28  #include <boost/interprocess/detail/config_begin.hpp>
29  #include <boost/interprocess/exceptions.hpp>
30  #include <boost/interprocess/detail/workaround.hpp>
31  #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
32  #include <boost/assert.hpp>
33  #include <boost/interprocess/sync/detail/common_algorithms.hpp>
34  
35  
36  #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
37     #include <boost/interprocess/sync/posix/mutex.hpp>
38     #define BOOST_INTERPROCESS_USE_POSIX
39  //Experimental...
40  #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
41     #include <boost/interprocess/sync/windows/mutex.hpp>
42     #define BOOST_INTERPROCESS_USE_WINDOWS
43  #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
44     #include <boost/interprocess/sync/spin/mutex.hpp>
45     #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
46  
47  namespace boost {
48  namespace interprocess {
49  namespace ipcdetail{
50  namespace robust_emulation_helpers {
51  
52  template<class T>
53  class mutex_traits;
54  
55  }}}}
56  
57  #endif
58  
59  #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
60  
61  //!\file
62  //!Describes a mutex class that can be placed in memory shared by
63  //!several processes.
64  
65  namespace boost {
66  namespace interprocess {
67  
68  class interprocess_condition;
69  
70  //!Wraps a interprocess_mutex that can be placed in shared memory and can be
71  //!shared between processes. Allows timed lock tries
72  class interprocess_mutex
73  {
74     #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
75     //Non-copyable
76     interprocess_mutex(const interprocess_mutex &);
77     interprocess_mutex &operator=(const interprocess_mutex &);
78     friend class interprocess_condition;
79  
80     public:
81     #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
82        #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
83        typedef ipcdetail::spin_mutex internal_mutex_type;
84        private:
85        friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
take_ownership()86        void take_ownership(){ m_mutex.take_ownership(); }
87        public:
88     #elif defined(BOOST_INTERPROCESS_USE_POSIX)
89        #undef BOOST_INTERPROCESS_USE_POSIX
90        typedef ipcdetail::posix_mutex internal_mutex_type;
91     #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
92        #undef BOOST_INTERPROCESS_USE_WINDOWS
93        typedef ipcdetail::windows_mutex internal_mutex_type;
94     #else
95        #error "Unknown platform for interprocess_mutex"
96     #endif
97  
98     #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
99     public:
100  
101     //!Constructor.
102     //!Throws interprocess_exception on error.
103     interprocess_mutex();
104  
105     //!Destructor. If any process uses the mutex after the destructor is called
106     //!the result is undefined. Does not throw.
107     ~interprocess_mutex();
108  
109     //!Effects: The calling thread tries to obtain ownership of the mutex, and
110     //!   if another thread has ownership of the mutex, it waits until it can
111     //!   obtain the ownership. If a thread takes ownership of the mutex the
112     //!   mutex must be unlocked by the same mutex.
113     //!Throws: interprocess_exception on error.
114     void lock();
115  
116     //!Effects: The calling thread tries to obtain ownership of the mutex, and
117     //!   if another thread has ownership of the mutex returns immediately.
118     //!Returns: If the thread acquires ownership of the mutex, returns true, if
119     //!   the another thread has ownership of the mutex, returns false.
120     //!Throws: interprocess_exception on error.
121     bool try_lock();
122  
123     //!Effects: The calling thread will try to obtain exclusive ownership of the
124     //!   mutex if it can do so in until the specified time is reached. If the
125     //!   mutex supports recursive locking, the mutex must be unlocked the same
126     //!   number of times it is locked.
127     //!Returns: If the thread acquires ownership of the mutex, returns true, if
128     //!   the timeout expires returns false.
129     //!Throws: interprocess_exception on error.
130     bool timed_lock(const boost::posix_time::ptime &abs_time);
131  
132     //!Effects: The calling thread releases the exclusive ownership of the mutex.
133     //!Throws: interprocess_exception on error.
134     void unlock();
135  
136     #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
internal_mutex()137     internal_mutex_type &internal_mutex()
138     {  return m_mutex;   }
139  
internal_mutex() const140     const internal_mutex_type &internal_mutex() const
141     {  return m_mutex;   }
142  
143     private:
144     internal_mutex_type m_mutex;
145     #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
146  };
147  
148  }  //namespace interprocess {
149  }  //namespace boost {
150  
151  
152  namespace boost {
153  namespace interprocess {
154  
interprocess_mutex()155  inline interprocess_mutex::interprocess_mutex(){}
156  
~interprocess_mutex()157  inline interprocess_mutex::~interprocess_mutex(){}
158  
lock()159  inline void interprocess_mutex::lock()
160  {  ipcdetail::timeout_when_locking_aware_lock(m_mutex);  }
161  
try_lock()162  inline bool interprocess_mutex::try_lock()
163  { return m_mutex.try_lock(); }
164  
timed_lock(const boost::posix_time::ptime & abs_time)165  inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
166  { return m_mutex.timed_lock(abs_time); }
167  
unlock()168  inline void interprocess_mutex::unlock()
169  { m_mutex.unlock(); }
170  
171  }  //namespace interprocess {
172  }  //namespace boost {
173  
174  #include <boost/interprocess/detail/config_end.hpp>
175  
176  #endif   //BOOST_INTERPROCESS_MUTEX_HPP
177