Correct memory locking code on Windows
[jack2.git] / common / JackShmMem.h
blobaeaacb5133e998449d0bfdc33c898938449c47f8
1 /*
2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2006 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #ifndef __JackShmMem__
22 #define __JackShmMem__
24 #include "shm.h"
25 #include "JackError.h"
27 #include <new> // GCC 4.0
28 #include <errno.h>
29 #include <stdlib.h>
31 #ifdef WIN32
32 #include <windows.h>
33 #define CHECK_MLOCK(ptr, size) (VirtualLock((ptr), (size)) != 0)
34 #define CHECK_MUNLOCK(ptr, size) (VirtualUnlock((ptr), (size)) != 0)
35 #else
36 #include <sys/types.h>
37 #include <sys/mman.h>
38 #define CHECK_MLOCK(ptr, size) (munlock((ptr), (size)) == 0)
39 #define CHECK_MUNLOCK(ptr, size) (munlock((ptr), (size)) == 0)
40 #endif
42 namespace Jack
45 void LockMemoryImp(void* ptr, size_t size);
46 void UnlockMemoryImp(void* ptr, size_t size);
48 class JackMem
50 private:
52 size_t fSize;
53 static size_t gSize;
55 public:
57 void* operator new(size_t size)
59 gSize = size;
60 return calloc(1, size);
63 void operator delete(void* ptr, size_t size)
65 free(ptr);
68 JackMem():fSize(gSize)
71 virtual ~JackMem()
73 UnlockMemoryImp(this, fSize);
76 void LockMemory()
78 LockMemoryImp(this, fSize);
81 void UnlockMemory()
83 UnlockMemoryImp(this, fSize);
88 /*!
89 \brief The base class for shared memory management.
91 A class which objects need to be allocated in shared memory derives from this class.
94 class JackShmMem
97 protected:
99 jack_shm_info_t fInfo;
100 static unsigned long fSegmentNum;
101 static unsigned long fSegmentCount;
102 static jack_shm_info_t gInfo;
104 public:
106 void* operator new(size_t size);
107 void operator delete(void* p, size_t size);
109 JackShmMem()
111 fInfo.index = gInfo.index;
112 fInfo.attached_at = gInfo.attached_at;
113 fInfo.size = gInfo.size;
116 virtual ~JackShmMem()
118 UnlockMemoryImp(this, fInfo.size);
121 int GetShmIndex()
123 return fInfo.index;
126 char* GetShmAddress()
128 return (char*)fInfo.attached_at;
131 void LockMemory()
133 LockMemoryImp(this, fInfo.size);
136 void UnlockMemory()
138 UnlockMemoryImp(this, fInfo.size);
144 \brief Pointer on shared memory segment in the client side.
147 template <class T>
148 class JackShmReadWritePtr
151 private:
153 jack_shm_info_t fInfo;
155 void Init(int index)
157 if (fInfo.index < 0 && index >= 0) {
158 JackLog("JackShmReadWritePtr::Init %ld %ld\n", index, fInfo.index);
159 if (jack_initialize_shm_client() < 0)
160 throw - 1;
161 fInfo.index = index;
162 if (jack_attach_shm(&fInfo)) {
163 //jack_error("cannot attach shared memory segment", strerror(errno));
164 throw - 2;
169 public:
171 JackShmReadWritePtr()
173 fInfo.index = -1;
174 fInfo.attached_at = NULL;
177 JackShmReadWritePtr(int index)
179 Init(index);
182 virtual ~JackShmReadWritePtr()
184 if (fInfo.index >= 0) {
185 JackLog("JackShmReadWritePtr::~JackShmReadWritePtr %ld\n", fInfo.index);
186 jack_release_shm(&fInfo);
187 fInfo.index = -1;
191 T* operator->() const
193 return (T*)fInfo.attached_at;
196 operator T*() const
198 return (T*)fInfo.attached_at;
201 JackShmReadWritePtr& operator=(int index)
203 Init(index);
204 return *this;
207 int GetShmIndex()
209 return fInfo.index;
212 T* GetShmAddress()
214 return (T*)fInfo.attached_at;
219 \brief Pointer on shared memory segment in the client side: destroy the segment (used client control)
222 template <class T>
223 class JackShmReadWritePtr1
226 private:
228 jack_shm_info_t fInfo;
230 void Init(int index)
232 if (fInfo.index < 0 && index >= 0) {
233 JackLog("JackShmReadWritePtr1::Init %ld %ld\n", index, fInfo.index);
234 if (jack_initialize_shm_client() < 0)
235 throw - 1;
236 fInfo.index = index;
237 if (jack_attach_shm(&fInfo)) {
238 //jack_error("cannot attach shared memory segment", strerror(errno));
239 throw - 2;
242 nobody else needs to access this shared memory any more, so
243 destroy it. because we have our own attachment to it, it won't
244 vanish till we exit (and release it).
246 jack_destroy_shm(&fInfo);
250 public:
252 JackShmReadWritePtr1()
254 fInfo.index = -1;
255 fInfo.attached_at = NULL;
258 JackShmReadWritePtr1(int index)
260 Init(index);
263 virtual ~JackShmReadWritePtr1()
265 if (fInfo.index >= 0) {
266 JackLog("JackShmReadWritePtr1::~JackShmReadWritePtr1 %ld\n", fInfo.index);
267 jack_release_shm(&fInfo);
268 fInfo.index = -1;
272 T* operator->() const
274 return (T*)fInfo.attached_at;
277 operator T*() const
279 return (T*)fInfo.attached_at;
282 JackShmReadWritePtr1& operator=(int index)
284 Init(index);
285 return *this;
288 int GetShmIndex()
290 return fInfo.index;
293 T* GetShmAddress()
295 return (T*)fInfo.attached_at;
300 \brief Pointer on shared memory segment in the client side.
303 template <class T>
304 class JackShmReadPtr
307 private:
309 jack_shm_info_t fInfo;
311 void Init(int index)
313 if (fInfo.index < 0 && index >= 0) {
314 JackLog("JackShmPtrRead::Init %ld %ld\n", index, fInfo.index);
315 if (jack_initialize_shm_client() < 0)
316 throw - 1;
317 fInfo.index = index;
318 if (jack_attach_shm_read(&fInfo)) {
319 //jack_error("cannot attach shared memory segment", strerror(errno));
320 throw - 2;
325 public:
327 JackShmReadPtr()
329 fInfo.index = -1;
330 fInfo.attached_at = NULL;
333 JackShmReadPtr(int index)
335 Init(index);
338 virtual ~JackShmReadPtr()
340 if (fInfo.index >= 0) {
341 JackLog("JackShmPtrRead::~JackShmPtrRead %ld\n", fInfo.index);
342 jack_release_shm(&fInfo);
343 fInfo.index = -1;
347 T* operator->() const
349 return (T*)fInfo.attached_at;
352 operator T*() const
354 return (T*)fInfo.attached_at;
357 JackShmReadPtr& operator=(int index)
359 Init(index);
360 return *this;
363 int GetShmIndex()
365 return fInfo.index;
368 T* GetShmAddress()
370 return (T*)fInfo.attached_at;
375 } // end of namespace
377 #endif