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