Browse code

Add IPB on windows

1 1
new file mode 100755
... ...
@@ -0,0 +1,129 @@
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
+#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
25
+
26
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
27
+#include <boost/interprocess/sync/scoped_lock.hpp>
28
+#include <boost/interprocess/exceptions.hpp>
29
+#include <boost/interprocess/sync/windows/semaphore.hpp>
30
+#include <boost/interprocess/sync/windows/mutex.hpp>
31
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
32
+
33
+
34
+namespace boost {
35
+namespace interprocess {
36
+namespace ipcdetail {
37
+
38
+class winapi_condition
39
+{
40
+   winapi_condition(const winapi_condition &);
41
+   winapi_condition &operator=(const winapi_condition &);
42
+
43
+   public:
44
+   winapi_condition()
45
+      : m_condition_data()
46
+   {}
47
+
48
+   ~winapi_condition()
49
+   {
50
+      //Notify all waiting threads
51
+      //to allow POSIX semantics on condition destruction
52
+      this->notify_all();
53
+   }
54
+
55
+   void notify_one()
56
+   {  m_condition_data.notify_one();   }
57
+
58
+   void notify_all()
59
+   {  m_condition_data.notify_all();   }
60
+
61
+   template <typename L>
62
+   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
63
+   {  return m_condition_data.timed_wait(lock, abs_time);   }
64
+
65
+   template <typename L, typename Pr>
66
+   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
67
+   {  return m_condition_data.timed_wait(lock, abs_time, pred);   }
68
+
69
+   template <typename L>
70
+   void wait(L& lock)
71
+   {  m_condition_data.wait(lock);   }
72
+
73
+   template <typename L, typename Pr>
74
+   void wait(L& lock, Pr pred)
75
+   {  m_condition_data.wait(lock, pred);   }
76
+
77
+   private:
78
+
79
+   struct condition_data
80
+   {
81
+      typedef boost::int32_t     integer_type;
82
+      typedef winapi_semaphore  semaphore_type;
83
+      typedef winapi_mutex      mutex_type;
84
+
85
+      condition_data()
86
+         : m_nwaiters_blocked(0)
87
+         , m_nwaiters_gone(0)
88
+         , m_nwaiters_to_unblock(0)
89
+         , m_sem_block_queue(0)
90
+         , m_sem_block_lock(1)
91
+         , m_mtx_unblock_lock()
92
+      {}
93
+
94
+      integer_type    &get_nwaiters_blocked()
95
+      {  return m_nwaiters_blocked;  }
96
+
97
+      integer_type    &get_nwaiters_gone()
98
+      {  return m_nwaiters_gone;  }
99
+
100
+      integer_type    &get_nwaiters_to_unblock()
101
+      {  return m_nwaiters_to_unblock;  }
102
+
103
+      semaphore_type  &get_sem_block_queue()
104
+      {  return m_sem_block_queue;  }
105
+
106
+      semaphore_type  &get_sem_block_lock()
107
+      {  return m_sem_block_lock;  }
108
+
109
+      mutex_type      &get_mtx_unblock_lock()
110
+      {  return m_mtx_unblock_lock;  }
111
+
112
+      integer_type            m_nwaiters_blocked;
113
+      integer_type            m_nwaiters_gone;
114
+      integer_type            m_nwaiters_to_unblock;
115
+      semaphore_type          m_sem_block_queue;
116
+      semaphore_type          m_sem_block_lock;
117
+      mutex_type              m_mtx_unblock_lock;
118
+   };
119
+
120
+   ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
121
+};
122
+
123
+}  //namespace ipcdetail
124
+}  //namespace interprocess
125
+}  //namespace boost
126
+
127
+#include <boost/interprocess/detail/config_end.hpp>
128
+
129
+#endif   //BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
0 130
new file mode 100755
... ...
@@ -0,0 +1,118 @@
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
+#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
25
+#include <boost/interprocess/detail/win32_api.hpp>
26
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
27
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
28
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
29
+#include <boost/interprocess/exceptions.hpp>
30
+
31
+
32
+namespace boost {
33
+namespace interprocess {
34
+namespace ipcdetail {
35
+
36
+class winapi_mutex
37
+{
38
+   winapi_mutex(const winapi_mutex &);
39
+   winapi_mutex &operator=(const winapi_mutex &);
40
+   public:
41
+
42
+   winapi_mutex();
43
+   ~winapi_mutex();
44
+
45
+   void lock();
46
+   bool try_lock();
47
+   bool timed_lock(const boost::posix_time::ptime &abs_time);
48
+   void unlock();
49
+   void take_ownership(){};
50
+
51
+   private:
52
+   const sync_id id_;
53
+};
54
+
55
+inline winapi_mutex::winapi_mutex()
56
+   : id_(this)
57
+{
58
+   sync_handles &handles =
59
+      windows_intermodule_singleton<sync_handles>::get();
60
+   //Create mutex with the initial count
61
+   bool open_or_created;
62
+   (void)handles.obtain_mutex(this->id_, &open_or_created);
63
+   //The mutex must be created, never opened
64
+   BOOST_ASSERT(open_or_created);
65
+   BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
66
+   (void)open_or_created;
67
+}
68
+
69
+inline winapi_mutex::~winapi_mutex()
70
+{
71
+   sync_handles &handles =
72
+      windows_intermodule_singleton<sync_handles>::get();
73
+   handles.destroy_handle(this->id_);
74
+}
75
+
76
+inline void winapi_mutex::lock(void)
77
+{
78
+   sync_handles &handles =
79
+      windows_intermodule_singleton<sync_handles>::get();
80
+   //This can throw
81
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
82
+   mut.lock();
83
+}
84
+
85
+inline bool winapi_mutex::try_lock(void)
86
+{
87
+   sync_handles &handles =
88
+      windows_intermodule_singleton<sync_handles>::get();
89
+   //This can throw
90
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
91
+   return mut.try_lock();
92
+}
93
+
94
+inline bool winapi_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
95
+{
96
+   sync_handles &handles =
97
+      windows_intermodule_singleton<sync_handles>::get();
98
+   //This can throw
99
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
100
+   return mut.timed_lock(abs_time);
101
+}
102
+
103
+inline void winapi_mutex::unlock(void)
104
+{
105
+   sync_handles &handles =
106
+      windows_intermodule_singleton<sync_handles>::get();
107
+   //This can throw
108
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
109
+   return mut.unlock();
110
+}
111
+
112
+}  //namespace ipcdetail {
113
+}  //namespace interprocess {
114
+}  //namespace boost {
115
+
116
+#include <boost/interprocess/detail/config_end.hpp>
117
+
118
+#endif   //BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
0 119
new file mode 100755
... ...
@@ -0,0 +1,38 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
12
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/sync/windows/named_condition_any.hpp>
25
+
26
+namespace boost {
27
+namespace interprocess {
28
+namespace ipcdetail {
29
+
30
+typedef winapi_named_condition_any winapi_named_condition;
31
+
32
+}  //namespace ipcdetail {
33
+}  //namespace interprocess {
34
+}  //namespace boost {
35
+
36
+#include <boost/interprocess/detail/config_end.hpp>
37
+
38
+#endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
0 39
new file mode 100755
... ...
@@ -0,0 +1,319 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
12
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/creation_tags.hpp>
25
+#include <boost/interprocess/permissions.hpp>
26
+#include <boost/interprocess/detail/interprocess_tester.hpp>
27
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
28
+#include <boost/interprocess/sync/windows/named_sync.hpp>
29
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
30
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
31
+
32
+namespace boost {
33
+namespace interprocess {
34
+namespace ipcdetail {
35
+
36
+template<class CharT>
37
+struct named_cond_callbacks_str;
38
+
39
+template<>
40
+struct named_cond_callbacks_str<char>
41
+{
42
+   static const char* ipc_cond()
43
+   {  return "Global\\bipc.cond.";  }
44
+
45
+   static const char* bq()
46
+   {  return "_bq";  }
47
+
48
+   static const char* bl()
49
+   {  return "_bl";  }
50
+
51
+   static const char* ul()
52
+   {  return "_ul";  }
53
+};
54
+
55
+template<>
56
+struct named_cond_callbacks_str<wchar_t>
57
+{
58
+   static const wchar_t* ipc_cond()
59
+   {  return L"Global\\bipc.cond.";  }
60
+
61
+   static const wchar_t* bq()
62
+   {  return L"_bq";  }
63
+
64
+   static const wchar_t* bl()
65
+   {  return L"_bl";  }
66
+
67
+   static const wchar_t* ul()
68
+   {  return L"_ul";  }
69
+};
70
+
71
+class winapi_named_condition_any
72
+{
73
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
74
+
75
+   //Non-copyable
76
+   winapi_named_condition_any();
77
+   winapi_named_condition_any(const winapi_named_condition_any &);
78
+   winapi_named_condition_any &operator=(const winapi_named_condition_any &);
79
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
80
+
81
+   public:
82
+   winapi_named_condition_any
83
+      (create_only_t, const char *name, const permissions &perm = permissions())
84
+      : m_condition_data()
85
+   {
86
+      named_cond_callbacks callbacks(m_condition_data.get_members());
87
+      m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
88
+   }
89
+
90
+   winapi_named_condition_any
91
+      (open_or_create_t, const char *name, const permissions &perm = permissions())
92
+      : m_condition_data()
93
+   {
94
+      named_cond_callbacks callbacks(m_condition_data.get_members());
95
+      m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
96
+   }
97
+
98
+   winapi_named_condition_any(open_only_t, const char *name)
99
+      : m_condition_data()
100
+   {
101
+      named_cond_callbacks callbacks(m_condition_data.get_members());
102
+      m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
103
+   }
104
+
105
+   #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
106
+
107
+   winapi_named_condition_any
108
+      (create_only_t, const wchar_t *name, const permissions &perm = permissions())
109
+      : m_condition_data()
110
+   {
111
+      named_cond_callbacks callbacks(m_condition_data.get_members());
112
+      m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
113
+   }
114
+
115
+   winapi_named_condition_any
116
+      (open_or_create_t, const wchar_t *name, const permissions &perm = permissions())
117
+      : m_condition_data()
118
+   {
119
+      named_cond_callbacks callbacks(m_condition_data.get_members());
120
+      m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
121
+   }
122
+
123
+   winapi_named_condition_any(open_only_t, const wchar_t *name)
124
+      : m_condition_data()
125
+   {
126
+      named_cond_callbacks callbacks(m_condition_data.get_members());
127
+      m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
128
+   }
129
+
130
+   #endif   //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
131
+
132
+   ~winapi_named_condition_any()
133
+   {
134
+      named_cond_callbacks callbacks(m_condition_data.get_members());
135
+      m_named_sync.close(callbacks);
136
+   }
137
+
138
+   void notify_one()
139
+   {  m_condition_data.notify_one();   }
140
+
141
+   void notify_all()
142
+   {  m_condition_data.notify_all();   }
143
+
144
+   template <typename L>
145
+   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
146
+   {  return m_condition_data.timed_wait(lock, abs_time);   }
147
+
148
+   template <typename L, typename Pr>
149
+   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
150
+   {  return m_condition_data.timed_wait(lock, abs_time, pred);   }
151
+
152
+   template <typename L>
153
+   void wait(L& lock)
154
+   {  m_condition_data.wait(lock);   }
155
+
156
+   template <typename L, typename Pr>
157
+   void wait(L& lock, Pr pred)
158
+   {  m_condition_data.wait(lock, pred);   }
159
+
160
+   static bool remove(const char *name)
161
+   {  return windows_named_sync::remove(name);  }
162
+
163
+   static bool remove(const wchar_t *name)
164
+   {  return windows_named_sync::remove(name);  }
165
+
166
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
167
+   private:
168
+
169
+   void dont_close_on_destruction()
170
+   {}
171
+
172
+   friend class interprocess_tester;
173
+
174
+   struct condition_data
175
+   {
176
+      typedef boost::int32_t           integer_type;
177
+      typedef winapi_semaphore_wrapper semaphore_type;
178
+      typedef winapi_mutex_wrapper     mutex_type;
179
+
180
+      integer_type    &get_nwaiters_blocked()
181
+      {  return m_nwaiters_blocked;  }
182
+
183
+      integer_type    &get_nwaiters_gone()
184
+      {  return m_nwaiters_gone;  }
185
+
186
+      integer_type    &get_nwaiters_to_unblock()
187
+      {  return m_nwaiters_to_unblock;  }
188
+
189
+      semaphore_type  &get_sem_block_queue()
190
+      {  return m_sem_block_queue;  }
191
+
192
+      semaphore_type  &get_sem_block_lock()
193
+      {  return m_sem_block_lock;  }
194
+
195
+      mutex_type      &get_mtx_unblock_lock()
196
+      {  return m_mtx_unblock_lock;  }
197
+
198
+      integer_type               m_nwaiters_blocked;
199
+      integer_type               m_nwaiters_gone;
200
+      integer_type               m_nwaiters_to_unblock;
201
+      winapi_semaphore_wrapper   m_sem_block_queue;
202
+      winapi_semaphore_wrapper   m_sem_block_lock;
203
+      winapi_mutex_wrapper       m_mtx_unblock_lock;
204
+   };
205
+
206
+
207
+   class named_cond_callbacks : public windows_named_sync_interface
208
+   {
209
+      typedef __int64 sem_count_t;
210
+      mutable sem_count_t sem_counts [2];
211
+
212
+      public:
213
+      named_cond_callbacks(condition_data &cond_data)
214
+         : m_condition_data(cond_data)
215
+      {}
216
+
217
+      virtual std::size_t get_data_size() const
218
+      {  return sizeof(sem_counts);   }
219
+
220
+      virtual const void *buffer_with_final_data_to_file()
221
+      {
222
+         sem_counts[0] = m_condition_data.m_sem_block_queue.value();
223
+         sem_counts[1] = m_condition_data.m_sem_block_lock.value();
224
+         return &sem_counts;
225
+      }
226
+
227
+      virtual const void *buffer_with_init_data_to_file()
228
+      {
229
+         sem_counts[0] = 0;
230
+         sem_counts[1] = 1;
231
+         return &sem_counts;
232
+      }
233
+
234
+      virtual void *buffer_to_store_init_data_from_file()
235
+      {  return &sem_counts; }
236
+
237
+      virtual bool open(create_enum_t op, const char *id_name)
238
+      {  return this->open_impl(op, id_name);   }
239
+
240
+      virtual bool open(create_enum_t op, const wchar_t *id_name)
241
+      {  return this->open_impl(op, id_name);   }
242
+
243
+      virtual void close()
244
+      {
245
+         m_condition_data.m_sem_block_queue.close();
246
+         m_condition_data.m_sem_block_lock.close();
247
+         m_condition_data.m_mtx_unblock_lock.close();
248
+         m_condition_data.m_nwaiters_blocked = 0;
249
+         m_condition_data.m_nwaiters_gone = 0;
250
+         m_condition_data.m_nwaiters_to_unblock = 0;
251
+      }
252
+
253
+      virtual ~named_cond_callbacks()
254
+      {}
255
+
256
+      private:
257
+
258
+      template<class CharT>
259
+      bool open_impl(create_enum_t, const CharT *id_name)
260
+      {
261
+         typedef named_cond_callbacks_str<CharT> str_t;
262
+         m_condition_data.m_nwaiters_blocked = 0;
263
+         m_condition_data.m_nwaiters_gone = 0;
264
+         m_condition_data.m_nwaiters_to_unblock = 0;
265
+
266
+         //Now open semaphores and mutex.
267
+         //Use local variables + swap to guarantee consistent
268
+         //initialization and cleanup in case any opening fails
269
+         permissions perm;
270
+         perm.set_unrestricted();
271
+         std::basic_string<CharT> aux_str  = str_t::ipc_cond();
272
+         aux_str += id_name;
273
+         std::size_t pos = aux_str.size();
274
+
275
+         //sem_block_queue
276
+         aux_str += str_t::bq();
277
+         winapi_semaphore_wrapper sem_block_queue;
278
+         bool created;
279
+         if(!sem_block_queue.open_or_create
280
+            (aux_str.c_str(), sem_counts[0], winapi_semaphore_wrapper::MaxCount, perm, created))
281
+            return false;
282
+         aux_str.erase(pos);
283
+
284
+         //sem_block_lock
285
+         aux_str += str_t::bl();
286
+         winapi_semaphore_wrapper sem_block_lock;
287
+         if(!sem_block_lock.open_or_create
288
+            (aux_str.c_str(), sem_counts[1], winapi_semaphore_wrapper::MaxCount, perm, created))
289
+            return false;
290
+         aux_str.erase(pos);
291
+
292
+         //mtx_unblock_lock
293
+         aux_str += str_t::ul();
294
+         winapi_mutex_wrapper mtx_unblock_lock;
295
+         if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
296
+            return false;
297
+
298
+         //All ok, commit data
299
+         m_condition_data.m_sem_block_queue.swap(sem_block_queue);
300
+         m_condition_data.m_sem_block_lock.swap(sem_block_lock);
301
+         m_condition_data.m_mtx_unblock_lock.swap(mtx_unblock_lock);
302
+         return true;
303
+      }
304
+
305
+      condition_data &m_condition_data;
306
+   };
307
+
308
+   windows_named_sync   m_named_sync;
309
+   ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
310
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
311
+};
312
+
313
+}  //namespace ipcdetail {
314
+}  //namespace interprocess {
315
+}  //namespace boost {
316
+
317
+#include <boost/interprocess/detail/config_end.hpp>
318
+
319
+#endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
0 320
new file mode 100755
... ...
@@ -0,0 +1,225 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
11
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
12
+
13
+#ifndef BOOST_CONFIG_HPP
14
+#  include <boost/config.hpp>
15
+#endif
16
+#
17
+#if defined(BOOST_HAS_PRAGMA_ONCE)
18
+#  pragma once
19
+#endif
20
+
21
+#include <boost/interprocess/detail/config_begin.hpp>
22
+#include <boost/interprocess/detail/workaround.hpp>
23
+#include <boost/interprocess/creation_tags.hpp>
24
+#include <boost/interprocess/permissions.hpp>
25
+#include <boost/interprocess/detail/interprocess_tester.hpp>
26
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
27
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
28
+#include <boost/interprocess/sync/windows/named_sync.hpp>
29
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
30
+#include <boost/interprocess/errors.hpp>
31
+#include <boost/interprocess/exceptions.hpp>
32
+#include <limits>
33
+
34
+namespace boost {
35
+namespace interprocess {
36
+namespace ipcdetail {
37
+
38
+
39
+
40
+class winapi_named_mutex
41
+{
42
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
43
+
44
+   //Non-copyable
45
+   winapi_named_mutex();
46
+   winapi_named_mutex(const winapi_named_mutex &);
47
+   winapi_named_mutex &operator=(const winapi_named_mutex &);
48
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
49
+
50
+   public:
51
+   winapi_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
52
+
53
+   winapi_named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions());
54
+
55
+   winapi_named_mutex(open_only_t, const char *name);
56
+
57
+   winapi_named_mutex(create_only_t, const wchar_t *name, const permissions &perm = permissions());
58
+
59
+   winapi_named_mutex(open_or_create_t, const wchar_t *name, const permissions &perm = permissions());
60
+
61
+   winapi_named_mutex(open_only_t, const wchar_t *name);
62
+
63
+   ~winapi_named_mutex();
64
+
65
+   void unlock();
66
+   void lock();
67
+   bool try_lock();
68
+   bool timed_lock(const boost::posix_time::ptime &abs_time);
69
+
70
+   static bool remove(const char *name);
71
+
72
+   static bool remove(const wchar_t *name);
73
+
74
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
75
+   private:
76
+   friend class interprocess_tester;
77
+   void dont_close_on_destruction();
78
+   winapi_mutex_wrapper m_mtx_wrapper;
79
+   windows_named_sync m_named_sync;
80
+
81
+   class named_mut_callbacks : public windows_named_sync_interface
82
+   {
83
+      public:
84
+      named_mut_callbacks(winapi_mutex_wrapper &mtx_wrapper)
85
+         : m_mtx_wrapper(mtx_wrapper)
86
+      {}
87
+
88
+      virtual std::size_t get_data_size() const
89
+      {  return 0u;   }
90
+
91
+      virtual const void *buffer_with_init_data_to_file()
92
+      {  return 0; }
93
+
94
+      virtual const void *buffer_with_final_data_to_file()
95
+      {  return 0; }
96
+
97
+      virtual void *buffer_to_store_init_data_from_file()
98
+      {  return 0; }
99
+
100
+      virtual bool open(create_enum_t, const char *id_name)
101
+      {
102
+         std::string aux_str  = "Global\\bipc.mut.";
103
+         aux_str += id_name;
104
+         //
105
+         permissions mut_perm;
106
+         mut_perm.set_unrestricted();
107
+         return m_mtx_wrapper.open_or_create(aux_str.c_str(), mut_perm);
108
+      }
109
+
110
+      virtual bool open(create_enum_t, const wchar_t *id_name)
111
+      {
112
+         std::wstring aux_str  = L"Global\\bipc.mut.";
113
+         aux_str += id_name;
114
+         //
115
+         permissions mut_perm;
116
+         mut_perm.set_unrestricted();
117
+         return m_mtx_wrapper.open_or_create(aux_str.c_str(), mut_perm);
118
+      }
119
+
120
+      virtual void close()
121
+      {
122
+         m_mtx_wrapper.close();
123
+      }
124
+
125
+      virtual ~named_mut_callbacks()
126
+      {}
127
+
128
+      private:
129
+      winapi_mutex_wrapper&     m_mtx_wrapper;
130
+   };
131
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
132
+};
133
+
134
+inline winapi_named_mutex::~winapi_named_mutex()
135
+{
136
+   named_mut_callbacks callbacks(m_mtx_wrapper);
137
+   m_named_sync.close(callbacks);
138
+}
139
+
140
+inline void winapi_named_mutex::dont_close_on_destruction()
141
+{}
142
+
143
+inline winapi_named_mutex::winapi_named_mutex
144
+   (create_only_t, const char *name, const permissions &perm)
145
+   : m_mtx_wrapper()
146
+{
147
+   named_mut_callbacks callbacks(m_mtx_wrapper);
148
+   m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
149
+}
150
+
151
+inline winapi_named_mutex::winapi_named_mutex
152
+   (open_or_create_t, const char *name, const permissions &perm)
153
+   : m_mtx_wrapper()
154
+{
155
+   named_mut_callbacks callbacks(m_mtx_wrapper);
156
+   m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
157
+}
158
+
159
+inline winapi_named_mutex::winapi_named_mutex(open_only_t, const char *name)
160
+   : m_mtx_wrapper()
161
+{
162
+   named_mut_callbacks callbacks(m_mtx_wrapper);
163
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
164
+}
165
+
166
+inline winapi_named_mutex::winapi_named_mutex
167
+   (create_only_t, const wchar_t *name, const permissions &perm)
168
+   : m_mtx_wrapper()
169
+{
170
+   named_mut_callbacks callbacks(m_mtx_wrapper);
171
+   m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
172
+}
173
+
174
+inline winapi_named_mutex::winapi_named_mutex
175
+   (open_or_create_t, const wchar_t *name, const permissions &perm)
176
+   : m_mtx_wrapper()
177
+{
178
+   named_mut_callbacks callbacks(m_mtx_wrapper);
179
+   m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
180
+}
181
+
182
+inline winapi_named_mutex::winapi_named_mutex(open_only_t, const wchar_t *name)
183
+   : m_mtx_wrapper()
184
+{
185
+   named_mut_callbacks callbacks(m_mtx_wrapper);
186
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
187
+}
188
+
189
+inline void winapi_named_mutex::unlock()
190
+{
191
+   m_mtx_wrapper.unlock();
192
+}
193
+
194
+inline void winapi_named_mutex::lock()
195
+{
196
+   m_mtx_wrapper.lock();
197
+}
198
+
199
+inline bool winapi_named_mutex::try_lock()
200
+{
201
+   return m_mtx_wrapper.try_lock();
202
+}
203
+
204
+inline bool winapi_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
205
+{
206
+   return m_mtx_wrapper.timed_lock(abs_time);
207
+}
208
+
209
+inline bool winapi_named_mutex::remove(const char *name)
210
+{
211
+   return windows_named_sync::remove(name);
212
+}
213
+
214
+inline bool winapi_named_mutex::remove(const wchar_t *name)
215
+{
216
+   return windows_named_sync::remove(name);
217
+}
218
+
219
+}  //namespace ipcdetail {
220
+}  //namespace interprocess {
221
+}  //namespace boost {
222
+
223
+#include <boost/interprocess/detail/config_end.hpp>
224
+
225
+#endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
0 226
\ No newline at end of file
1 227
new file mode 100755
... ...
@@ -0,0 +1,74 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
11
+#define BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
12
+
13
+#ifndef BOOST_CONFIG_HPP
14
+#  include <boost/config.hpp>
15
+#endif
16
+#
17
+#if defined(BOOST_HAS_PRAGMA_ONCE)
18
+#  pragma once
19
+#endif
20
+
21
+#include <boost/interprocess/detail/config_begin.hpp>
22
+#include <boost/interprocess/detail/workaround.hpp>
23
+#include <boost/interprocess/sync/windows/named_mutex.hpp>
24
+
25
+namespace boost {
26
+namespace interprocess {
27
+namespace ipcdetail {
28
+
29
+
30
+class winapi_named_recursive_mutex
31
+   //Windows mutexes based on CreateMutex are already recursive...
32
+   : public winapi_named_mutex
33
+{
34
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
35
+
36
+   //Non-copyable
37
+   winapi_named_recursive_mutex();
38
+   winapi_named_recursive_mutex(const winapi_named_mutex &);
39
+   winapi_named_recursive_mutex &operator=(const winapi_named_mutex &);
40
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
41
+
42
+   public:
43
+   winapi_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
44
+      : winapi_named_mutex(create_only_t(), name, perm)
45
+   {}
46
+
47
+   winapi_named_recursive_mutex(open_or_create_t, const char *name, const permissions &perm = permissions())
48
+      : winapi_named_mutex(open_or_create_t(), name, perm)
49
+   {}
50
+
51
+   winapi_named_recursive_mutex(open_only_t, const char *name)
52
+      : winapi_named_mutex(open_only_t(), name)
53
+   {}
54
+
55
+   winapi_named_recursive_mutex(create_only_t, const wchar_t *name, const permissions &perm = permissions())
56
+      : winapi_named_mutex(create_only_t(), name, perm)
57
+   {}
58
+
59
+   winapi_named_recursive_mutex(open_or_create_t, const wchar_t *name, const permissions &perm = permissions())
60
+      : winapi_named_mutex(open_or_create_t(), name, perm)
61
+   {}
62
+
63
+   winapi_named_recursive_mutex(open_only_t, const wchar_t *name)
64
+      : winapi_named_mutex(open_only_t(), name)
65
+   {}
66
+};
67
+
68
+}  //namespace ipcdetail {
69
+}  //namespace interprocess {
70
+}  //namespace boost {
71
+
72
+#include <boost/interprocess/detail/config_end.hpp>
73
+
74
+#endif   //BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
0 75
new file mode 100755
... ...
@@ -0,0 +1,230 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
12
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/creation_tags.hpp>
25
+#include <boost/interprocess/permissions.hpp>
26
+#include <boost/interprocess/detail/interprocess_tester.hpp>
27
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
28
+#include <boost/interprocess/sync/windows/named_sync.hpp>
29
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
30
+
31
+namespace boost {
32
+namespace interprocess {
33
+namespace ipcdetail {
34
+
35
+
36
+
37
+class winapi_named_semaphore
38
+{
39
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
40
+
41
+   //Non-copyable
42
+   winapi_named_semaphore();
43
+   winapi_named_semaphore(const winapi_named_semaphore &);
44
+   winapi_named_semaphore &operator=(const winapi_named_semaphore &);
45
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
46
+
47
+   public:
48
+   winapi_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
49
+
50
+   winapi_named_semaphore(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
51
+
52
+   winapi_named_semaphore(open_only_t, const char *name);
53
+
54
+   winapi_named_semaphore(create_only_t, const wchar_t *name, unsigned int initialCount, const permissions &perm = permissions());
55
+
56
+   winapi_named_semaphore(open_or_create_t, const wchar_t *name, unsigned int initialCount, const permissions &perm = permissions());
57
+
58
+   winapi_named_semaphore(open_only_t, const wchar_t *name);
59
+
60
+   ~winapi_named_semaphore();
61
+
62
+   void post();
63
+   void wait();
64
+   bool try_wait();
65
+   bool timed_wait(const boost::posix_time::ptime &abs_time);
66
+
67
+   static bool remove(const char *name);
68
+   static bool remove(const wchar_t *name);
69
+
70
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
71
+   private:
72
+   friend class interprocess_tester;
73
+   void dont_close_on_destruction();
74
+   winapi_semaphore_wrapper m_sem_wrapper;
75
+   windows_named_sync m_named_sync;
76
+
77
+   class named_sem_callbacks : public windows_named_sync_interface
78
+   {
79
+      public:
80
+      typedef __int64 sem_count_t;
81
+      named_sem_callbacks(winapi_semaphore_wrapper &sem_wrapper, sem_count_t sem_cnt)
82
+         : m_sem_wrapper(sem_wrapper), m_sem_count(sem_cnt)
83
+      {}
84
+
85
+      virtual std::size_t get_data_size() const
86
+      {  return sizeof(sem_count_t);   }
87
+
88
+      virtual const void *buffer_with_final_data_to_file()
89
+      {  return &m_sem_count; }
90
+
91
+      virtual const void *buffer_with_init_data_to_file()
92
+      {  return &m_sem_count; }
93
+
94
+      virtual void *buffer_to_store_init_data_from_file()
95
+      {  return &m_sem_count; }
96
+
97
+      virtual bool open(create_enum_t, const char *id_name)
98
+      {
99
+         std::string aux_str  = "Global\\bipc.sem.";
100
+         aux_str += id_name;
101
+         //
102
+         permissions sem_perm;
103
+         sem_perm.set_unrestricted();
104
+         bool created;
105
+         return m_sem_wrapper.open_or_create
106
+            ( aux_str.c_str(), static_cast<long>(m_sem_count)
107
+            , winapi_semaphore_wrapper::MaxCount, sem_perm, created);
108
+      }
109
+
110
+      virtual bool open(create_enum_t, const wchar_t *id_name)
111
+      {
112
+         std::wstring aux_str  = L"Global\\bipc.sem.";
113
+         aux_str += id_name;
114
+         //
115
+         permissions sem_perm;
116
+         sem_perm.set_unrestricted();
117
+         bool created;
118
+         return m_sem_wrapper.open_or_create
119
+            ( aux_str.c_str(), static_cast<long>(m_sem_count)
120
+            , winapi_semaphore_wrapper::MaxCount, sem_perm, created);
121
+      }
122
+
123
+      virtual void close()
124
+      {
125
+         m_sem_wrapper.close();
126
+      }
127
+
128
+      virtual ~named_sem_callbacks()
129
+      {}
130
+
131
+      private:
132
+      winapi_semaphore_wrapper&     m_sem_wrapper;
133
+      sem_count_t m_sem_count;
134
+   };
135
+
136
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
137
+};
138
+
139
+inline winapi_named_semaphore::~winapi_named_semaphore()
140
+{
141
+   named_sem_callbacks callbacks(m_sem_wrapper, m_sem_wrapper.value());
142
+   m_named_sync.close(callbacks);
143
+}
144
+
145
+inline void winapi_named_semaphore::dont_close_on_destruction()
146
+{}
147
+
148
+inline winapi_named_semaphore::winapi_named_semaphore
149
+   (create_only_t, const char *name, unsigned int initial_count, const permissions &perm)
150
+   : m_sem_wrapper()
151
+{
152
+   named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
153
+   m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
154
+}
155
+
156
+inline winapi_named_semaphore::winapi_named_semaphore
157
+   (open_or_create_t, const char *name, unsigned int initial_count, const permissions &perm)
158
+   : m_sem_wrapper()
159
+{
160
+   named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
161
+   m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
162
+}
163
+
164
+inline winapi_named_semaphore::winapi_named_semaphore(open_only_t, const char *name)
165
+   : m_sem_wrapper()
166
+{
167
+   named_sem_callbacks callbacks(m_sem_wrapper, 0);
168
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
169
+}
170
+
171
+inline winapi_named_semaphore::winapi_named_semaphore
172
+   (create_only_t, const wchar_t *name, unsigned int initial_count, const permissions &perm)
173
+   : m_sem_wrapper()
174
+{
175
+   named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
176
+   m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
177
+}
178
+
179
+inline winapi_named_semaphore::winapi_named_semaphore
180
+   (open_or_create_t, const wchar_t *name, unsigned int initial_count, const permissions &perm)
181
+   : m_sem_wrapper()
182
+{
183
+   named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
184
+   m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
185
+}
186
+
187
+inline winapi_named_semaphore::winapi_named_semaphore(open_only_t, const wchar_t *name)
188
+   : m_sem_wrapper()
189
+{
190
+   named_sem_callbacks callbacks(m_sem_wrapper, 0);
191
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
192
+}
193
+
194
+inline void winapi_named_semaphore::post()
195
+{
196
+   m_sem_wrapper.post();
197
+}
198
+
199
+inline void winapi_named_semaphore::wait()
200
+{
201
+   m_sem_wrapper.wait();
202
+}
203
+
204
+inline bool winapi_named_semaphore::try_wait()
205
+{
206
+   return m_sem_wrapper.try_wait();
207
+}
208
+
209
+inline bool winapi_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
210
+{
211
+   return m_sem_wrapper.timed_wait(abs_time);
212
+}
213
+
214
+inline bool winapi_named_semaphore::remove(const char *name)
215
+{
216
+   return windows_named_sync::remove(name);
217
+}
218
+
219
+inline bool winapi_named_semaphore::remove(const wchar_t *name)
220
+{
221
+   return windows_named_sync::remove(name);
222
+}
223
+
224
+}  //namespace ipcdetail {
225
+}  //namespace interprocess {
226
+}  //namespace boost {
227
+
228
+#include <boost/interprocess/detail/config_end.hpp>
229
+
230
+#endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
0 231
new file mode 100755
... ...
@@ -0,0 +1,236 @@
1
+//////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
12
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/creation_tags.hpp>
25
+#include <boost/interprocess/permissions.hpp>
26
+#include <boost/interprocess/detail/shared_dir_helpers.hpp>
27
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
28
+#include <boost/interprocess/errors.hpp>
29
+#include <boost/interprocess/exceptions.hpp>
30
+#include <string>
31
+#include <boost/assert.hpp>
32
+
33
+namespace boost {
34
+namespace interprocess {
35
+namespace ipcdetail {
36
+
37
+class windows_named_sync_interface
38
+{
39
+   public:
40
+   virtual std::size_t get_data_size() const = 0;
41
+   virtual const void *buffer_with_final_data_to_file() = 0;
42
+   virtual const void *buffer_with_init_data_to_file() = 0;
43
+   virtual void *buffer_to_store_init_data_from_file() = 0;
44
+   virtual bool open(create_enum_t creation_type, const char *id_name) = 0;
45
+   virtual bool open(create_enum_t creation_type, const wchar_t *id_name) = 0;
46
+   virtual void close() = 0;
47
+   virtual ~windows_named_sync_interface() = 0;
48
+};
49
+
50
+inline windows_named_sync_interface::~windows_named_sync_interface()
51
+{}
52
+
53
+class windows_named_sync
54
+{
55
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
56
+
57
+   //Non-copyable
58
+   windows_named_sync(const windows_named_sync &);
59
+   windows_named_sync &operator=(const windows_named_sync &);
60
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
61
+
62
+   public:
63
+   windows_named_sync();
64
+   template <class CharT>
65
+   void open_or_create(create_enum_t creation_type, const CharT *name, const permissions &perm, windows_named_sync_interface &sync_interface);
66
+   void close(windows_named_sync_interface &sync_interface);
67
+
68
+   static bool remove(const char *name);
69
+   static bool remove(const wchar_t *name);
70
+
71
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
72
+   private:
73
+   void *m_file_hnd;
74
+
75
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
76
+};
77
+
78
+inline windows_named_sync::windows_named_sync()
79
+   : m_file_hnd(winapi::invalid_handle_value)
80
+{}
81
+
82
+inline void windows_named_sync::close(windows_named_sync_interface &sync_interface)
83
+{
84
+   const std::size_t buflen = sync_interface.get_data_size();
85
+   const std::size_t sizeof_file_info = sizeof(sync_id::internal_type) + buflen;
86
+   winapi::interprocess_overlapped overlapped;
87
+   if(winapi::lock_file_ex
88
+      (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
89
+      if(winapi::set_file_pointer(m_file_hnd, sizeof(sync_id::internal_type), 0, winapi::file_begin)){
90
+         const void *buf = sync_interface.buffer_with_final_data_to_file();
91
+
92
+         unsigned long written_or_read = 0;
93
+         if(winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0)){
94
+            //...
95
+         }
96
+      }
97
+   }
98
+   sync_interface.close();
99
+   if(m_file_hnd != winapi::invalid_handle_value){
100
+      winapi::close_handle(m_file_hnd);
101
+      m_file_hnd = winapi::invalid_handle_value;
102
+   }
103
+}
104
+
105
+template <class CharT>
106
+inline void windows_named_sync::open_or_create
107
+   ( create_enum_t creation_type
108
+   , const CharT *name
109
+   , const permissions &perm
110
+   , windows_named_sync_interface &sync_interface)
111
+{
112
+   std::basic_string<CharT> aux_str(name);
113
+   m_file_hnd  = winapi::invalid_handle_value;
114
+   //Use a file to emulate POSIX lifetime semantics. After this logic
115
+   //we'll obtain the ID of the native handle to open in aux_str
116
+   {
117
+      create_shared_dir_cleaning_old_and_get_filepath(name, aux_str);
118
+      //Create a file with required permissions.
119
+      m_file_hnd = winapi::create_file
120
+         ( aux_str.c_str()
121
+         , winapi::generic_read | winapi::generic_write
122
+         , creation_type == DoOpen ? winapi::open_existing :
123
+               (creation_type == DoCreate ? winapi::create_new : winapi::open_always)
124
+         , 0
125
+         , (winapi::interprocess_security_attributes*)perm.get_permissions());
126
+
127
+      //Obtain OS error in case something has failed
128
+      error_info err;
129
+      bool success = false;
130
+      if(m_file_hnd != winapi::invalid_handle_value){
131
+         //Now lock the file
132
+         const std::size_t buflen = sync_interface.get_data_size();
133
+         typedef __int64 unique_id_type;
134
+         const std::size_t sizeof_file_info = sizeof(unique_id_type) + buflen;
135
+         winapi::interprocess_overlapped overlapped;
136
+         if(winapi::lock_file_ex
137
+            (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
138
+            __int64 filesize = 0;
139
+            //Obtain the unique id to open the native semaphore.
140
+            //If file size was created
141
+            if(winapi::get_file_size(m_file_hnd, filesize)){
142
+               unsigned long written_or_read = 0;
143
+               unique_id_type unique_id_val;
144
+               if(static_cast<std::size_t>(filesize) != sizeof_file_info){
145
+                  winapi::set_end_of_file(m_file_hnd);
146
+                  winapi::query_performance_counter(&unique_id_val);
147
+                  const void *buf = sync_interface.buffer_with_init_data_to_file();
148
+                  //Write unique ID in file. This ID will be used to calculate the semaphore name
149
+                  if(winapi::write_file(m_file_hnd, &unique_id_val, sizeof(unique_id_val), &written_or_read, 0)  &&
150
+                     written_or_read == sizeof(unique_id_val) &&
151
+                     winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0) &&
152
+                     written_or_read == buflen ){
153
+                     success = true;
154
+                  }
155
+                  winapi::get_file_size(m_file_hnd, filesize);
156
+                  BOOST_ASSERT(std::size_t(filesize) == sizeof_file_info);
157
+               }
158
+               else{
159
+                  void *buf = sync_interface.buffer_to_store_init_data_from_file();
160
+                  if(winapi::read_file(m_file_hnd, &unique_id_val, sizeof(unique_id_val), &written_or_read, 0)  &&
161
+                     written_or_read == sizeof(unique_id_val) &&
162
+                     winapi::read_file(m_file_hnd, buf, buflen, &written_or_read, 0)  &&
163
+                     written_or_read == buflen   ){
164
+                     success = true;
165
+                  }
166
+               }
167
+               if(success){
168
+                  //Now create a global semaphore name based on the unique id
169
+                  CharT unique_id_name[sizeof(unique_id_val)*2+1];
170
+                  std::size_t name_suffix_length = sizeof(unique_id_name);
171
+                  bytes_to_str(&unique_id_val, sizeof(unique_id_val), &unique_id_name[0], name_suffix_length);
172
+                  success = sync_interface.open(creation_type, unique_id_name);
173
+               }
174
+            }
175
+
176
+            //Obtain OS error in case something has failed
177
+            err = system_error_code();
178
+
179
+            //If this fails we have no possible rollback so don't check the return
180
+            if(!winapi::unlock_file_ex(m_file_hnd, 0, sizeof_file_info, 0, &overlapped)){
181
+               err = system_error_code();
182
+            }
183
+         }
184
+         else{
185
+            //Obtain OS error in case something has failed
186
+            err = system_error_code();
187
+         }
188
+      }
189
+      else{
190
+         err = system_error_code();
191
+      }
192
+
193
+      if(!success){
194
+         if(m_file_hnd != winapi::invalid_handle_value){
195
+            winapi::close_handle(m_file_hnd);
196
+            m_file_hnd = winapi::invalid_handle_value;
197
+         }
198
+         //Throw as something went wrong
199
+         throw interprocess_exception(err);
200
+      }
201
+   }
202
+}
203
+
204
+inline bool windows_named_sync::remove(const char *name)
205
+{
206
+   try{
207
+      //Make sure a temporary path is created for shared memory
208
+      std::string semfile;
209
+      ipcdetail::shared_filepath(name, semfile);
210
+      return winapi::unlink_file(semfile.c_str());
211
+   }
212
+   catch(...){
213
+      return false;
214
+   }
215
+}
216
+
217
+inline bool windows_named_sync::remove(const wchar_t *name)
218
+{
219
+   try{
220
+      //Make sure a temporary path is created for shared memory
221
+      std::wstring semfile;
222
+      ipcdetail::shared_filepath(name, semfile);
223
+      return winapi::unlink_file(semfile.c_str());
224
+   }
225
+   catch(...){
226
+      return false;
227
+   }
228
+}
229
+
230
+}  //namespace ipcdetail {
231
+}  //namespace interprocess {
232
+}  //namespace boost {
233
+
234
+#include <boost/interprocess/detail/config_end.hpp>
235
+
236
+#endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
0 237
new file mode 100755
... ...
@@ -0,0 +1,47 @@
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
+#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/sync/windows/mutex.hpp>
25
+
26
+namespace boost {
27
+namespace interprocess {
28
+namespace ipcdetail {
29
+
30
+//Windows mutex is already recursive
31
+class winapi_recursive_mutex
32
+   : public winapi_mutex
33
+{
34
+   winapi_recursive_mutex(const winapi_recursive_mutex &);
35
+   winapi_recursive_mutex &operator=(const winapi_recursive_mutex &);
36
+   public:
37
+   winapi_recursive_mutex() : winapi_mutex() {}
38
+};
39
+
40
+}  //namespace ipcdetail {
41
+}  //namespace interprocess {
42
+}  //namespace boost {
43
+
44
+
45
+#include <boost/interprocess/detail/config_end.hpp>
46
+
47
+#endif   //BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
0 48
new file mode 100755
... ...
@@ -0,0 +1,119 @@
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
+#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
25
+#include <boost/interprocess/detail/win32_api.hpp>
26
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
27
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
28
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
29
+#include <boost/interprocess/exceptions.hpp>
30
+#include <boost/assert.hpp>
31
+
32
+
33
+namespace boost {
34
+namespace interprocess {
35
+namespace ipcdetail {
36
+
37
+class winapi_semaphore
38
+{
39
+   winapi_semaphore(const winapi_semaphore &);
40
+   winapi_semaphore &operator=(const winapi_semaphore &);
41
+   public:
42
+
43
+   winapi_semaphore(unsigned int initialCount);
44
+   ~winapi_semaphore();
45
+
46
+   void post(unsigned int release_count = 1);
47
+   void wait();
48
+   bool try_wait();
49
+   bool timed_wait(const boost::posix_time::ptime &abs_time);
50
+
51
+   private:
52
+   const sync_id id_;
53
+   const unsigned initial_count_;
54
+};
55
+
56
+inline winapi_semaphore::winapi_semaphore(unsigned int initialCount)
57
+   : id_(this), initial_count_(initialCount)
58
+{
59
+   sync_handles &handles =
60
+      windows_intermodule_singleton<sync_handles>::get();
61
+   //Force smeaphore creation with the initial count
62
+   bool open_or_created;
63
+   handles.obtain_semaphore(this->id_, initialCount, &open_or_created);
64
+   //The semaphore must be created, never opened
65
+   BOOST_ASSERT(open_or_created);
66
+   BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
67
+   (void)open_or_created;
68
+}
69
+
70
+inline winapi_semaphore::~winapi_semaphore()
71
+{
72
+   sync_handles &handles =
73
+      windows_intermodule_singleton<sync_handles>::get();
74
+   handles.destroy_handle(this->id_);
75
+}
76
+
77
+inline void winapi_semaphore::wait()
78
+{
79
+   sync_handles &handles =
80
+      windows_intermodule_singleton<sync_handles>::get();
81
+   //This can throw
82
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, initial_count_));
83
+   sem.wait();
84
+}
85
+
86
+inline bool winapi_semaphore::try_wait()
87
+{
88
+   sync_handles &handles =
89
+      windows_intermodule_singleton<sync_handles>::get();
90
+   //This can throw
91
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, initial_count_));
92
+   return sem.try_wait();
93
+}
94
+
95
+inline bool winapi_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
96
+{
97
+   sync_handles &handles =
98
+      windows_intermodule_singleton<sync_handles>::get();
99
+   //This can throw
100
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, initial_count_));
101
+   return sem.timed_wait(abs_time);
102
+}
103
+
104
+inline void winapi_semaphore::post(unsigned release_count)
105
+{
106
+   sync_handles &handles =
107
+      windows_intermodule_singleton<sync_handles>::get();
108
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, initial_count_));
109
+   sem.post(release_count);
110
+}
111
+
112
+
113
+}  //namespace ipcdetail {
114
+}  //namespace interprocess {
115
+}  //namespace boost {
116
+
117
+#include <boost/interprocess/detail/config_end.hpp>
118
+
119
+#endif   //BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
0 120
new file mode 100755
... ...
@@ -0,0 +1,262 @@
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
+#ifndef BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/detail/win32_api.hpp>
25
+#include <boost/interprocess/sync/spin/mutex.hpp>
26
+#include <boost/interprocess/exceptions.hpp>
27
+#include <boost/interprocess/sync/scoped_lock.hpp>
28
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
29
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
30
+
31
+//Shield against external warnings
32
+#include <boost/interprocess/detail/config_external_begin.hpp>
33
+   #include <boost/unordered/unordered_map.hpp>
34
+#include <boost/interprocess/detail/config_external_end.hpp>
35
+
36
+
37
+#include <boost/container/map.hpp>
38
+#include <cstddef>
39
+
40
+namespace boost {
41
+namespace interprocess {
42
+namespace ipcdetail {
43
+
44
+inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *out_str, std::size_t &out_length)
45
+{
46
+   const std::size_t need_mem = mem_length*2+1;
47
+   if(out_length < need_mem){
48
+      out_length = need_mem;
49
+      return false;
50
+   }
51
+
52
+   const char Characters [] =
53
+      { '0', '1', '2', '3', '4', '5', '6', '7'
54
+      , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
55
+
56
+   std::size_t char_counter = 0;
57
+   const char *buf = (const char *)mem;
58
+   for(std::size_t i = 0; i != mem_length; ++i){
59
+      out_str[char_counter++] = Characters[(buf[i]&0xF0)>>4];
60
+      out_str[char_counter++] = Characters[(buf[i]&0x0F)];
61
+   }
62
+   out_str[char_counter] = 0;
63
+   return true;
64
+}
65
+
66
+inline bool bytes_to_str(const void *mem, const std::size_t mem_length, wchar_t *out_str, std::size_t &out_length)
67
+{
68
+   const std::size_t need_mem = mem_length*2+1;
69
+   if(out_length < need_mem){
70
+      out_length = need_mem;
71
+      return false;
72
+   }
73
+
74
+   const wchar_t Characters [] =
75
+      { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7'
76
+      , L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
77
+
78
+   std::size_t char_counter = 0;
79
+   const char *buf = (const char *)mem;
80
+   for(std::size_t i = 0; i != mem_length; ++i){
81
+      out_str[char_counter++] = Characters[(buf[i]&0xF0)>>4];
82
+      out_str[char_counter++] = Characters[(buf[i]&0x0F)];
83
+   }
84
+   out_str[char_counter] = 0;
85
+   return true;
86
+}
87
+
88
+class sync_id
89
+{
90
+   public:
91
+   typedef __int64 internal_type;
92
+   sync_id(const void *map_addr)
93
+      : map_addr_(map_addr)
94
+   {  winapi::query_performance_counter(&rand_);  }
95
+
96
+   explicit sync_id(internal_type val, const void *map_addr)
97
+      : map_addr_(map_addr)
98
+   {  rand_ = val;  }
99
+
100
+   const internal_type &internal_pod() const
101
+   {  return rand_;  }
102
+
103
+   internal_type &internal_pod()
104
+   {  return rand_;  }
105
+
106
+   const void *map_address() const
107
+   {  return map_addr_;  }
108
+
109
+   friend std::size_t hash_value(const sync_id &m)
110
+   {  return boost::hash_value(m.rand_);  }
111
+
112
+   friend bool operator==(const sync_id &l, const sync_id &r)
113
+   {  return l.rand_ == r.rand_ && l.map_addr_ == r.map_addr_;  }
114
+
115
+   private:
116
+   internal_type rand_;
117
+   const void * const map_addr_;
118
+};
119
+
120
+class sync_handles
121
+{
122
+   public:
123
+   enum type { MUTEX, SEMAPHORE };
124
+
125
+   private:
126
+   struct address_less
127
+   {
128
+      bool operator()(sync_id const * const l, sync_id const * const r) const
129
+      {  return l->map_address() <  r->map_address(); }
130
+   };
131
+
132
+   typedef boost::unordered_map<sync_id, void*> umap_type;
133
+   typedef boost::container::map<const sync_id*, umap_type::iterator, address_less> map_type;
134
+   static const std::size_t LengthOfGlobal = sizeof("Global\\boost.ipc")-1;
135
+   static const std::size_t StrSize        = LengthOfGlobal + (sizeof(sync_id)*2+1);
136
+   typedef char NameBuf[StrSize];
137
+
138
+
139
+   void fill_name(NameBuf &name, const sync_id &id)
140
+   {
141
+      const char *n = "Global\\boost.ipc";
142
+      std::size_t i = 0;
143
+      do{
144
+         name[i] = n[i];
145
+         ++i;
146
+      } while(n[i]);
147
+      std::size_t len = sizeof(NameBuf) - LengthOfGlobal;
148
+      bytes_to_str(&id.internal_pod(), sizeof(id.internal_pod()), &name[LengthOfGlobal], len);
149
+   }
150
+
151
+   void throw_if_error(void *hnd_val)
152
+   {
153
+      if(!hnd_val){
154
+         error_info err(winapi::get_last_error());
155
+         throw interprocess_exception(err);
156
+      }
157
+   }
158
+
159
+   void* open_or_create_semaphore(const sync_id &id, unsigned int initial_count)
160
+   {
161
+      NameBuf name;
162
+      fill_name(name, id);
163
+      permissions unrestricted_security;
164
+      unrestricted_security.set_unrestricted();
165
+      winapi_semaphore_wrapper sem_wrapper;
166
+      bool created;
167
+      sem_wrapper.open_or_create
168
+         (name, (long)initial_count, winapi_semaphore_wrapper::MaxCount, unrestricted_security, created);
169
+      throw_if_error(sem_wrapper.handle());
170
+      return sem_wrapper.release();
171
+   }
172
+
173
+   void* open_or_create_mutex(const sync_id &id)
174
+   {
175
+      NameBuf name;
176
+      fill_name(name, id);
177
+      permissions unrestricted_security;
178
+      unrestricted_security.set_unrestricted();
179
+      winapi_mutex_wrapper mtx_wrapper;
180
+      mtx_wrapper.open_or_create(name, unrestricted_security);
181
+      throw_if_error(mtx_wrapper.handle());
182
+      return mtx_wrapper.release();
183
+   }
184
+
185
+   public:
186
+   void *obtain_mutex(const sync_id &id, bool *popen_created = 0)
187
+   {
188
+      umap_type::value_type v(id, (void*)0);
189
+      scoped_lock<spin_mutex> lock(mtx_);
190
+      umap_type::iterator it = umap_.insert(v).first;
191
+      void *&hnd_val = it->second;
192
+      if(!hnd_val){
193
+         map_[&it->first] = it;
194
+         hnd_val = open_or_create_mutex(id);
195
+         if(popen_created) *popen_created = true;
196
+      }
197
+      else if(popen_created){
198
+         *popen_created = false;
199
+      }
200
+      return hnd_val;
201
+   }
202
+
203
+   void *obtain_semaphore(const sync_id &id, unsigned int initial_count, bool *popen_created = 0)
204
+   {
205
+      umap_type::value_type v(id, (void*)0);
206
+      scoped_lock<spin_mutex> lock(mtx_);
207
+      umap_type::iterator it = umap_.insert(v).first;
208
+      void *&hnd_val = it->second;
209
+      if(!hnd_val){
210
+         map_[&it->first] = it;
211
+         hnd_val = open_or_create_semaphore(id, initial_count);
212
+         if(popen_created) *popen_created = true;
213
+      }
214
+      else if(popen_created){
215
+         *popen_created = false;
216
+      }
217
+      return hnd_val;
218
+   }
219
+
220
+   void destroy_handle(const sync_id &id)
221
+   {
222
+      scoped_lock<spin_mutex> lock(mtx_);
223
+      umap_type::iterator it = umap_.find(id);
224
+      umap_type::iterator itend = umap_.end();
225
+
226
+      if(it != itend){
227
+         winapi::close_handle(it->second);
228
+         const map_type::key_type &k = &it->first;
229
+         map_.erase(k);
230
+         umap_.erase(it);
231
+      }
232
+   }
233
+
234
+   void destroy_syncs_in_range(const void *addr, std::size_t size)
235
+   {
236
+      const sync_id low_id(addr);
237
+      const sync_id hig_id(static_cast<const char*>(addr)+size);
238
+      scoped_lock<spin_mutex> lock(mtx_);
239
+      map_type::iterator itlow(map_.lower_bound(&low_id)),
240
+                         ithig(map_.lower_bound(&hig_id));
241
+      while(itlow != ithig){
242
+         void * const hnd = umap_[*itlow->first];
243
+         winapi::close_handle(hnd);
244
+         umap_.erase(*itlow->first);
245
+         itlow = map_.erase(itlow);
246
+      }
247
+   }
248
+
249
+   private:
250
+   spin_mutex mtx_;
251
+   umap_type umap_;
252
+   map_type map_;
253
+};
254
+
255
+
256
+}  //namespace ipcdetail {
257
+}  //namespace interprocess {
258
+}  //namespace boost {
259
+
260
+#include <boost/interprocess/detail/config_end.hpp>
261
+
262
+#endif   //BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
0 263
new file mode 100755
... ...
@@ -0,0 +1,135 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/creation_tags.hpp>
25
+#include <boost/interprocess/permissions.hpp>
26
+#include <boost/interprocess/detail/win32_api.hpp>
27
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
28
+#include <boost/interprocess/sync/windows/winapi_wrapper_common.hpp>
29
+#include <boost/interprocess/errors.hpp>
30
+#include <boost/interprocess/exceptions.hpp>
31
+#include <limits>
32
+
33
+namespace boost {
34
+namespace interprocess {
35
+namespace ipcdetail {
36
+
37
+class winapi_mutex_functions
38
+{
39
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
40
+
41
+   //Non-copyable
42
+   winapi_mutex_functions(const winapi_mutex_functions &);
43
+   winapi_mutex_functions &operator=(const winapi_mutex_functions &);
44
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
45
+
46
+   public:
47
+   winapi_mutex_functions(void *mtx_hnd)
48
+      : m_mtx_hnd(mtx_hnd)
49
+   {}
50
+
51
+   void unlock()
52
+   {  winapi::release_mutex(m_mtx_hnd);   }
53
+
54
+   void lock()
55
+   {  return winapi_wrapper_wait_for_single_object(m_mtx_hnd);  }
56
+
57
+   bool try_lock()
58
+   {  return winapi_wrapper_try_wait_for_single_object(m_mtx_hnd);  }
59
+
60
+   bool timed_lock(const boost::posix_time::ptime &abs_time)
61
+   {  return winapi_wrapper_timed_wait_for_single_object(m_mtx_hnd, abs_time);  }
62
+
63
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
64
+   protected:
65
+   void *m_mtx_hnd;
66
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
67
+};
68
+
69
+//Swappable mutex wrapper
70
+class winapi_mutex_wrapper
71
+   : public winapi_mutex_functions
72
+{
73
+   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
74
+
75
+   //Non-copyable
76
+   winapi_mutex_wrapper(const winapi_mutex_wrapper &);
77
+   winapi_mutex_wrapper &operator=(const winapi_mutex_wrapper &);
78
+   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
79
+
80
+   //Note that Windows API does not return winapi::invalid_handle_value
81
+   //when failing to create/open a mutex, but a nullptr
82
+
83
+   public:
84
+   winapi_mutex_wrapper(void *mtx_hnd = 0)
85
+      : winapi_mutex_functions(mtx_hnd)
86
+   {}
87
+
88
+   ~winapi_mutex_wrapper()
89
+   {  this->close(); }
90
+
91
+   void *release()
92
+   {
93
+      void *hnd = m_mtx_hnd;
94
+      m_mtx_hnd = 0;
95
+      return hnd;
96
+   }
97
+
98
+   void *handle() const
99
+   {  return m_mtx_hnd; }
100
+
101
+   template<class CharT>
102
+   bool open_or_create(const CharT *name, const permissions &perm)
103
+   {
104
+      if(m_mtx_hnd == 0){
105
+         m_mtx_hnd = winapi::open_or_create_mutex
106
+            ( name
107
+            , false
108
+            , (winapi::interprocess_security_attributes*)perm.get_permissions()
109
+            );
110
+         return m_mtx_hnd != 0;
111
+      }
112
+      else{
113
+         return false;
114
+      }
115
+   }
116
+
117
+   void close()
118
+   {
119
+      if(m_mtx_hnd != 0){
120
+         winapi::close_handle(m_mtx_hnd);
121
+         m_mtx_hnd = 0;
122
+      }
123
+   }
124
+
125
+   void swap(winapi_mutex_wrapper &other)
126
+   {  void *tmp = m_mtx_hnd; m_mtx_hnd = other.m_mtx_hnd; other.m_mtx_hnd = tmp;   }
127
+};
128
+
129
+}  //namespace ipcdetail {
130
+}  //namespace interprocess {
131
+}  //namespace boost {
132
+
133
+#include <boost/interprocess/detail/config_end.hpp>
134
+
135
+#endif   //BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
0 136
new file mode 100755
... ...
@@ -0,0 +1,169 @@
1
+ //////////////////////////////////////////////////////////////////////////////
2
+//
3
+// (C) Copyright Ion Gaztanaga 2011-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
+#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
12
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
13
+
14
+#ifndef BOOST_CONFIG_HPP
15
+#  include <boost/config.hpp>
16
+#endif
17
+#
18
+#if defined(BOOST_HAS_PRAGMA_ONCE)
19
+#  pragma once
20
+#endif
21
+
22
+#include <boost/interprocess/detail/config_begin.hpp>
23
+#include <boost/interprocess/detail/workaround.hpp>
24
+#include <boost/interprocess/creation_tags.hpp>
25
+#include <boost/interprocess/permissions.hpp>
26
+#include <boost/interprocess/detail/win32_api.hpp>
27