Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Malloc_T.cpp

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

Generated on Mon Jun 16 11:20:05 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002