![]() |
Disk ARchive
2.5.2
Full featured and portable backup and archiving tool
|
00001 /*********************************************************************/ 00002 // dar - disk archive - a backup/restoration program 00003 // Copyright (C) 2002-2052 Denis Corbin 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 // 00019 // to contact the author : http://dar.linux.free.fr/email.html 00020 /*********************************************************************/ 00021 00025 00026 00027 00028 #ifndef ON_POOL_HPP 00029 #define ON_POOL_HPP 00030 00031 #include "../my_config.h" 00032 #include <vector> 00033 #include <new> 00034 #include "integers.hpp" 00035 #include "memory_pool.hpp" 00036 #include "mem_allocator.hpp" 00037 #include "cygwin_adapt.hpp" 00038 00039 00040 namespace libdar 00041 { 00042 00043 00046 00051 00052 class on_pool 00053 { 00054 public: 00055 #ifdef LIBDAR_SPECIAL_ALLOC 00056 00063 on_pool() { dynamic_init(); }; 00064 00069 on_pool(const on_pool & ref) { dynamic_init(); }; 00070 00075 const on_pool & operator = (const on_pool & ref) { return *this; }; 00076 00078 virtual ~on_pool() throw(Ebug) {}; 00079 #endif 00080 00084 void *operator new(size_t n_byte) { void *ret = alloc(n_byte, nullptr); if(ret == nullptr) throw std::bad_alloc(); return ret; }; 00085 00086 00090 void *operator new(size_t n_byte, const std::nothrow_t & nothrow_value) { return alloc(n_byte, nullptr); }; 00091 00092 00096 void *operator new[](size_t n_byte) { void *ret = alloc(n_byte, nullptr); if(ret == nullptr) throw std::bad_alloc(); return ret; }; 00097 00098 00102 void *operator new[](size_t n_byte, const std::nothrow_t & nothrow_value) { return alloc(n_byte, nullptr); }; 00103 00108 void *operator new(size_t n_byte, memory_pool *p) { return alloc(n_byte, p); }; 00109 00110 00115 void *operator new[] (size_t n_byte, memory_pool *p) { return alloc(n_byte, p); }; 00116 00117 00119 void operator delete(void *ptr, memory_pool *p) { dealloc(ptr); }; 00120 00121 00123 void operator delete[](void *ptr, memory_pool *p) { dealloc(ptr); }; 00124 00125 00127 void operator delete(void *ptr) { dealloc(ptr); }; 00128 00129 00131 void operator delete[](void *ptr) { dealloc(ptr); }; 00132 00133 protected: 00141 #ifdef LIBDAR_SPECIAL_ALLOC 00142 memory_pool *get_pool() const { return dynamic ? (((pool_ptr *)this) - 1)->reserve : nullptr; }; 00143 #else 00144 memory_pool *get_pool() const { return nullptr; }; 00145 #endif 00146 00147 template <class T> void meta_new(T * & ptr, size_t num) 00148 { 00149 #ifdef LIBDAR_SPECIAL_ALLOC 00150 size_t byte = num * sizeof(T); 00151 00152 if(get_pool() != nullptr) 00153 ptr = (T *)get_pool()->alloc(byte); 00154 else 00155 ptr = (T *)new (std::nothrow) char [byte]; 00156 #else 00157 ptr = new (std::nothrow) T[num]; 00158 #endif 00159 } 00160 00161 00162 00163 template <class T> void meta_delete(T * ptr) 00164 { 00165 #ifdef LIBDAR_SPECIAL_ALLOC 00166 if(get_pool() != nullptr) 00167 get_pool()->release(ptr); 00168 else 00169 delete [] (char *)(ptr); 00170 #else 00171 delete [] ptr; 00172 #endif 00173 } 00174 00175 private: 00176 #ifdef LIBDAR_SPECIAL_ALLOC 00177 00182 union pool_ptr 00183 { 00184 memory_pool *reserve; //< this is to be able to pass the pool object to the constructor if it requires dynamic memory allocation 00185 U_I alignment__i; //< to properly align the allocated memory block that follows 00186 U_32 alignment_32; //< to properly align the allocated memory block that follows 00187 U_64 alignment_64; //< to properly align the allocated memory block that follows 00188 }; 00189 00190 // this field is necessary to make distinction between object on the heap that have a pool_ptr header from those 00191 // created as local or temporary variable (on the stack). 00192 bool dynamic; 00193 00195 void dynamic_init() const { const_cast<on_pool *>(this)->dynamic = (alloc_not_constructed == this); alloc_not_constructed = nullptr; }; 00196 #endif 00197 00203 static void *alloc(size_t size, memory_pool *p); 00204 00209 static void dealloc(void *ptr); 00210 00211 #ifdef LIBDAR_SPECIAL_ALLOC 00212 #ifdef CYGWIN_BUILD 00213 static on_pool *alloc_not_constructed; 00214 // under cygwin the thread_local directive does not work but 00215 // as we build only command-line tools that are single threaded 00216 // program, it does not hurt using global static field here 00217 // well, as soon as another application than dar/dar_xform/... 00218 // relies on a cygwin build of libdar, this trick should be changed 00219 #else 00220 thread_local static on_pool * alloc_not_constructed; 00221 #endif 00222 #endif 00223 }; 00224 00226 00227 } // end of namespace 00228 00229 #endif