Dmitry Baikov jackmp-time patch: add jack_get_time, jack_time_to_frames, jack_frames_...
[jack2.git] / common / JackShmMem.h
blobb9f15008bbb670eb1ba68ea3ed430c36bb576f80
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 #define CHECK_MLOCKALL()(false)
36 #define CHECK_MUNLOCKALL()(false)
37 #else
38 #include <sys/types.h>
39 #include <sys/mman.h>
40 #define CHECK_MLOCK(ptr, size) (mlock((ptr), (size)) == 0)
41 #define CHECK_MUNLOCK(ptr, size) (munlock((ptr), (size)) == 0)
42 #define CHECK_MLOCKALL() (mlockall(MCL_CURRENT | MCL_FUTURE) == 0)
43 #define CHECK_MUNLOCKALL() (munlockall() == 0)
44 #endif
46 namespace Jack
49 void LockMemoryImp(void* ptr, size_t size);
50 void UnlockMemoryImp(void* ptr, size_t size);
52 class JackMem
54 private:
56 size_t fSize;
57 static size_t gSize;
59 public:
61 void* operator new(size_t size)
63 gSize = size;
64 return calloc(1, size);
67 void operator delete(void* ptr, size_t size)
69 free(ptr);
72 JackMem():fSize(gSize)
75 virtual ~JackMem()
77 UnlockMemoryImp(this, fSize);
80 void LockMemory()
82 LockMemoryImp(this, fSize);
85 void UnlockMemory()
87 UnlockMemoryImp(this, fSize);
92 /*!
93 \brief The base class for shared memory management.
95 A class which objects need to be allocated in shared memory derives from this class.
98 class JackShmMem
101 protected:
103 jack_shm_info_t fInfo;
104 static unsigned long fSegmentNum;
105 static unsigned long fSegmentCount;
106 static jack_shm_info_t gInfo;
108 public:
110 void* operator new(size_t size);
111 void operator delete(void* p, size_t size);
113 JackShmMem()
115 fInfo.index = gInfo.index;
116 fInfo.attached_at = gInfo.attached_at;
117 fInfo.size = gInfo.size;
120 virtual ~JackShmMem()
122 UnlockMemoryImp(this, fInfo.size);
125 int GetShmIndex()
127 return fInfo.index;
130 char* GetShmAddress()
132 return (char*)fInfo.attached_at;
135 void LockMemory()
137 LockMemoryImp(this, fInfo.size);
140 void UnlockMemory()
142 UnlockMemoryImp(this, fInfo.size);
148 \brief Pointer on shared memory segment in the client side.
151 template <class T>
152 class JackShmReadWritePtr
155 private:
157 jack_shm_info_t fInfo;
159 void Init(int index)
161 if (fInfo.index < 0 && index >= 0) {
162 JackLog("JackShmReadWritePtr::Init %ld %ld\n", index, fInfo.index);
163 if (jack_initialize_shm_client() < 0)
164 throw - 1;
165 fInfo.index = index;
166 if (jack_attach_shm(&fInfo)) {
167 //jack_error("cannot attach shared memory segment", strerror(errno));
168 throw - 2;
173 public:
175 JackShmReadWritePtr()
177 fInfo.index = -1;
178 fInfo.attached_at = NULL;
181 JackShmReadWritePtr(int index)
183 Init(index);
186 virtual ~JackShmReadWritePtr()
188 if (fInfo.index >= 0) {
189 JackLog("JackShmReadWritePtr::~JackShmReadWritePtr %ld\n", fInfo.index);
190 jack_release_shm(&fInfo);
191 fInfo.index = -1;
195 T* operator->() const
197 return (T*)fInfo.attached_at;
200 operator T*() const
202 return (T*)fInfo.attached_at;
205 JackShmReadWritePtr& operator=(int index)
207 Init(index);
208 return *this;
211 int GetShmIndex()
213 return fInfo.index;
216 T* GetShmAddress()
218 return (T*)fInfo.attached_at;
223 \brief Pointer on shared memory segment in the client side: destroy the segment (used client control)
226 template <class T>
227 class JackShmReadWritePtr1
230 private:
232 jack_shm_info_t fInfo;
234 void Init(int index)
236 if (fInfo.index < 0 && index >= 0) {
237 JackLog("JackShmReadWritePtr1::Init %ld %ld\n", index, fInfo.index);
238 if (jack_initialize_shm_client() < 0)
239 throw - 1;
240 fInfo.index = index;
241 if (jack_attach_shm(&fInfo)) {
242 //jack_error("cannot attach shared memory segment", strerror(errno));
243 throw - 2;
246 nobody else needs to access this shared memory any more, so
247 destroy it. because we have our own attachment to it, it won't
248 vanish till we exit (and release it).
250 jack_destroy_shm(&fInfo);
254 public:
256 JackShmReadWritePtr1()
258 fInfo.index = -1;
259 fInfo.attached_at = NULL;
262 JackShmReadWritePtr1(int index)
264 Init(index);
267 virtual ~JackShmReadWritePtr1()
269 if (fInfo.index >= 0) {
270 JackLog("JackShmReadWritePtr1::~JackShmReadWritePtr1 %ld\n", fInfo.index);
271 jack_release_shm(&fInfo);
272 fInfo.index = -1;
276 T* operator->() const
278 return (T*)fInfo.attached_at;
281 operator T*() const
283 return (T*)fInfo.attached_at;
286 JackShmReadWritePtr1& operator=(int index)
288 Init(index);
289 return *this;
292 int GetShmIndex()
294 return fInfo.index;
297 T* GetShmAddress()
299 return (T*)fInfo.attached_at;
304 \brief Pointer on shared memory segment in the client side.
307 template <class T>
308 class JackShmReadPtr
311 private:
313 jack_shm_info_t fInfo;
315 void Init(int index)
317 if (fInfo.index < 0 && index >= 0) {
318 JackLog("JackShmPtrRead::Init %ld %ld\n", index, fInfo.index);
319 if (jack_initialize_shm_client() < 0)
320 throw - 1;
321 fInfo.index = index;
322 if (jack_attach_shm_read(&fInfo)) {
323 //jack_error("cannot attach shared memory segment", strerror(errno));
324 throw - 2;
329 public:
331 JackShmReadPtr()
333 fInfo.index = -1;
334 fInfo.attached_at = NULL;
337 JackShmReadPtr(int index)
339 Init(index);
342 virtual ~JackShmReadPtr()
344 if (fInfo.index >= 0) {
345 JackLog("JackShmPtrRead::~JackShmPtrRead %ld\n", fInfo.index);
346 jack_release_shm(&fInfo);
347 fInfo.index = -1;
351 T* operator->() const
353 return (T*)fInfo.attached_at;
356 operator T*() const
358 return (T*)fInfo.attached_at;
361 JackShmReadPtr& operator=(int index)
363 Init(index);
364 return *this;
367 int GetShmIndex()
369 return fInfo.index;
372 T* GetShmAddress()
374 return (T*)fInfo.attached_at;
379 } // end of namespace
381 #endif