Jack2 1.9.6

JackShmMem.h

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