Merge branch 'master' into develop
[jack2.git] / common / JackShmMem.h
blobce2398968b5e3dfeadccad0195cec92d4c248dfa
1 /*
2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #ifndef __JackShmMem__
21 #define __JackShmMem__
23 #include "shm.h"
24 #include "JackError.h"
25 #include "JackCompilerDeps.h"
27 #include <new> // GCC 4.0
28 #include <errno.h>
29 #include <stdlib.h>
31 #include "JackShmMem_os.h"
33 namespace Jack
36 void LockMemoryImp(void* ptr, size_t size);
37 void InitLockMemoryImp(void* ptr, size_t size);
38 void UnlockMemoryImp(void* ptr, size_t size);
39 void LockAllMemory();
40 void UnlockAllMemory();
42 /*!
43 \brief
45 A class which objects possibly want to be allocated in shared memory derives from this class.
48 class JackShmMemAble
50 protected:
52 jack_shm_info_t fInfo;
54 public:
56 void Init();
58 int GetShmIndex()
60 return fInfo.index;
63 char* GetShmAddress()
65 return (char*)fInfo.ptr.attached_at;
68 void LockMemory()
70 LockMemoryImp(this, fInfo.size);
73 void UnlockMemory()
75 UnlockMemoryImp(this, fInfo.size);
80 /*!
81 \brief The base class for shared memory management.
83 A class which objects need to be allocated in shared memory derives from this class.
86 class SERVER_EXPORT JackShmMem : public JackShmMemAble
89 protected:
91 JackShmMem();
92 ~JackShmMem();
94 public:
96 void* operator new(size_t size);
97 void* operator new(size_t size, void* memory);
99 void operator delete(void* p, size_t size);
100 void operator delete(void* p);
105 \brief Pointer on shared memory segment in the client side.
108 template <class T>
109 class JackShmReadWritePtr
112 private:
114 jack_shm_info_t fInfo;
115 bool fInitDone;
117 void Init(int index, const char* server_name = JACK_DEFAULT_SERVER_NAME)
119 if (fInfo.index < 0 && index >= 0) {
120 jack_log("JackShmReadWritePtr::Init %ld %d", index, fInfo.index);
121 if (jack_initialize_shm(server_name) < 0) {
122 throw std::bad_alloc();
124 fInfo.index = index;
125 if (jack_attach_lib_shm(&fInfo)) {
126 throw std::bad_alloc();
128 GetShmAddress()->LockMemory();
129 fInitDone = true;
133 public:
135 JackShmReadWritePtr()
137 fInfo.index = -1;
138 fInitDone = false;
139 fInfo.ptr.attached_at = (char*)NULL;
142 JackShmReadWritePtr(int index, const char* server_name)
144 Init(index, server_name);
147 ~JackShmReadWritePtr()
149 if (!fInitDone) {
150 jack_error("JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for %d, skipping unlock", fInfo.index);
151 return;
153 if (fInfo.index >= 0) {
154 jack_log("JackShmReadWritePtr::~JackShmReadWritePtr %d", fInfo.index);
155 GetShmAddress()->UnlockMemory();
156 jack_release_lib_shm(&fInfo);
157 fInfo.index = -1;
161 T* operator->() const
163 return (T*)fInfo.ptr.attached_at;
166 operator T*() const
168 return (T*)fInfo.ptr.attached_at;
171 JackShmReadWritePtr& operator=(int index)
173 Init(index);
174 return *this;
177 void SetShmIndex(int index, const char* server_name)
179 Init(index, server_name);
182 int GetShmIndex()
184 return fInfo.index;
187 T* GetShmAddress()
189 return (T*)fInfo.ptr.attached_at;
194 \brief Pointer on shared memory segment in the client side: destroy the segment (used client control)
197 template <class T>
198 class JackShmReadWritePtr1
201 private:
203 jack_shm_info_t fInfo;
204 bool fInitDone;
206 void Init(int index, const char* server_name = JACK_DEFAULT_SERVER_NAME)
208 if (fInfo.index < 0 && index >= 0) {
209 jack_log("JackShmReadWritePtr1::Init %ld %d", index, fInfo.index);
210 if (jack_initialize_shm(server_name) < 0) {
211 throw std::bad_alloc();
213 fInfo.index = index;
214 if (jack_attach_lib_shm(&fInfo)) {
215 throw std::bad_alloc();
217 GetShmAddress()->LockMemory();
218 fInitDone = true;
220 nobody else needs to access this shared memory any more, so
221 destroy it. because we have our own attachment to it, it won't
222 vanish till we exit (and release it).
224 jack_destroy_shm(&fInfo);
228 public:
230 JackShmReadWritePtr1()
232 fInfo.index = -1;
233 fInitDone = false;
234 fInfo.ptr.attached_at = NULL;
237 JackShmReadWritePtr1(int index, const char* server_name)
239 Init(index, server_name);
242 ~JackShmReadWritePtr1()
244 if (!fInitDone) {
245 jack_error("JackShmReadWritePtr1::~JackShmReadWritePtr1 - Init not done for %d, skipping unlock", fInfo.index);
246 return;
248 if (fInfo.index >= 0) {
249 jack_log("JackShmReadWritePtr1::~JackShmReadWritePtr1 %d", fInfo.index);
250 GetShmAddress()->UnlockMemory();
251 jack_release_lib_shm(&fInfo);
252 fInfo.index = -1;
256 T* operator->() const
258 return (T*)fInfo.ptr.attached_at;
261 operator T*() const
263 return (T*)fInfo.ptr.attached_at;
266 JackShmReadWritePtr1& operator=(int index)
268 Init(index);
269 return *this;
272 void SetShmIndex(int index, const char* server_name)
274 Init(index, server_name);
277 int GetShmIndex()
279 return fInfo.index;
282 T* GetShmAddress()
284 return (T*)fInfo.ptr.attached_at;
289 \brief Pointer on shared memory segment in the client side.
292 template <class T>
293 class JackShmReadPtr
296 private:
298 jack_shm_info_t fInfo;
299 bool fInitDone;
301 void Init(int index, const char* server_name = JACK_DEFAULT_SERVER_NAME)
303 if (fInfo.index < 0 && index >= 0) {
304 jack_log("JackShmPtrRead::Init %ld %d", index, fInfo.index);
305 if (jack_initialize_shm(server_name) < 0) {
306 throw std::bad_alloc();
308 fInfo.index = index;
309 if (jack_attach_lib_shm_read(&fInfo)) {
310 throw std::bad_alloc();
312 GetShmAddress()->LockMemory();
313 fInitDone = true;
317 public:
319 JackShmReadPtr()
321 fInfo.index = -1;
322 fInitDone = false;
323 fInfo.ptr.attached_at = NULL;
326 JackShmReadPtr(int index, const char* server_name)
328 Init(index, server_name);
331 ~JackShmReadPtr()
333 if (!fInitDone) {
334 jack_error("JackShmReadPtr::~JackShmReadPtr - Init not done for %ld, skipping unlock", fInfo.index);
335 return;
337 if (fInfo.index >= 0) {
338 jack_log("JackShmPtrRead::~JackShmPtrRead %ld", fInfo.index);
339 GetShmAddress()->UnlockMemory();
340 jack_release_lib_shm(&fInfo);
341 fInfo.index = -1;
345 T* operator->() const
347 return (T*)fInfo.ptr.attached_at;
350 operator T*() const
352 return (T*)fInfo.ptr.attached_at;
355 JackShmReadPtr& operator=(int index)
357 Init(index);
358 return *this;
361 void SetShmIndex(int index, const char* server_name)
363 Init(index, server_name);
366 int GetShmIndex()
368 return fInfo.index;
371 T* GetShmAddress()
373 return (T*)fInfo.ptr.attached_at;
378 } // end of namespace
380 #endif