Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 #ifndef __JackShmMem__ 00021 #define __JackShmMem__ 00022 00023 #include "shm.h" 00024 #include "JackError.h" 00025 #include "JackCompilerDeps.h" 00026 00027 #include <new> // GCC 4.0 00028 #include <errno.h> 00029 #include <stdlib.h> 00030 00031 #include "JackShmMem_os.h" 00032 00033 namespace Jack 00034 { 00035 00036 SERVER_EXPORT void LockMemoryImp(void* ptr, size_t size); 00037 SERVER_EXPORT void InitLockMemoryImp(void* ptr, size_t size); 00038 SERVER_EXPORT void UnlockMemoryImp(void* ptr, size_t size); 00039 SERVER_EXPORT void LockAllMemory(); 00040 SERVER_EXPORT void UnlockAllMemory(); 00041 00042 class JackMem 00043 { 00044 private: 00045 00046 size_t fSize; 00047 static size_t gSize; 00048 00049 protected: 00050 00051 JackMem(): fSize(gSize) 00052 {} 00053 ~JackMem() 00054 {} 00055 00056 public: 00057 00058 void* operator new(size_t size) 00059 { 00060 gSize = size; 00061 return calloc(1, size); 00062 } 00063 00064 void operator delete(void* ptr, size_t size) 00065 { 00066 free(ptr); 00067 } 00068 00069 void LockMemory() 00070 { 00071 LockMemoryImp(this, fSize); 00072 } 00073 00074 void UnlockMemory() 00075 { 00076 UnlockMemoryImp(this, fSize); 00077 } 00078 00079 }; 00080 00087 class JackShmMemAble 00088 { 00089 protected: 00090 00091 jack_shm_info_t fInfo; 00092 00093 public: 00094 00095 void Init(); 00096 00097 int GetShmIndex() 00098 { 00099 return fInfo.index; 00100 } 00101 00102 char* GetShmAddress() 00103 { 00104 return (char*)fInfo.ptr.attached_at; 00105 } 00106 00107 void LockMemory() 00108 { 00109 LockMemoryImp(this, fInfo.size); 00110 } 00111 00112 void UnlockMemory() 00113 { 00114 UnlockMemoryImp(this, fInfo.size); 00115 } 00116 00117 }; 00118 00125 class SERVER_EXPORT JackShmMem : public JackShmMemAble 00126 { 00127 00128 protected: 00129 00130 JackShmMem(); 00131 ~JackShmMem(); 00132 00133 public: 00134 00135 void* operator new(size_t size); 00136 void* operator new(size_t size, void* memory); 00137 00138 void operator delete(void* p, size_t size); 00139 void operator delete(void* p); 00140 00141 }; 00142 00147 template <class T> 00148 class JackShmReadWritePtr 00149 { 00150 00151 private: 00152 00153 jack_shm_info_t fInfo; 00154 00155 void Init(int index, const char* server_name = "default") 00156 { 00157 if (fInfo.index < 0 && index >= 0) { 00158 jack_log("JackShmReadWritePtr::Init %ld %ld", index, fInfo.index); 00159 if (jack_initialize_shm(server_name) < 0) 00160 throw - 1; 00161 fInfo.index = index; 00162 if (jack_attach_shm(&fInfo)) { 00163 throw - 2; 00164 } 00165 GetShmAddress()->LockMemory(); 00166 } 00167 } 00168 00169 public: 00170 00171 JackShmReadWritePtr() 00172 { 00173 fInfo.index = -1; 00174 fInfo.ptr.attached_at = (char*)NULL; 00175 } 00176 00177 JackShmReadWritePtr(int index, const char* server_name) 00178 { 00179 Init(index, server_name); 00180 } 00181 00182 ~JackShmReadWritePtr() 00183 { 00184 if (fInfo.index >= 0) { 00185 jack_log("JackShmReadWritePtr::~JackShmReadWritePtr %ld", fInfo.index); 00186 GetShmAddress()->UnlockMemory(); 00187 jack_release_shm(&fInfo); 00188 fInfo.index = -1; 00189 } 00190 } 00191 00192 T* operator->() const 00193 { 00194 return (T*)fInfo.ptr.attached_at; 00195 } 00196 00197 operator T*() const 00198 { 00199 return (T*)fInfo.ptr.attached_at; 00200 } 00201 00202 JackShmReadWritePtr& operator=(int index) 00203 { 00204 Init(index); 00205 return *this; 00206 } 00207 00208 void SetShmIndex(int index, const char* server_name) 00209 { 00210 Init(index, server_name); 00211 } 00212 00213 int GetShmIndex() 00214 { 00215 return fInfo.index; 00216 } 00217 00218 T* GetShmAddress() 00219 { 00220 return (T*)fInfo.ptr.attached_at; 00221 } 00222 }; 00223 00228 template <class T> 00229 class JackShmReadWritePtr1 00230 { 00231 00232 private: 00233 00234 jack_shm_info_t fInfo; 00235 00236 void Init(int index, const char* server_name = "default") 00237 { 00238 if (fInfo.index < 0 && index >= 0) { 00239 jack_log("JackShmReadWritePtr1::Init %ld %ld", index, fInfo.index); 00240 if (jack_initialize_shm(server_name) < 0) 00241 throw - 1; 00242 fInfo.index = index; 00243 if (jack_attach_shm(&fInfo)) { 00244 throw - 2; 00245 } 00246 /* 00247 nobody else needs to access this shared memory any more, so 00248 destroy it. because we have our own attachment to it, it won't 00249 vanish till we exit (and release it). 00250 */ 00251 jack_destroy_shm(&fInfo); 00252 GetShmAddress()->LockMemory(); 00253 } 00254 } 00255 00256 public: 00257 00258 JackShmReadWritePtr1() 00259 { 00260 fInfo.index = -1; 00261 fInfo.ptr.attached_at = NULL; 00262 } 00263 00264 JackShmReadWritePtr1(int index, const char* server_name) 00265 { 00266 Init(index, server_name); 00267 } 00268 00269 ~JackShmReadWritePtr1() 00270 { 00271 if (fInfo.index >= 0) { 00272 jack_log("JackShmReadWritePtr1::~JackShmReadWritePtr1 %ld", fInfo.index); 00273 GetShmAddress()->UnlockMemory(); 00274 jack_release_shm(&fInfo); 00275 fInfo.index = -1; 00276 } 00277 } 00278 00279 T* operator->() const 00280 { 00281 return (T*)fInfo.ptr.attached_at; 00282 } 00283 00284 operator T*() const 00285 { 00286 return (T*)fInfo.ptr.attached_at; 00287 } 00288 00289 JackShmReadWritePtr1& operator=(int index) 00290 { 00291 Init(index); 00292 return *this; 00293 } 00294 00295 void SetShmIndex(int index, const char* server_name) 00296 { 00297 Init(index, server_name); 00298 } 00299 00300 int GetShmIndex() 00301 { 00302 return fInfo.index; 00303 } 00304 00305 T* GetShmAddress() 00306 { 00307 return (T*)fInfo.ptr.attached_at; 00308 } 00309 }; 00310 00315 template <class T> 00316 class JackShmReadPtr 00317 { 00318 00319 private: 00320 00321 jack_shm_info_t fInfo; 00322 00323 void Init(int index, const char* server_name = "default") 00324 { 00325 if (fInfo.index < 0 && index >= 0) { 00326 jack_log("JackShmPtrRead::Init %ld %ld", index, fInfo.index); 00327 if (jack_initialize_shm(server_name) < 0) 00328 throw - 1; 00329 fInfo.index = index; 00330 if (jack_attach_shm_read(&fInfo)) { 00331 throw - 2; 00332 } 00333 GetShmAddress()->LockMemory(); 00334 } 00335 } 00336 00337 public: 00338 00339 JackShmReadPtr() 00340 { 00341 fInfo.index = -1; 00342 fInfo.ptr.attached_at = NULL; 00343 } 00344 00345 JackShmReadPtr(int index, const char* server_name) 00346 { 00347 Init(index, server_name); 00348 } 00349 00350 ~JackShmReadPtr() 00351 { 00352 if (fInfo.index >= 0) { 00353 jack_log("JackShmPtrRead::~JackShmPtrRead %ld", fInfo.index); 00354 GetShmAddress()->UnlockMemory(); 00355 jack_release_shm(&fInfo); 00356 fInfo.index = -1; 00357 } 00358 } 00359 00360 T* operator->() const 00361 { 00362 return (T*)fInfo.ptr.attached_at; 00363 } 00364 00365 operator T*() const 00366 { 00367 return (T*)fInfo.ptr.attached_at; 00368 } 00369 00370 JackShmReadPtr& operator=(int index) 00371 { 00372 Init(index); 00373 return *this; 00374 } 00375 00376 void SetShmIndex(int index, const char* server_name) 00377 { 00378 Init(index, server_name); 00379 } 00380 00381 int GetShmIndex() 00382 { 00383 return fInfo.index; 00384 } 00385 00386 T* GetShmAddress() 00387 { 00388 return (T*)fInfo.ptr.attached_at; 00389 } 00390 00391 }; 00392 00393 } // end of namespace 00394 00395 #endif