Malloc_T.cpp

Go to the documentation of this file.
00001 // Malloc_T.cpp,v 4.101 2006/04/19 11:51:53 jwillemsen Exp
00002 
00003 #ifndef ACE_MALLOC_T_CPP
00004 #define ACE_MALLOC_T_CPP
00005 
00006 #include "ace/Malloc_T.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/Malloc_T.inl"
00014 #endif /* __ACE_INLINE__ */
00015 
00016 #include "ace/ACE.h"
00017 #include "ace/OS_NS_string.h"
00018 
00019 
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 template <class T, class ACE_LOCK>
00023 ACE_Cached_Allocator<T, ACE_LOCK>::ACE_Cached_Allocator (size_t n_chunks)
00024   : pool_ (0),
00025     free_list_ (ACE_PURE_FREE_LIST)
00026 {
00027   // To maintain alignment requirements, make sure that each element
00028   // inserted into the free list is aligned properly for the platform.
00029   // Since the memory is allocated as a char[], the compiler won't help.
00030   // To make sure enough room is allocated, round up the size so that
00031   // each element starts aligned.
00032   //
00033   // NOTE - this would probably be easier by defining pool_ as a pointer
00034   // to T and allocating an array of them (the compiler would probably
00035   // take care of the alignment for us), but then the ACE_NEW below would
00036   // require a default constructor on T - a requirement that is not in
00037   // previous versions of ACE
00038   size_t chunk_size = sizeof (T);
00039   chunk_size = ACE_MALLOC_ROUNDUP (chunk_size, ACE_MALLOC_ALIGN);
00040   ACE_NEW (this->pool_,
00041            char[n_chunks * chunk_size]);
00042 
00043   for (size_t c = 0;
00044        c < n_chunks;
00045        c++)
00046     {
00047       void* placement = this->pool_ + c * chunk_size;
00048       this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<T>);
00049     }
00050   // Put into free list using placement contructor, no real memory
00051   // allocation in the above <new>.
00052 }
00053 
00054 template <class T, class ACE_LOCK>
00055 ACE_Cached_Allocator<T, ACE_LOCK>::~ACE_Cached_Allocator (void)
00056 {
00057   delete [] this->pool_;
00058 }
00059 
00060 template <class T, class ACE_LOCK> void *
00061 ACE_Cached_Allocator<T, ACE_LOCK>::malloc (size_t nbytes)
00062 {
00063   // Check if size requested fits within pre-determined size.
00064   if (nbytes > sizeof (T))
00065     return 0;
00066 
00067   // addr() call is really not absolutely necessary because of the way
00068   // ACE_Cached_Mem_Pool_Node's internal structure arranged.
00069   return this->free_list_.remove ()->addr ();
00070 }
00071 
00072 template <class T, class ACE_LOCK> void *
00073 ACE_Cached_Allocator<T, ACE_LOCK>::calloc (size_t nbytes,
00074                                            char initial_value)
00075 {
00076   // Check if size requested fits within pre-determined size.
00077   if (nbytes > sizeof (T))
00078     return 0;
00079 
00080   // addr() call is really not absolutely necessary because of the way
00081   // ACE_Cached_Mem_Pool_Node's internal structure arranged.
00082   void *ptr = this->free_list_.remove ()->addr ();
00083   if (ptr != 0)
00084     ACE_OS::memset (ptr, initial_value, sizeof (T));
00085   return ptr;
00086 }
00087 
00088 template <class T, class ACE_LOCK> void *
00089 ACE_Cached_Allocator<T, ACE_LOCK>::calloc (size_t,
00090                                            size_t,
00091                                            char)
00092 {
00093   ACE_NOTSUP_RETURN (0);
00094 }
00095 
00096 template <class T, class ACE_LOCK> void
00097 ACE_Cached_Allocator<T, ACE_LOCK>::free (void * ptr)
00098 {
00099   if (ptr != 0)
00100     this->free_list_.add ((ACE_Cached_Mem_Pool_Node<T> *) ptr) ;
00101 }
00102 
00103 template <class ACE_LOCK>
00104 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::ACE_Dynamic_Cached_Allocator
00105   (size_t n_chunks, size_t chunk_size)
00106     : pool_ (0),
00107       free_list_ (ACE_PURE_FREE_LIST),
00108       chunk_size_(chunk_size)
00109 {
00110   chunk_size = ACE_MALLOC_ROUNDUP (chunk_size, ACE_MALLOC_ALIGN);
00111   ACE_NEW (this->pool_, char[n_chunks * chunk_size_]);
00112 
00113   for (size_t c = 0;
00114        c < n_chunks;
00115        c++)
00116     {
00117       void* placement = this->pool_ + c * chunk_size_;
00118 
00119       this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<char>);
00120     }
00121   // Put into free list using placement contructor, no real memory
00122   // allocation in the above <new>.
00123 }
00124 
00125 template <class ACE_LOCK>
00126 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::~ACE_Dynamic_Cached_Allocator (void)
00127 {
00128   delete [] this->pool_;
00129   this->pool_ = 0;
00130   chunk_size_ = 0;
00131 }
00132 
00133 template <class ACE_LOCK> void *
00134 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::malloc (size_t nbytes)
00135 {
00136   // Check if size requested fits within pre-determined size.
00137   if (nbytes > chunk_size_)
00138     return 0;
00139 
00140   // addr() call is really not absolutely necessary because of the way
00141   // ACE_Cached_Mem_Pool_Node's internal structure arranged.
00142   return this->free_list_.remove ()->addr ();
00143 }
00144 
00145 template <class ACE_LOCK> void *
00146 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::calloc (size_t nbytes,
00147                                                 char initial_value)
00148 {
00149   // Check if size requested fits within pre-determined size.
00150   if (nbytes > chunk_size_)
00151     return 0;
00152 
00153   // addr() call is really not absolutely necessary because of the way
00154   // ACE_Cached_Mem_Pool_Node's internal structure arranged.
00155   void *ptr = this->free_list_.remove ()->addr ();
00156   if (ptr != 0)
00157     ACE_OS::memset (ptr, initial_value, chunk_size_);
00158   return ptr;
00159 }
00160 
00161 template <class ACE_LOCK> void *
00162 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::calloc (size_t, size_t, char)
00163 {
00164   ACE_NOTSUP_RETURN (0);
00165 }
00166 
00167 template <class ACE_LOCK> void
00168 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::free (void * ptr)
00169 {
00170   if (ptr != 0)
00171     this->free_list_.add ((ACE_Cached_Mem_Pool_Node<char> *) ptr);
00172 }
00173 
00174 ACE_ALLOC_HOOK_DEFINE (ACE_Malloc_T)
00175 
00176 template <class MALLOC> void *
00177 ACE_Allocator_Adapter<MALLOC>::malloc (size_t nbytes)
00178 {
00179   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::malloc");
00180   return this->allocator_.malloc (nbytes);
00181 }
00182 
00183 template <class MALLOC> void *
00184 ACE_Allocator_Adapter<MALLOC>::calloc (size_t nbytes,
00185                                        char initial_value)
00186 {
00187   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::calloc");
00188   return this->allocator_.calloc (nbytes, initial_value);
00189 }
00190 
00191 template <class MALLOC> void *
00192 ACE_Allocator_Adapter<MALLOC>::calloc (size_t n_elem,
00193                                        size_t elem_size,
00194                                        char initial_value)
00195 {
00196   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::calloc");
00197   return this->allocator_.calloc (n_elem, elem_size, initial_value);
00198 }
00199 
00200 template <class MALLOC> MALLOC &
00201 ACE_Allocator_Adapter<MALLOC>::alloc (void)
00202 {
00203   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::allocator");
00204   return this->allocator_;
00205 }
00206 
00207 template <class MALLOC> void
00208 ACE_Allocator_Adapter<MALLOC>::free (void *ptr)
00209 {
00210   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::free");
00211   this->allocator_.free (ptr);
00212 }
00213 
00214 template <class MALLOC> int
00215 ACE_Allocator_Adapter<MALLOC>::remove (void)
00216 {
00217   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::remove");
00218   return this->allocator_.remove ();
00219 }
00220 
00221 template <class MALLOC> int
00222 ACE_Allocator_Adapter<MALLOC>::trybind (const char *name,
00223                                         void *&pointer)
00224 {
00225   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::trybind");
00226   return this->allocator_.trybind (name, pointer);
00227 }
00228 
00229 template <class MALLOC> int
00230 ACE_Allocator_Adapter<MALLOC>::bind (const char *name,
00231                                      void *pointer,
00232                                      int duplicates)
00233 {
00234   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::bind");
00235   return this->allocator_.bind (name, pointer, duplicates);
00236 }
00237 
00238 template <class MALLOC> int
00239 ACE_Allocator_Adapter<MALLOC>::find (const char *name,
00240                                      void *&pointer)
00241 {
00242   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::find");
00243   return this->allocator_.find (name, pointer);
00244 }
00245 
00246 template <class MALLOC> int
00247 ACE_Allocator_Adapter<MALLOC>::find (const char *name)
00248 {
00249   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::find");
00250   return this->allocator_.find (name);
00251 }
00252 
00253 template <class MALLOC> int
00254 ACE_Allocator_Adapter<MALLOC>::unbind (const char *name, void *&pointer)
00255 {
00256   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::unbind");
00257   return this->allocator_.unbind (name, pointer);
00258 }
00259 
00260 template <class MALLOC> int
00261 ACE_Allocator_Adapter<MALLOC>::unbind (const char *name)
00262 {
00263   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::unbind");
00264   return this->allocator_.unbind (name);
00265 }
00266 
00267 template <class MALLOC> int
00268 ACE_Allocator_Adapter<MALLOC>::sync (ssize_t len, int flags)
00269 {
00270   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::sync");
00271   return this->allocator_.sync (len, flags);
00272 }
00273 
00274 template <class MALLOC> int
00275 ACE_Allocator_Adapter<MALLOC>::sync (void *addr, size_t len, int flags)
00276 {
00277   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::sync");
00278   return this->allocator_.sync (addr, len, flags);
00279 }
00280 
00281 template <class MALLOC> int
00282 ACE_Allocator_Adapter<MALLOC>::protect (ssize_t len, int flags)
00283 {
00284   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::protect");
00285   return this->allocator_.protect (len, flags);
00286 }
00287 
00288 template <class MALLOC> int
00289 ACE_Allocator_Adapter<MALLOC>::protect (void *addr, size_t len, int flags)
00290 {
00291   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::protect");
00292   return this->allocator_.protect (addr, len, flags);
00293 }
00294 
00295 template <class MALLOC>
00296 ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (const char *pool_name)
00297   : allocator_ (ACE_TEXT_CHAR_TO_TCHAR (pool_name))
00298 {
00299   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
00300 }
00301 
00302 #if defined (ACE_HAS_WCHAR)
00303 template <class MALLOC>
00304 ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (const wchar_t *pool_name)
00305   : allocator_ (ACE_TEXT_WCHAR_TO_TCHAR (pool_name))
00306 {
00307   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
00308 }
00309 #endif /* ACE_HAS_WCHAR */
00310 
00311 template <class MALLOC>
00312 ACE_Allocator_Adapter<MALLOC>::~ACE_Allocator_Adapter (void)
00313 {
00314   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::~ACE_Allocator_Adapter");
00315 }
00316 
00317 #if defined (ACE_HAS_MALLOC_STATS)
00318 template <class MALLOC> void
00319 ACE_Allocator_Adapter<MALLOC>::print_stats (void) const
00320 {
00321   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::print_stats");
00322   this->allocator_.print_stats ();
00323 }
00324 #endif /* ACE_HAS_MALLOC_STATS */
00325 
00326 template <class MALLOC> void
00327 ACE_Allocator_Adapter<MALLOC>::dump (void) const
00328 {
00329 #if defined (ACE_HAS_DUMP)
00330   ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::dump");
00331   this->allocator_.dump ();
00332 #endif /* ACE_HAS_DUMP */
00333 }
00334 
00335 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
00336 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump (void) const
00337 {
00338 #if defined (ACE_HAS_DUMP)
00339   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
00340 
00341   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00342   this->memory_pool_.dump ();
00343   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("cb_ptr_ = %@\n"), this->cb_ptr_));
00344   this->cb_ptr_->dump ();
00345 #if defined (ACE_HAS_MALLOC_STATS)
00346   if (this->cb_ptr_ != 0)
00347     this->cb_ptr_->malloc_stats_.dump ();
00348 #endif /* ACE_HAS_MALLOC_STATS */
00349   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00350 #endif /* ACE_HAS_DUMP */
00351 }
00352 
00353 #if defined (ACE_HAS_MALLOC_STATS)
00354 
00355 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
00356 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::print_stats (void) const
00357 {
00358   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::print_stats");
00359   ACE_GUARD (ACE_LOCK, ace_mon, *this->lock_);
00360 
00361   if (this->cb_ptr_ == 0)
00362     return;
00363   this->cb_ptr_->malloc_stats_.dump ();
00364   ACE_DEBUG ((LM_DEBUG,
00365               ACE_LIB_TEXT ("(%P|%t) contents of freelist:\n")));
00366 
00367   for (MALLOC_HEADER *currp = this->cb_ptr_->freep_->next_block_;
00368        ;
00369        currp = currp->next_block_)
00370     {
00371       ACE_DEBUG ((LM_DEBUG,
00372                   ACE_LIB_TEXT ("(%P|%t) ptr = %@, MALLOC_HEADER units = %d, byte units = %d\n"),
00373                   currp,
00374                   currp->size_,
00375                   currp->size_ * sizeof (MALLOC_HEADER)));
00376       if (currp == this->cb_ptr_->freep_)
00377         break;
00378     }
00379 }
00380 #endif /* ACE_HAS_MALLOC_STATS */
00381 
00382 // Put <ptr> in the free list (locked version).
00383 
00384 template<ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
00385 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::free (void *ptr)
00386 {
00387   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::free");
00388   ACE_GUARD (ACE_LOCK, ace_mon, *this->lock_);
00389 
00390   this->shared_free (ptr);
00391 }
00392 
00393 // This function is called by the ACE_Malloc_T constructor to initialize
00394 // the memory pool.  The first time in it allocates room for the
00395 // control block (as well as a chunk of memory, depending on
00396 // rounding...).  Depending on the type of <MEM_POOL> (i.e., shared
00397 // vs. local) subsequent calls from other processes will only
00398 // initialize the control block pointer.
00399 
00400 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00401 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::open (void)
00402 {
00403   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::open");
00404   ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00405 
00406   size_t rounded_bytes = 0;
00407   int first_time = 0;
00408 
00409   this->cb_ptr_ = (ACE_CB *)
00410     this->memory_pool_.init_acquire (sizeof *this->cb_ptr_,
00411                                      rounded_bytes,
00412                                      first_time);
00413   if (this->cb_ptr_ == 0)
00414     ACE_ERROR_RETURN ((LM_ERROR,
00415                        ACE_LIB_TEXT ("(%P|%t) %p\n"),
00416                        ACE_LIB_TEXT ("init_acquire failed")),
00417                       -1);
00418   else if (first_time)
00419     {
00420       // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) first time in, control block = %@\n"), this->cb_ptr_));
00421 
00422       MALLOC_HEADER::init_ptr (&this->cb_ptr_->freep_,
00423                                &this->cb_ptr_->base_,
00424                                this->cb_ptr_);
00425 
00426       MALLOC_HEADER::init_ptr (&this->cb_ptr_->freep_->next_block_,
00427                                this->cb_ptr_->freep_,
00428                                this->cb_ptr_);
00429 
00430       NAME_NODE::init_ptr (&this->cb_ptr_->name_head_,
00431                            0,
00432                            this->cb_ptr_);
00433 
00434       this->cb_ptr_->freep_->size_ = 0;
00435       this->cb_ptr_->ref_counter_ = 1;
00436 
00437       if (rounded_bytes > (sizeof *this->cb_ptr_ + sizeof (MALLOC_HEADER)))
00438         {
00439           // If we've got any extra space at the end of the control
00440           // block, then skip past the dummy <MALLOC_HEADER> to
00441           // point at the first free block.
00442           MALLOC_HEADER *p = ((MALLOC_HEADER *) (this->cb_ptr_->freep_)) + 1;
00443 
00444           MALLOC_HEADER::init_ptr (&p->next_block_,
00445                                    0,
00446                                    this->cb_ptr_);
00447 
00448           // Why aC++ in 64-bit mode can't grok this, I have no
00449           // idea... but it ends up with an extra bit set which makes
00450           // size_ really big without this hack.
00451 #if defined (__hpux) && defined (__LP64__)
00452           size_t hpux11_hack = (rounded_bytes - sizeof *this->cb_ptr_)
00453                                / sizeof (MALLOC_HEADER);
00454           p->size_ = hpux11_hack;
00455 #else
00456           p->size_ = (rounded_bytes - sizeof *this->cb_ptr_)
00457             / sizeof (MALLOC_HEADER);
00458 #endif /* (__hpux) && defined (__LP64__) */
00459 
00460           ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nchunks_);
00461           ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
00462           ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
00463 
00464           // Insert the newly allocated chunk of memory into the free
00465           // list.  Add "1" to skip over the <MALLOC_HEADER> when
00466           // freeing the pointer.
00467           this->shared_free (p + 1);
00468         }
00469     }
00470   else
00471     ++this->cb_ptr_->ref_counter_;
00472   return 0;
00473 }
00474 
00475 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
00476 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name)
00477   : cb_ptr_ (0),
00478     memory_pool_ (pool_name),
00479     bad_flag_ (0)
00480 {
00481   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
00482   this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(pool_name);
00483   if (this->lock_ == 0)
00484     return;
00485 
00486   this->delete_lock_ = 1;
00487 
00488   this->bad_flag_ = this->open ();
00489 
00490   if (this->bad_flag_ == -1)
00491     ACE_ERROR ((LM_ERROR,
00492                 ACE_LIB_TEXT ("%p\n"),
00493                 ACE_LIB_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
00494 }
00495 
00496 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
00497 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
00498                                                               const ACE_TCHAR *lock_name,
00499                                                               const ACE_MEM_POOL_OPTIONS *options)
00500   : cb_ptr_ (0),
00501     memory_pool_ (pool_name, options),
00502     bad_flag_ (0)
00503 {
00504   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
00505   // Use pool_name for lock_name if lock_name not passed.
00506   const ACE_TCHAR *name = lock_name ? lock_name : pool_name;
00507   this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(name);
00508   if (this->lock_ == 0)
00509     return;
00510 
00511   this->delete_lock_ = 1;
00512 
00513   this->bad_flag_ = this->open ();
00514   if (this->bad_flag_ == -1)
00515     ACE_ERROR ((LM_ERROR,
00516                 ACE_LIB_TEXT ("%p\n"),
00517                 ACE_LIB_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
00518 }
00519 
00520 
00521 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
00522 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
00523                                                               const ACE_MEM_POOL_OPTIONS *options,
00524                                                               ACE_LOCK *lock)
00525   : cb_ptr_ (0),
00526     memory_pool_ (pool_name, options),
00527     lock_ (lock),
00528     delete_lock_ (0),
00529     bad_flag_ (0)
00530 {
00531   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
00532 
00533   if (lock == 0)
00534     {
00535       this->bad_flag_ = -1;
00536       errno = EINVAL;
00537       return;
00538     }
00539 
00540   this->bad_flag_ = this->open ();
00541   if (this->bad_flag_ == -1)
00542     ACE_ERROR ((LM_ERROR,
00543                 ACE_LIB_TEXT ("%p\n"),
00544                 ACE_LIB_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
00545 }
00546 
00547 #if !defined (ACE_HAS_TEMPLATE_TYPEDEFS)
00548 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
00549 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
00550                                                           const ACE_TCHAR *lock_name,
00551                                                           const void *options)
00552   : cb_ptr_ (0),
00553     memory_pool_ (pool_name,
00554                   (const ACE_MEM_POOL_OPTIONS *) options),
00555     bad_flag_ (0)
00556 {
00557   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
00558 
00559   this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(lock_name);
00560   if (this->lock_ == 0)
00561     return;
00562 
00563   this->delete_lock_ = 1;
00564   this->bad_flag_ = this->open ();
00565   if (this->bad_flag_ == -1)
00566     ACE_ERROR ((LM_ERROR,
00567                 ACE_LIB_TEXT ("%p\n"),
00568                 ACE_LIB_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
00569 }
00570 #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */
00571 
00572 
00573 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
00574 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_T (void)
00575 {
00576   ACE_TRACE ("ACE_Malloc_T<MEM_POOL>::~ACE_Malloc_T<MEM_POOL>");
00577   if (this->delete_lock_)
00578     {
00579       delete this->lock_;
00580       this->lock_ = 0;
00581     }
00582 }
00583 
00584 // Clean up the resources allocated by ACE_Malloc_T.
00585 
00586 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00587 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::remove (void)
00588 {
00589   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::remove");
00590   // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) destroying ACE_Malloc_T\n")));
00591 
00592 #if defined (ACE_HAS_MALLOC_STATS)
00593   this->print_stats ();
00594 #endif /* ACE_HAS_MALLOC_STATS */
00595 
00596   // Remove the ACE_LOCK.
00597   if (this->delete_lock_)
00598     this->lock_->remove ();
00599 
00600   // Give the memory pool a chance to release its resources.
00601   int const result = this->memory_pool_.release ();
00602 
00603   // Reset this->cb_ptr_ as it is no longer valid.
00604   // There's also no need to keep the reference counter as the
00605   // underlying memory pool has been destroyed.
00606   // Also notice that we are leaving the decision of removing
00607   // the pool to users so they can map to the same mmap file
00608   // again.
00609   this->cb_ptr_ = 0;
00610 
00611   return result;
00612 }
00613 
00614 // General-purpose memory allocator.  Assumes caller holds the locks.
00615 
00616 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
00617 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_malloc (size_t nbytes)
00618 {
00619 #if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00620   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_malloc");
00621 #endif /* !ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
00622 
00623   if (this->cb_ptr_ == 0)
00624     return 0;
00625 
00626   // Round up request to a multiple of the MALLOC_HEADER size.
00627   size_t const nunits =
00628     (nbytes + sizeof (MALLOC_HEADER) - 1) / sizeof (MALLOC_HEADER)
00629     + 1; // Add one for the <MALLOC_HEADER> itself.
00630 
00631   MALLOC_HEADER *prevp = 0;
00632   MALLOC_HEADER *currp = 0;
00633 
00634   ACE_SEH_TRY
00635     {
00636       // Begin the search starting at the place in the freelist where the
00637       // last block was found.
00638       prevp = this->cb_ptr_->freep_;
00639       currp = prevp->next_block_;
00640     }
00641 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00642   ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
00643     {
00644       currp = prevp->next_block_;
00645     }
00646 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
00647 
00648   // Search the freelist to locate a block of the appropriate size.
00649 
00650   while (1)
00651 
00652     // *Warning* Do not use "continue" within this while-loop.
00653 
00654     {
00655       ACE_SEH_TRY
00656         {
00657           if (currp->size_ >= nunits) // Big enough
00658             {
00659               ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
00660               if (currp->size_ == nunits)
00661                 // Exact size, just update the pointers.
00662                 prevp->next_block_ = currp->next_block_;
00663               else
00664                 {
00665                   // Remaining chunk is larger than requested block, so
00666                   // allocate at tail end.
00667                   ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
00668                   currp->size_ -= nunits;
00669                   currp += currp->size_;
00670                   MALLOC_HEADER::init_ptr (&currp->next_block_,
00671                                            0,
00672                                            this->cb_ptr_);
00673                   currp->size_ = nunits;
00674                 }
00675               this->cb_ptr_->freep_ = prevp;
00676 
00677               // Skip over the MALLOC_HEADER when returning pointer.
00678               return currp + 1;
00679             }
00680           else if (currp == this->cb_ptr_->freep_)
00681             {
00682               // We've wrapped around freelist without finding a
00683               // block.  Therefore, we need to ask the memory pool for
00684               // a new chunk of bytes.
00685 
00686               size_t chunk_bytes = 0;
00687 
00688               currp = (MALLOC_HEADER *)
00689                 this->memory_pool_.acquire (nunits * sizeof (MALLOC_HEADER),
00690                                             chunk_bytes);
00691               void *remap_addr = this->memory_pool_.base_addr ();
00692               if (remap_addr != 0)
00693                 this->cb_ptr_ = (ACE_CB *) remap_addr;
00694 
00695               if (currp != 0)
00696                 {
00697                   ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
00698                   ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nchunks_);
00699                   ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
00700 
00701                   MALLOC_HEADER::init_ptr (&currp->next_block_,
00702                                            0,
00703                                            this->cb_ptr_);
00704                   // Compute the chunk size in MALLOC_HEADER units.
00705                   currp->size_ = chunk_bytes / sizeof (MALLOC_HEADER);
00706 
00707                   // Insert the newly allocated chunk of memory into the
00708                   // free list.  Add "1" to skip over the
00709                   // <MALLOC_HEADER> when freeing the pointer since
00710                   // the first thing <free> does is decrement by this
00711                   // amount.
00712                   this->shared_free (currp + 1);
00713                   currp = this->cb_ptr_->freep_;
00714                 }
00715               else
00716                 return 0;
00717                 // Shouldn't do this here because of errors with the wchar ver
00718                 // This is because ACE_ERROR_RETURN converts the __FILE__ to
00719                 // wchar before printing out.  The compiler will complain
00720                 // about this since a destructor would present in a SEH block
00721                 //ACE_ERROR_RETURN ((LM_ERROR,
00722                 //                   ACE_LIB_TEXT ("(%P|%t) %p\n"),
00723                 //                   ACE_LIB_TEXT ("malloc")),
00724                 //                  0);
00725             }
00726           prevp = currp;
00727           currp = currp->next_block_;
00728         }
00729       ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
00730         {
00731         }
00732     }
00733   ACE_NOTREACHED (return 0;)
00734 }
00735 
00736 // General-purpose memory allocator.
00737 
00738 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
00739 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::malloc (size_t nbytes)
00740 {
00741   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::malloc");
00742   ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, 0);
00743 
00744   return this->shared_malloc (nbytes);
00745 }
00746 
00747 // General-purpose memory allocator.
00748 
00749 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
00750 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc (size_t nbytes,
00751                                                         char initial_value)
00752 {
00753   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
00754   void *ptr = this->malloc (nbytes);
00755 
00756   if (ptr != 0)
00757     ACE_OS::memset (ptr, initial_value, nbytes);
00758 
00759   return ptr;
00760 }
00761 
00762 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
00763 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc (size_t n_elem,
00764                                                         size_t elem_size,
00765                                                         char initial_value)
00766 {
00767   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
00768 
00769   return this->calloc (n_elem * elem_size, initial_value);
00770 }
00771 
00772 // Put block AP in the free list (must be called with locks held!)
00773 
00774 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
00775 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_free (void *ap)
00776 {
00777 #if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00778   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_free");
00779 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
00780 
00781   if (ap == 0 || this->cb_ptr_ == 0)
00782     return;
00783 
00784   // Adjust AP to point to the block MALLOC_HEADER
00785   MALLOC_HEADER *blockp = ((MALLOC_HEADER *) ap) - 1;
00786   MALLOC_HEADER *currp = this->cb_ptr_->freep_;
00787 
00788   // Search until we find the location where the blocks belongs.  Note
00789   // that addresses are kept in sorted order.
00790 
00791   ACE_SEH_TRY
00792     {
00793       for (;
00794            blockp <= currp
00795              || blockp >= (MALLOC_HEADER *) currp->next_block_;
00796            currp = currp->next_block_)
00797         {
00798           if (currp >= (MALLOC_HEADER *) currp->next_block_
00799               && (blockp > currp
00800                   || blockp < (MALLOC_HEADER *) currp->next_block_))
00801             // Freed block at the start or the end of the memory pool.
00802             break;
00803         }
00804 
00805       // Join to upper neighbor.
00806       if ((blockp + blockp->size_) == currp->next_block_)
00807         {
00808           ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.nblocks_);
00809           blockp->size_ += currp->next_block_->size_;
00810           blockp->next_block_ = currp->next_block_->next_block_;
00811         }
00812       else
00813         blockp->next_block_ = currp->next_block_;
00814 
00815       // Join to lower neighbor.
00816       if ((currp + currp->size_) == blockp)
00817         {
00818           ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.nblocks_);
00819           currp->size_ += blockp->size_;
00820           currp->next_block_ = blockp->next_block_;
00821         }
00822       else
00823         currp->next_block_ = blockp;
00824 
00825       ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.ninuse_);
00826       this->cb_ptr_->freep_ = currp;
00827     }
00828   ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
00829     {
00830     }
00831 }
00832 
00833 // No locks held here, caller must acquire/release lock.
00834 
00835 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void*
00836 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_find (const char *name)
00837 {
00838 #if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00839   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_find");
00840 #endif /* !ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
00841 
00842   if (this->cb_ptr_ == 0)
00843     return 0;
00844 
00845   ACE_SEH_TRY
00846     {
00847       for (NAME_NODE *node = this->cb_ptr_->name_head_;
00848            node != 0;
00849            node = node->next_)
00850         if (ACE_OS::strcmp (node->name (),
00851                             name) == 0)
00852           return node;
00853     }
00854   ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
00855     {
00856     }
00857   return 0;
00858 }
00859 
00860 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00861 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_bind (const char *name,
00862                                                              void *pointer)
00863 {
00864   if (this->cb_ptr_ == 0)
00865     return -1;
00866 
00867   // Combine the two allocations into one to avoid overhead...
00868   NAME_NODE *new_node = 0;
00869 
00870   ACE_ALLOCATOR_RETURN (new_node,
00871                         (NAME_NODE *)
00872                         this->shared_malloc (sizeof (NAME_NODE) +
00873                                              ACE_OS::strlen (name) + 1),
00874                         -1);
00875   char *name_ptr = (char *) (new_node + 1);
00876 
00877   // Use operator placement new to insert <new_node> at the head of
00878   // the linked list of <NAME_NODE>s.
00879   NAME_NODE *result =
00880     new (new_node) NAME_NODE (name,
00881                               name_ptr,
00882                               reinterpret_cast<char *> (pointer),
00883                               this->cb_ptr_->name_head_);
00884   this->cb_ptr_->name_head_ = result;
00885   return 0;
00886 }
00887 
00888 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00889 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::trybind (const char *name,
00890                                                          void *&pointer)
00891 {
00892   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::trybind");
00893   ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00894 
00895   NAME_NODE *node = (NAME_NODE *) this->shared_find (name);
00896 
00897   if (node == 0)
00898     // Didn't find it, so insert it.
00899     return this->shared_bind (name, pointer);
00900 
00901   // Found it, so return a copy of the current entry.
00902   pointer = (char *) node->pointer_;
00903   return 1;
00904 }
00905 
00906 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00907 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::bind (const char *name,
00908                                                       void *pointer,
00909                                                       int duplicates)
00910 {
00911   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::bind");
00912   ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00913 
00914   if (duplicates == 0 && this->shared_find (name) != 0)
00915     // If we're not allowing duplicates, then if the name is already
00916     // present, return 1.
00917     return 1;
00918 
00919   // If we get this far, either we're allowing duplicates or we didn't
00920   // find the name yet.
00921   return this->shared_bind (name, pointer);
00922 }
00923 
00924 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00925 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find (const char *name,
00926                                                     void *&pointer)
00927 {
00928   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find");
00929 
00930   ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00931 
00932   NAME_NODE *node = (NAME_NODE *) this->shared_find (name);
00933 
00934   if (node == 0)
00935     return -1;
00936 
00937   pointer = (char *) node->pointer_;
00938   return 0;
00939 }
00940 
00941 // Returns a count of the number of available chunks that can hold
00942 // <size> byte allocations.  Function can be used to determine if you
00943 // have reached a water mark. This implies a fixed amount of allocated
00944 // memory.
00945 //
00946 // @param size - the chunk size of that you would like a count of
00947 // @return function returns the number of chunks of the given size
00948 //          that would fit in the currently allocated memory
00949 
00950 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> ssize_t
00951 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::avail_chunks (size_t size) const
00952 {
00953   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::avail_chunks");
00954   ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00955 
00956   if (this->cb_ptr_ == 0)
00957     return -1;
00958 
00959   size_t count = 0;
00960   // Avoid dividing by 0...
00961   size = size == 0 ? 1 : size;
00962   MALLOC_HEADER *currp = this->cb_ptr_->freep_;
00963 
00964   // Calculate how many will fit in this block.
00965   do {
00966     size_t avail_size = currp->size_ == 0 ? 0 : currp->size_ - 1;
00967     if (avail_size * sizeof (MALLOC_HEADER) >= size)
00968       count += avail_size * sizeof (MALLOC_HEADER) / size;
00969     currp = currp->next_block_;
00970   }
00971   while (currp != this->cb_ptr_->freep_);
00972 
00973   return count;
00974 }
00975 
00976 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00977 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find (const char *name)
00978 {
00979   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find");
00980   ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00981 
00982   return this->shared_find (name) == 0 ? -1 : 0;
00983 }
00984 
00985 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
00986 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name, void *&pointer)
00987 {
00988   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind");
00989   ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
00990 
00991   if (this->cb_ptr_ == 0)
00992     return -1;
00993 
00994   NAME_NODE *prev = 0;
00995 
00996   for (NAME_NODE *curr = this->cb_ptr_->name_head_;
00997        curr != 0;
00998        curr = curr->next_)
00999     {
01000       if (ACE_OS::strcmp (curr->name (), name) == 0)
01001         {
01002           pointer = (char *) curr->pointer_;
01003 
01004           if (prev == 0)
01005             this->cb_ptr_->name_head_ = curr->next_;
01006           else
01007             prev->next_ = curr->next_;
01008 
01009           if (curr->next_)
01010             curr->next_->prev_ = prev;
01011 
01012           // This will free up both the node and the name due to our
01013           // clever trick in <bind>!
01014           this->shared_free (curr);
01015           return 0;
01016         }
01017       prev = curr;
01018     }
01019 
01020   // Didn't find it, so fail.
01021   return -1;
01022 }
01023 
01024 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01025 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name)
01026 {
01027   ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind");
01028   void *temp = 0;
01029   return this->unbind (name, temp);
01030 }
01031 
01032 /*****************************************************************************/
01033 
01034 template <class ACE_LOCK> ACE_LOCK *
01035 ACE_Malloc_Lock_Adapter_T<ACE_LOCK>::operator () (const ACE_TCHAR *name)
01036 {
01037   ACE_LOCK *p = 0;
01038   if (name == 0)
01039     ACE_NEW_RETURN (p, ACE_LOCK (name), 0);
01040   else
01041     ACE_NEW_RETURN (p, ACE_LOCK (ACE::basename (name,
01042                                                 ACE_DIRECTORY_SEPARATOR_CHAR)),
01043                     0);
01044   return p;
01045 }
01046 
01047 /*****************************************************************************/
01048 
01049 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
01050 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump (void) const
01051 {
01052 #if defined (ACE_HAS_DUMP)
01053   ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
01054 
01055   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01056   this->curr_->dump ();
01057   this->guard_.dump ();
01058   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("name_ = %s"), this->name_));
01059   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
01060   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01061 #endif /* ACE_HAS_DUMP */
01062 }
01063 
01064 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
01065 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_LIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc,
01066                                                                                       const char *name)
01067   : malloc_ (malloc),
01068     curr_ (0),
01069     guard_ (*malloc_.lock_),
01070     name_ (name != 0 ? ACE_OS::strdup (name) : 0)
01071 {
01072   ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_LIFO_Iterator_T");
01073   // Cheap trick to make code simple.
01074   // @@ Doug, this looks like trouble...
01075   NAME_NODE temp;
01076   this->curr_ = &temp;
01077   this->curr_->next_ = malloc_.cb_ptr_->name_head_;
01078 
01079   this->advance ();
01080 }
01081 
01082 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
01083 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_LIFO_Iterator_T (void)
01084 {
01085   ACE_OS::free ((void *) this->name_);
01086 }
01087 
01088 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01089 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry,
01090                                                                     const char *&name)
01091 {
01092   ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
01093 
01094   if (this->curr_ != 0)
01095     {
01096       next_entry = (char *) this->curr_->pointer_;
01097       name = this->curr_->name ();
01098       return 1;
01099     }
01100   else
01101     return 0;
01102 }
01103 
01104 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01105 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry)
01106 {
01107   ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
01108 
01109   if (this->curr_ != 0)
01110     {
01111       next_entry = this->curr_->pointer_;
01112       return 1;
01113     }
01114   else
01115     return 0;
01116 }
01117 
01118 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01119 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done (void) const
01120 {
01121   ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done");
01122 
01123   return this->curr_ == 0;
01124 }
01125 
01126 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01127 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance (void)
01128 {
01129   ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance");
01130 
01131   this->curr_ = this->curr_->next_;
01132 
01133   if (this->name_ == 0)
01134     return this->curr_ != 0;
01135 
01136   while (this->curr_ != 0
01137          && ACE_OS::strcmp (this->name_,
01138                             this->curr_->name ()) != 0)
01139     this->curr_ = this->curr_->next_;
01140 
01141   return this->curr_ != 0;
01142 }
01143 
01144 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
01145 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump (void) const
01146 {
01147 #if defined (ACE_HAS_DUMP)
01148   ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
01149 
01150   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
01151   this->curr_->dump ();
01152   this->guard_.dump ();
01153   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("name_ = %s"), this->name_));
01154   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
01155   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
01156 #endif /* ACE_HAS_DUMP */
01157 }
01158 
01159 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
01160 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_FIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc,
01161                                                                                       const char *name)
01162   : malloc_ (malloc),
01163     curr_ (0),
01164     guard_ (*malloc_.lock_),
01165     name_ (name != 0 ? ACE_OS::strdup (name) : 0)
01166 {
01167   ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_FIFO_Iterator");
01168   // Cheap trick to make code simple.
01169   // @@ Doug, this looks like trouble...
01170   NAME_NODE temp;
01171   this->curr_ = &temp;
01172   this->curr_->next_ = malloc_.cb_ptr_->name_head_;
01173   this->curr_->prev_ = 0;
01174 
01175   // Go to the first element that was inserted.
01176   this->start ();
01177 }
01178 
01179 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
01180 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_FIFO_Iterator_T (void)
01181 {
01182   ACE_OS::free ((void *) this->name_);
01183 }
01184 
01185 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01186 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry,
01187                                                                     const char *&name)
01188 {
01189   ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
01190 
01191   if (this->curr_ != 0)
01192     {
01193       next_entry = (char *) this->curr_->pointer_;
01194       name = this->curr_->name ();
01195       return 1;
01196     }
01197   else
01198     return 0;
01199 }
01200 
01201 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01202 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry)
01203 {
01204   ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
01205 
01206   if (this->curr_ != 0)
01207     {
01208       next_entry = this->curr_->pointer_;
01209       return 1;
01210     }
01211   else
01212     return 0;
01213 }
01214 
01215 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01216 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done (void) const
01217 {
01218   ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done");
01219 
01220   return this->curr_ == 0;
01221 }
01222 
01223 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01224 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance (void)
01225 {
01226   ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance");
01227 
01228   this->curr_ = this->curr_->prev_;
01229 
01230   if (this->name_ == 0)
01231     return this->curr_ != 0;
01232 
01233   while (this->curr_ != 0
01234          && ACE_OS::strcmp (this->name_,
01235                             this->curr_->name ()) != 0)
01236     this->curr_ = this->curr_->prev_;
01237 
01238   return this->curr_ != 0;
01239 }
01240 
01241 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
01242 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::start (void)
01243 {
01244   this->curr_ = this->curr_->next_;
01245   NAME_NODE *prev = 0;
01246 
01247   // Locate the element that was inserted first.
01248   // @@ We could optimize this by making the list a circular list or
01249   // storing an extra pointer.
01250   while (this->curr_ != 0)
01251     {
01252       prev = this->curr_;
01253       this->curr_ = this->curr_->next_;
01254     }
01255 
01256   this->curr_ = prev;
01257   return this->curr_ != 0;
01258 }
01259 
01260 ACE_END_VERSIONED_NAMESPACE_DECL
01261 
01262 #endif /* ACE_MALLOC_T_CPP */

Generated on Thu Nov 9 09:41:54 2006 for ACE by doxygen 1.3.6