Jack2  1.9.8
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 std::bad_alloc();
00161                 }
00162                 fInfo.index = index;
00163                 if (jack_attach_lib_shm(&fInfo)) {
00164                     throw std::bad_alloc();
00165                 }
00166                 GetShmAddress()->LockMemory();
00167             }
00168         }
00169 
00170     public:
00171 
00172         JackShmReadWritePtr()
00173         {
00174             fInfo.index = -1;
00175             fInfo.ptr.attached_at = (char*)NULL;
00176         }
00177 
00178         JackShmReadWritePtr(int index, const char* server_name)
00179         {
00180             Init(index, server_name);
00181         }
00182 
00183         ~JackShmReadWritePtr()
00184         {
00185             if (fInfo.index >= 0) {
00186                 jack_log("JackShmReadWritePtr::~JackShmReadWritePtr %ld", fInfo.index);
00187                 GetShmAddress()->UnlockMemory();
00188                 jack_release_lib_shm(&fInfo);
00189                 fInfo.index = -1;
00190              }
00191         }
00192 
00193         T* operator->() const
00194         {
00195             return (T*)fInfo.ptr.attached_at;
00196         }
00197 
00198         operator T*() const
00199         {
00200             return (T*)fInfo.ptr.attached_at;
00201         }
00202 
00203         JackShmReadWritePtr& operator=(int index)
00204         {
00205             Init(index);
00206             return *this;
00207         }
00208 
00209         void SetShmIndex(int index, const char* server_name)
00210         {
00211             Init(index, server_name);
00212         }
00213 
00214         int GetShmIndex()
00215         {
00216             return fInfo.index;
00217         }
00218 
00219         T* GetShmAddress()
00220         {
00221             return (T*)fInfo.ptr.attached_at;
00222         }
00223 };
00224 
00229 template <class T>
00230 class JackShmReadWritePtr1
00231 {
00232 
00233     private:
00234 
00235         jack_shm_info_t fInfo;
00236 
00237         void Init(int index, const char* server_name = "default")
00238         {
00239             if (fInfo.index < 0 && index >= 0) {
00240                 jack_log("JackShmReadWritePtr1::Init %ld %ld", index, fInfo.index);
00241                 if (jack_initialize_shm(server_name) < 0) {
00242                     throw std::bad_alloc();
00243                 }
00244                 fInfo.index = index;
00245                 if (jack_attach_lib_shm(&fInfo)) {
00246                     throw std::bad_alloc();
00247                 }
00248                 GetShmAddress()->LockMemory();
00249                 /*
00250                 nobody else needs to access this shared memory any more, so
00251                 destroy it. because we have our own attachment to it, it won't
00252                 vanish till we exit (and release it).
00253                 */
00254                 jack_destroy_shm(&fInfo);
00255             }
00256         }
00257 
00258     public:
00259 
00260         JackShmReadWritePtr1()
00261         {
00262             fInfo.index = -1;
00263             fInfo.ptr.attached_at = NULL;
00264         }
00265 
00266         JackShmReadWritePtr1(int index, const char* server_name)
00267         {
00268             Init(index, server_name);
00269         }
00270 
00271         ~JackShmReadWritePtr1()
00272         {
00273             if (fInfo.index >= 0) {
00274                 jack_log("JackShmReadWritePtr1::~JackShmReadWritePtr1 %ld", fInfo.index);
00275                 GetShmAddress()->UnlockMemory();
00276                 jack_release_lib_shm(&fInfo);
00277                 fInfo.index = -1;
00278             }
00279         }
00280 
00281         T* operator->() const
00282         {
00283             return (T*)fInfo.ptr.attached_at;
00284         }
00285 
00286         operator T*() const
00287         {
00288             return (T*)fInfo.ptr.attached_at;
00289         }
00290 
00291         JackShmReadWritePtr1& operator=(int index)
00292         {
00293             Init(index);
00294             return *this;
00295         }
00296 
00297         void SetShmIndex(int index, const char* server_name)
00298         {
00299             Init(index, server_name);
00300         }
00301 
00302         int GetShmIndex()
00303         {
00304             return fInfo.index;
00305         }
00306 
00307         T* GetShmAddress()
00308         {
00309             return (T*)fInfo.ptr.attached_at;
00310         }
00311 };
00312 
00317 template <class T>
00318 class JackShmReadPtr
00319 {
00320 
00321     private:
00322 
00323         jack_shm_info_t fInfo;
00324 
00325         void Init(int index, const char* server_name = "default")
00326         {
00327             if (fInfo.index < 0 && index >= 0) {
00328                 jack_log("JackShmPtrRead::Init %ld %ld", index, fInfo.index);
00329                 if (jack_initialize_shm(server_name) < 0) {
00330                     throw std::bad_alloc();
00331                 }
00332                 fInfo.index = index;
00333                 if (jack_attach_lib_shm_read(&fInfo)) {
00334                     throw std::bad_alloc();
00335                 }
00336                 GetShmAddress()->LockMemory();
00337             }
00338         }
00339 
00340     public:
00341 
00342         JackShmReadPtr()
00343         {
00344             fInfo.index = -1;
00345             fInfo.ptr.attached_at = NULL;
00346         }
00347 
00348         JackShmReadPtr(int index, const char* server_name)
00349         {
00350             Init(index, server_name);
00351         }
00352 
00353         ~JackShmReadPtr()
00354         {
00355             if (fInfo.index >= 0) {
00356                 jack_log("JackShmPtrRead::~JackShmPtrRead %ld", fInfo.index);
00357                 GetShmAddress()->UnlockMemory();
00358                 jack_release_lib_shm(&fInfo);
00359                 fInfo.index = -1;
00360             }
00361         }
00362 
00363         T* operator->() const
00364         {
00365             return (T*)fInfo.ptr.attached_at;
00366         }
00367 
00368         operator T*() const
00369         {
00370             return (T*)fInfo.ptr.attached_at;
00371         }
00372 
00373         JackShmReadPtr& operator=(int index)
00374         {
00375             Init(index);
00376             return *this;
00377         }
00378 
00379         void SetShmIndex(int index, const char* server_name)
00380         {
00381             Init(index, server_name);
00382         }
00383 
00384         int GetShmIndex()
00385         {
00386             return fInfo.index;
00387         }
00388 
00389         T* GetShmAddress()
00390         {
00391             return (T*)fInfo.ptr.attached_at;
00392         }
00393 
00394 };
00395 
00396 } // end of namespace
00397 
00398 #endif