JackShmMem.h

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

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1