Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Malloc_T.cpp
blob8f1467423601a2b8e4ad0376ff816e6938bb5e84
1 #ifndef ACE_MALLOC_T_CPP
2 #define ACE_MALLOC_T_CPP
4 #include "ace/Malloc_T.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
7 # pragma once
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #if !defined (__ACE_INLINE__)
11 #include "ace/Malloc_T.inl"
12 #endif /* __ACE_INLINE__ */
14 #include "ace/ACE.h"
15 #include "ace/OS_NS_string.h"
16 #include <cstring>
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 template <class T, class ACE_LOCK>
21 ACE_Cached_Allocator<T, ACE_LOCK>::ACE_Cached_Allocator (size_t n_chunks)
22 : pool_ (0),
23 free_list_ (ACE_PURE_FREE_LIST)
25 // To maintain alignment requirements, make sure that each element
26 // inserted into the free list is aligned properly for the platform.
27 // Since the memory is allocated as a char[], the compiler won't help.
28 // To make sure enough room is allocated, round up the size so that
29 // each element starts aligned.
31 // NOTE - this would probably be easier by defining pool_ as a pointer
32 // to T and allocating an array of them (the compiler would probably
33 // take care of the alignment for us), but then the ACE_NEW below would
34 // require a default constructor on T - a requirement that is not in
35 // previous versions of ACE
36 size_t chunk_size = sizeof (T);
37 chunk_size = ACE_MALLOC_ROUNDUP (chunk_size, ACE_MALLOC_ALIGN);
38 #if defined (ACE_HAS_ALLOC_HOOKS)
39 ACE_ALLOCATOR (this->pool_,
40 static_cast<char*>(ACE_Allocator::instance()->malloc(sizeof(char) * n_chunks * chunk_size)));
41 #else
42 ACE_NEW (this->pool_,
43 char[n_chunks * chunk_size]);
44 #endif /* ACE_HAS_ALLOC_HOOKS */
46 for (size_t c = 0;
47 c < n_chunks;
48 c++)
50 void* placement = this->pool_ + c * chunk_size;
51 this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<T>);
53 // Put into free list using placement constructor, no real memory
54 // allocation in the above <new>.
57 template <class T, class ACE_LOCK>
58 ACE_Cached_Allocator<T, ACE_LOCK>::~ACE_Cached_Allocator ()
60 #if defined (ACE_HAS_ALLOC_HOOKS)
61 ACE_Allocator::instance()->free (this->pool_);
62 #else
63 delete [] this->pool_;
64 #endif /* ACE_HAS_ALLOC_HOOKS */
67 ACE_ALLOC_HOOK_DEFINE_Tcc(ACE_Cached_Allocator)
69 template <class T, class ACE_LOCK> void *
70 ACE_Cached_Allocator<T, ACE_LOCK>::malloc (size_t nbytes)
72 // Check if size requested fits within pre-determined size.
73 if (nbytes > sizeof (T))
74 return 0;
76 ACE_Cached_Mem_Pool_Node<T> *allocated = this->free_list_.remove ();
77 return allocated == 0 ? 0 : allocated->addr();
80 template <class T, class ACE_LOCK> void *
81 ACE_Cached_Allocator<T, ACE_LOCK>::calloc (size_t nbytes,
82 char initial_value)
84 // Check if size requested fits within pre-determined size.
85 if (nbytes > sizeof (T))
86 return 0;
88 ACE_Cached_Mem_Pool_Node<T> *allocated = this->free_list_.remove ();
89 void *ptr = allocated == 0 ? 0 : allocated->addr();
90 if (ptr != 0)
91 ACE_OS::memset (ptr, initial_value, sizeof (T));
92 return ptr;
95 template <class T, class ACE_LOCK> void *
96 ACE_Cached_Allocator<T, ACE_LOCK>::calloc (size_t,
97 size_t,
98 char)
100 ACE_NOTSUP_RETURN (0);
103 template <class T, class ACE_LOCK> void
104 ACE_Cached_Allocator<T, ACE_LOCK>::free (void * ptr)
106 if (ptr != 0)
107 this->free_list_.add ((ACE_Cached_Mem_Pool_Node<T> *) ptr) ;
110 template <class ACE_LOCK>
111 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::ACE_Dynamic_Cached_Allocator
112 (size_t n_chunks, size_t chunk_size)
113 : pool_ (0),
114 free_list_ (ACE_PURE_FREE_LIST),
115 chunk_size_ (chunk_size)
117 ACE_ASSERT (chunk_size > 0);
118 chunk_size = ACE_MALLOC_ROUNDUP (chunk_size, ACE_MALLOC_ALIGN);
119 ACE_NEW (this->pool_, char[n_chunks * chunk_size]);
121 for (size_t c = 0;
122 c < n_chunks;
123 c++)
125 void *placement = this->pool_ + c * chunk_size;
127 this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<char>);
129 // Put into free list using placement constructor, no real memory
130 // allocation in the above <new>.
133 template <class ACE_LOCK>
134 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::~ACE_Dynamic_Cached_Allocator ()
136 delete [] this->pool_;
137 this->pool_ = 0;
138 chunk_size_ = 0;
141 template <class ACE_LOCK> void *
142 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::malloc (size_t nbytes)
144 // Check if size requested fits within pre-determined size.
145 if (nbytes > chunk_size_)
146 return 0;
148 ACE_Cached_Mem_Pool_Node<char> *allocated = this->free_list_.remove ();
149 return allocated == 0 ? 0 : allocated->addr();
152 template <class ACE_LOCK> void *
153 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::calloc (size_t nbytes,
154 char initial_value)
156 // Check if size requested fits within pre-determined size.
157 if (nbytes > chunk_size_)
158 return 0;
160 ACE_Cached_Mem_Pool_Node<char> *allocated = this->free_list_.remove ();
161 void *ptr = allocated == 0 ? 0 : allocated->addr();
162 if (ptr != 0)
163 ACE_OS::memset (ptr, initial_value, chunk_size_);
164 return ptr;
167 template <class ACE_LOCK> void *
168 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::calloc (size_t, size_t, char)
170 ACE_NOTSUP_RETURN (0);
173 template <class ACE_LOCK> void
174 ACE_Dynamic_Cached_Allocator<ACE_LOCK>::free (void * ptr)
176 if (ptr != 0)
177 this->free_list_.add ((ACE_Cached_Mem_Pool_Node<char> *) ptr);
180 ACE_ALLOC_HOOK_DEFINE_Tmcc (ACE_Malloc_T)
182 template <class MALLOC> void *
183 ACE_Allocator_Adapter<MALLOC>::malloc (size_t nbytes)
185 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::malloc");
186 return this->allocator_.malloc (nbytes);
189 template <class MALLOC> void *
190 ACE_Allocator_Adapter<MALLOC>::calloc (size_t nbytes,
191 char initial_value)
193 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::calloc");
194 return this->allocator_.calloc (nbytes, initial_value);
197 template <class MALLOC> void *
198 ACE_Allocator_Adapter<MALLOC>::calloc (size_t n_elem,
199 size_t elem_size,
200 char initial_value)
202 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::calloc");
203 return this->allocator_.calloc (n_elem, elem_size, initial_value);
206 template <class MALLOC> MALLOC &
207 ACE_Allocator_Adapter<MALLOC>::alloc ()
209 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::allocator");
210 return this->allocator_;
213 template <class MALLOC> void
214 ACE_Allocator_Adapter<MALLOC>::free (void *ptr)
216 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::free");
217 this->allocator_.free (ptr);
220 template <class MALLOC> int
221 ACE_Allocator_Adapter<MALLOC>::remove ()
223 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::remove");
224 return this->allocator_.remove ();
227 template <class MALLOC> int
228 ACE_Allocator_Adapter<MALLOC>::trybind (const char *name,
229 void *&pointer)
231 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::trybind");
232 return this->allocator_.trybind (name, pointer);
235 template <class MALLOC> int
236 ACE_Allocator_Adapter<MALLOC>::bind (const char *name,
237 void *pointer,
238 int duplicates)
240 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::bind");
241 return this->allocator_.bind (name, pointer, duplicates);
244 template <class MALLOC> int
245 ACE_Allocator_Adapter<MALLOC>::find (const char *name,
246 void *&pointer)
248 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::find");
249 return this->allocator_.find (name, pointer);
252 template <class MALLOC> int
253 ACE_Allocator_Adapter<MALLOC>::find (const char *name)
255 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::find");
256 return this->allocator_.find (name);
259 template <class MALLOC> int
260 ACE_Allocator_Adapter<MALLOC>::unbind (const char *name, void *&pointer)
262 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::unbind");
263 return this->allocator_.unbind (name, pointer);
266 template <class MALLOC> int
267 ACE_Allocator_Adapter<MALLOC>::unbind (const char *name)
269 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::unbind");
270 return this->allocator_.unbind (name);
273 template <class MALLOC> int
274 ACE_Allocator_Adapter<MALLOC>::sync (ssize_t len, int flags)
276 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::sync");
277 return this->allocator_.sync (len, flags);
280 template <class MALLOC> int
281 ACE_Allocator_Adapter<MALLOC>::sync (void *addr, size_t len, int flags)
283 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::sync");
284 return this->allocator_.sync (addr, len, flags);
287 template <class MALLOC> int
288 ACE_Allocator_Adapter<MALLOC>::protect (ssize_t len, int flags)
290 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::protect");
291 return this->allocator_.protect (len, flags);
294 template <class MALLOC> int
295 ACE_Allocator_Adapter<MALLOC>::protect (void *addr, size_t len, int flags)
297 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::protect");
298 return this->allocator_.protect (addr, len, flags);
301 template <class MALLOC>
302 ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (const char *pool_name)
303 : allocator_ (ACE_TEXT_CHAR_TO_TCHAR (pool_name))
305 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
308 template <class MALLOC>
309 ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (
310 const char *pool_name,
311 const char *lock_name,
312 MEMORY_POOL_OPTIONS options)
313 : allocator_ (ACE_TEXT_CHAR_TO_TCHAR (pool_name),
314 ACE_TEXT_CHAR_TO_TCHAR (lock_name),
315 options)
317 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
320 #if defined (ACE_HAS_WCHAR)
321 template <class MALLOC>
322 ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (const wchar_t *pool_name)
323 : allocator_ (ACE_TEXT_WCHAR_TO_TCHAR (pool_name))
325 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
328 template <class MALLOC>
329 ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (
330 const wchar_t *pool_name,
331 const wchar_t *lock_name,
332 MEMORY_POOL_OPTIONS options)
333 : allocator_ (ACE_TEXT_WCHAR_TO_TCHAR (pool_name),
334 ACE_TEXT_WCHAR_TO_TCHAR (lock_name),
335 options)
337 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
339 #endif /* ACE_HAS_WCHAR */
341 template <class MALLOC>
342 ACE_Allocator_Adapter<MALLOC>::~ACE_Allocator_Adapter ()
344 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::~ACE_Allocator_Adapter");
347 #if defined (ACE_HAS_MALLOC_STATS)
348 template <class MALLOC> void
349 ACE_Allocator_Adapter<MALLOC>::print_stats () const
351 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::print_stats");
352 this->allocator_.print_stats ();
354 #endif /* ACE_HAS_MALLOC_STATS */
356 template <class MALLOC> void
357 ACE_Allocator_Adapter<MALLOC>::dump () const
359 #if defined (ACE_HAS_DUMP)
360 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::dump");
361 this->allocator_.dump ();
362 #endif /* ACE_HAS_DUMP */
365 ACE_ALLOC_HOOK_DEFINE_Tt(ACE_Allocator_Adapter)
367 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
368 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump () const
370 #if defined (ACE_HAS_DUMP)
371 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
373 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
374 this->memory_pool_.dump ();
375 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("cb_ptr_ = %@\n"), this->cb_ptr_));
376 this->cb_ptr_->dump ();
377 #if defined (ACE_HAS_MALLOC_STATS)
378 if (this->cb_ptr_ != 0)
379 this->cb_ptr_->malloc_stats_.dump ();
380 #endif /* ACE_HAS_MALLOC_STATS */
381 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
382 #endif /* ACE_HAS_DUMP */
385 #if defined (ACE_HAS_MALLOC_STATS)
387 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
388 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::print_stats () const
390 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::print_stats");
391 ACE_GUARD (ACE_LOCK, ace_mon, *this->lock_);
393 if (this->cb_ptr_ == 0)
394 return;
395 this->cb_ptr_->malloc_stats_.dump ();
396 ACELIB_DEBUG ((LM_DEBUG,
397 ACE_TEXT ("(%P|%t) contents of freelist:\n")));
399 for (MALLOC_HEADER *currp = this->cb_ptr_->freep_->next_block_;
401 currp = currp->next_block_)
403 ACELIB_DEBUG ((LM_DEBUG,
404 ACE_TEXT ("(%P|%t) ptr = %@, MALLOC_HEADER units = %d, byte units = %d\n"),
405 currp,
406 currp->size_,
407 currp->size_ * sizeof (MALLOC_HEADER)));
408 if (currp == this->cb_ptr_->freep_)
409 break;
412 #endif /* ACE_HAS_MALLOC_STATS */
414 // Put <ptr> in the free list (locked version).
416 template<ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
417 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::free (void *ptr)
419 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::free");
420 ACE_GUARD (ACE_LOCK, ace_mon, *this->lock_);
422 this->shared_free (ptr);
425 // This function is called by the ACE_Malloc_T constructor to initialize
426 // the memory pool. The first time in it allocates room for the
427 // control block (as well as a chunk of memory, depending on
428 // rounding...). Depending on the type of <MEM_POOL> (i.e., shared
429 // vs. local) subsequent calls from other processes will only
430 // initialize the control block pointer.
431 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
432 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::open ()
434 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::open");
435 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
437 size_t rounded_bytes = 0;
438 int first_time = 0;
440 this->cb_ptr_ = (ACE_CB *)
441 this->memory_pool_.init_acquire (sizeof *this->cb_ptr_,
442 rounded_bytes,
443 first_time);
444 if (this->cb_ptr_ == 0)
445 ACELIB_ERROR_RETURN ((LM_ERROR,
446 ACE_TEXT ("(%P|%t) %p\n"),
447 ACE_TEXT ("init_acquire failed")),
448 -1);
449 else if (first_time)
451 // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) first time in, control block = %@\n"), this->cb_ptr_));
453 MALLOC_HEADER::init_ptr (&this->cb_ptr_->freep_,
454 &this->cb_ptr_->base_,
455 this->cb_ptr_);
457 MALLOC_HEADER::init_ptr (&this->cb_ptr_->freep_->next_block_,
458 this->cb_ptr_->freep_,
459 this->cb_ptr_);
461 NAME_NODE::init_ptr (&this->cb_ptr_->name_head_,
463 this->cb_ptr_);
465 this->cb_ptr_->freep_->size_ = 0;
466 this->cb_ptr_->ref_counter_ = 1;
468 if (rounded_bytes > (sizeof *this->cb_ptr_ + sizeof (MALLOC_HEADER)))
470 // If we've got any extra space at the end of the control
471 // block, then skip past the dummy <MALLOC_HEADER> to
472 // point at the first free block.
473 MALLOC_HEADER *p = ((MALLOC_HEADER *) (this->cb_ptr_->freep_)) + 1;
475 MALLOC_HEADER::init_ptr (&p->next_block_,
477 this->cb_ptr_);
479 p->size_ = (rounded_bytes - sizeof *this->cb_ptr_) / sizeof (MALLOC_HEADER);
481 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nchunks_);
482 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
483 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
485 // Insert the newly allocated chunk of memory into the free
486 // list. Add "1" to skip over the <MALLOC_HEADER> when
487 // freeing the pointer.
488 this->shared_free (p + 1);
491 else
492 ++this->cb_ptr_->ref_counter_;
493 return 0;
496 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
497 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name)
498 : cb_ptr_ (0),
499 memory_pool_ (pool_name),
500 bad_flag_ (0)
502 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
503 this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(pool_name);
504 if (this->lock_ != 0)
506 this->delete_lock_ = true;
508 this->bad_flag_ = this->open ();
510 if (this->bad_flag_ == -1)
511 ACELIB_ERROR ((LM_ERROR,
512 ACE_TEXT ("%p\n"),
513 ACE_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
517 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
518 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
519 const ACE_TCHAR *lock_name,
520 const ACE_MEM_POOL_OPTIONS *options)
521 : cb_ptr_ (0),
522 memory_pool_ (pool_name, options),
523 bad_flag_ (0)
525 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
526 // Use pool_name for lock_name if lock_name not passed.
527 const ACE_TCHAR *name = lock_name ? lock_name : pool_name;
528 this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(name);
529 if (this->lock_ != 0)
531 this->delete_lock_ = true;
533 this->bad_flag_ = this->open ();
534 if (this->bad_flag_ == -1)
535 ACELIB_ERROR ((LM_ERROR,
536 ACE_TEXT ("%p\n"),
537 ACE_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
542 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
543 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
544 const ACE_MEM_POOL_OPTIONS *options,
545 ACE_LOCK *lock)
546 : cb_ptr_ (0),
547 memory_pool_ (pool_name, options),
548 lock_ (lock),
549 delete_lock_ (false),
550 bad_flag_ (0)
552 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
554 if (lock == 0)
556 this->bad_flag_ = -1;
557 errno = EINVAL;
558 return;
561 this->bad_flag_ = this->open ();
562 if (this->bad_flag_ == -1)
563 ACELIB_ERROR ((LM_ERROR,
564 ACE_TEXT ("%p\n"),
565 ACE_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
568 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
569 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_T ()
571 ACE_TRACE ("ACE_Malloc_T<MEM_POOL>::~ACE_Malloc_T<MEM_POOL>");
572 if (this->delete_lock_)
574 delete this->lock_;
575 this->lock_ = 0;
579 // Clean up the resources allocated by ACE_Malloc_T.
580 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
581 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::remove ()
583 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::remove");
584 // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) destroying ACE_Malloc_T\n")));
586 #if defined (ACE_HAS_MALLOC_STATS)
587 this->print_stats ();
588 #endif /* ACE_HAS_MALLOC_STATS */
590 // Remove the ACE_LOCK.
591 if (this->delete_lock_)
592 this->lock_->remove ();
594 // Give the memory pool a chance to release its resources.
595 int const result = this->memory_pool_.release ();
597 // Reset this->cb_ptr_ as it is no longer valid.
598 // There's also no need to keep the reference counter as the
599 // underlying memory pool has been destroyed.
600 // Also notice that we are leaving the decision of removing
601 // the pool to users so they can map to the same mmap file
602 // again.
603 this->cb_ptr_ = nullptr;
605 return result;
608 // General-purpose memory allocator. Assumes caller holds the locks.
610 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
611 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_malloc (size_t nbytes)
613 #if !defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
614 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_malloc");
615 #endif /* !ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
617 if (this->cb_ptr_ == 0)
618 return 0;
620 // Round up request to a multiple of the MALLOC_HEADER size.
621 size_t const nunits =
622 (nbytes + sizeof (MALLOC_HEADER) - 1) / sizeof (MALLOC_HEADER)
623 + 1; // Add one for the <MALLOC_HEADER> itself.
625 MALLOC_HEADER *prevp = 0;
626 MALLOC_HEADER *currp = 0;
628 ACE_SEH_TRY
630 // Begin the search starting at the place in the freelist where the
631 // last block was found.
632 prevp = this->cb_ptr_->freep_;
633 currp = prevp->next_block_;
635 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
636 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
638 currp = prevp->next_block_;
640 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
642 // Search the freelist to locate a block of the appropriate size.
644 while (1)
646 // *Warning* Do not use "continue" within this while-loop.
649 ACE_SEH_TRY
651 if (currp->size_ >= nunits) // Big enough
653 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
654 if (currp->size_ == nunits)
655 // Exact size, just update the pointers.
656 prevp->next_block_ = currp->next_block_;
657 else
659 // Remaining chunk is larger than requested block, so
660 // allocate at tail end.
661 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
662 currp->size_ -= nunits;
663 currp += currp->size_;
664 MALLOC_HEADER::init_ptr (&currp->next_block_,
666 this->cb_ptr_);
667 currp->size_ = nunits;
669 this->cb_ptr_->freep_ = prevp;
671 // Skip over the MALLOC_HEADER when returning pointer.
672 return currp + 1;
674 else if (currp == static_cast<MALLOC_HEADER *> (this->cb_ptr_->freep_))
676 // We've wrapped around freelist without finding a
677 // block. Therefore, we need to ask the memory pool for
678 // a new chunk of bytes.
680 size_t chunk_bytes = 0;
682 currp = (MALLOC_HEADER *)
683 this->memory_pool_.acquire (nunits * sizeof (MALLOC_HEADER),
684 chunk_bytes);
685 void *remap_addr = this->memory_pool_.base_addr ();
686 if (remap_addr != 0)
687 this->cb_ptr_ = (ACE_CB *) remap_addr;
689 if (currp != 0)
691 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
692 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nchunks_);
693 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
695 MALLOC_HEADER::init_ptr (&currp->next_block_,
697 this->cb_ptr_);
698 // Compute the chunk size in MALLOC_HEADER units.
699 currp->size_ = chunk_bytes / sizeof (MALLOC_HEADER);
701 // Insert the newly allocated chunk of memory into the
702 // free list. Add "1" to skip over the
703 // <MALLOC_HEADER> when freeing the pointer since
704 // the first thing <free> does is decrement by this
705 // amount.
706 this->shared_free (currp + 1);
707 currp = this->cb_ptr_->freep_;
709 else
710 return 0;
711 // Shouldn't do this here because of errors with the wchar ver
712 // This is because ACELIB_ERROR_RETURN converts the __FILE__ to
713 // wchar before printing out. The compiler will complain
714 // about this since a destructor would present in a SEH block
715 //ACELIB_ERROR_RETURN ((LM_ERROR,
716 // ACE_TEXT ("(%P|%t) %p\n"),
717 // ACE_TEXT ("malloc")),
718 // 0);
720 prevp = currp;
721 currp = currp->next_block_;
723 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
727 ACE_NOTREACHED (return 0;)
730 // General-purpose memory allocator.
732 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
733 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::malloc (size_t nbytes)
735 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::malloc");
736 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, 0);
738 return this->shared_malloc (nbytes);
741 // General-purpose memory allocator.
743 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
744 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc (size_t nbytes,
745 char initial_value)
747 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
748 void *ptr = this->malloc (nbytes);
750 if (ptr != 0)
751 ACE_OS::memset (ptr, initial_value, nbytes);
753 return ptr;
756 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
757 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc (size_t n_elem,
758 size_t elem_size,
759 char initial_value)
761 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
763 return this->calloc (n_elem * elem_size, initial_value);
766 // Put block AP in the free list (must be called with locks held!)
768 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
769 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_free (void *ap)
771 #if !defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
772 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_free");
773 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
775 if (ap == 0 || this->cb_ptr_ == 0)
776 return;
778 // Adjust AP to point to the block MALLOC_HEADER
779 MALLOC_HEADER *blockp = ((MALLOC_HEADER *) ap) - 1;
780 MALLOC_HEADER *currp = this->cb_ptr_->freep_;
782 // Search until we find the location where the blocks belongs. Note
783 // that addresses are kept in sorted order.
784 ACE_SEH_TRY
786 for (;
787 blockp <= currp
788 || blockp >= (MALLOC_HEADER *) currp->next_block_;
789 currp = currp->next_block_)
791 if (currp >= (MALLOC_HEADER *) currp->next_block_
792 && (blockp > currp
793 || blockp < (MALLOC_HEADER *) currp->next_block_))
794 // Freed block at the start or the end of the memory pool.
795 break;
798 // Join to upper neighbor.
799 if (blockp + blockp->size_ == static_cast<MALLOC_HEADER *> (currp->next_block_))
801 ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.nblocks_);
802 blockp->size_ += currp->next_block_->size_;
803 blockp->next_block_ = currp->next_block_->next_block_;
805 else
806 blockp->next_block_ = currp->next_block_;
808 // Join to lower neighbor.
809 if ((currp + currp->size_) == blockp)
811 ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.nblocks_);
812 currp->size_ += blockp->size_;
813 currp->next_block_ = blockp->next_block_;
815 else
816 currp->next_block_ = blockp;
818 ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.ninuse_);
819 this->cb_ptr_->freep_ = currp;
821 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
826 // No locks held here, caller must acquire/release lock.
828 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void*
829 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_find (const char *name)
831 #if !defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
832 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_find");
833 #endif /* !ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
835 if (!this->cb_ptr_)
836 return nullptr;
838 ACE_SEH_TRY
840 for (NAME_NODE *node = this->cb_ptr_->name_head_;
841 node != 0;
842 node = node->next_)
843 if (std::strcmp (node->name (), name) == 0)
844 return node;
846 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
849 return 0;
852 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
853 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_bind (const char *name,
854 void *pointer)
856 if (!this->cb_ptr_)
857 return -1;
859 // Combine the two allocations into one to avoid overhead...
860 NAME_NODE *new_node = nullptr;
862 ACE_ALLOCATOR_RETURN (new_node,
863 (NAME_NODE *)
864 this->shared_malloc (sizeof (NAME_NODE) +
865 ACE_OS::strlen (name) + 1),
866 -1);
867 char *name_ptr = (char *) (new_node + 1);
869 // Use operator placement new to insert <new_node> at the head of
870 // the linked list of <NAME_NODE>s.
871 NAME_NODE *result =
872 new (new_node) NAME_NODE (name,
873 name_ptr,
874 reinterpret_cast<char *> (pointer),
875 this->cb_ptr_->name_head_);
876 this->cb_ptr_->name_head_ = result;
877 return 0;
880 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
881 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::trybind (const char *name,
882 void *&pointer)
884 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::trybind");
885 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
887 NAME_NODE *node = (NAME_NODE *) this->shared_find (name);
889 if (node == 0)
890 // Didn't find it, so insert it.
891 return this->shared_bind (name, pointer);
893 // Found it, so return a copy of the current entry.
894 pointer = (char *) node->pointer_;
895 return 1;
898 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
899 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::bind (const char *name,
900 void *pointer,
901 int duplicates)
903 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::bind");
904 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
906 if (duplicates == 0 && this->shared_find (name) != 0)
907 // If we're not allowing duplicates, then if the name is already
908 // present, return 1.
909 return 1;
911 // If we get this far, either we're allowing duplicates or we didn't
912 // find the name yet.
913 return this->shared_bind (name, pointer);
916 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
917 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find (const char *name,
918 void *&pointer)
920 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find");
922 ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
924 NAME_NODE *node = (NAME_NODE *) this->shared_find (name);
926 if (node == 0)
927 return -1;
929 pointer = (char *) node->pointer_;
930 return 0;
933 // Returns a count of the number of available chunks that can hold
934 // <size> byte allocations. Function can be used to determine if you
935 // have reached a water mark. This implies a fixed amount of allocated
936 // memory.
938 // @param size - the chunk size of that you would like a count of
939 // @return function returns the number of chunks of the given size
940 // that would fit in the currently allocated memory
942 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> ssize_t
943 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::avail_chunks (size_t size) const
945 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::avail_chunks");
946 ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
948 if (this->cb_ptr_ == 0)
949 return -1;
951 size_t count = 0;
952 // Avoid dividing by 0...
953 size = size == 0 ? 1 : size;
954 MALLOC_HEADER *currp = this->cb_ptr_->freep_;
956 // Calculate how many will fit in this block.
957 do {
958 size_t avail_size = currp->size_ == 0 ? 0 : currp->size_ - 1;
959 if (avail_size * sizeof (MALLOC_HEADER) >= size)
960 count += avail_size * sizeof (MALLOC_HEADER) / size;
961 currp = currp->next_block_;
963 while (currp != this->cb_ptr_->freep_);
965 return count;
968 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
969 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find (const char *name)
971 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find");
972 ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
974 return this->shared_find (name) == 0 ? -1 : 0;
977 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
978 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name, void *&pointer)
980 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind");
981 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
983 if (this->cb_ptr_ == 0)
984 return -1;
986 NAME_NODE *prev = 0;
988 for (NAME_NODE *curr = this->cb_ptr_->name_head_;
989 curr != 0;
990 curr = curr->next_)
992 if (std::strcmp (curr->name (), name) == 0)
994 pointer = (char *) curr->pointer_;
996 if (prev == 0)
997 this->cb_ptr_->name_head_ = curr->next_;
998 else
999 prev->next_ = curr->next_;
1001 if (curr->next_)
1002 curr->next_->prev_ = prev;
1004 // This will free up both the node and the name due to our
1005 // clever trick in <bind>!
1006 this->shared_free (curr);
1007 return 0;
1009 prev = curr;
1012 // Didn't find it, so fail.
1013 return -1;
1016 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1017 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name)
1019 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind");
1020 void *temp = 0;
1021 return this->unbind (name, temp);
1024 /*****************************************************************************/
1026 template <class ACE_LOCK> ACE_LOCK *
1027 ACE_Malloc_Lock_Adapter_T<ACE_LOCK>::operator () (const ACE_TCHAR *name)
1029 ACE_LOCK *p = 0;
1030 if (name == 0)
1031 ACE_NEW_RETURN (p, ACE_LOCK (name), 0);
1032 else
1033 ACE_NEW_RETURN (p, ACE_LOCK (ACE::basename (name,
1034 ACE_DIRECTORY_SEPARATOR_CHAR)),
1036 return p;
1039 /*****************************************************************************/
1041 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
1042 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump () const
1044 #if defined (ACE_HAS_DUMP)
1045 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
1047 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
1048 this->curr_->dump ();
1049 this->guard_.dump ();
1050 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("name_ = %C\n"), this->name_));
1051 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
1052 #endif /* ACE_HAS_DUMP */
1055 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1056 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,
1057 const char *name)
1058 : malloc_ (malloc),
1059 curr_ (0),
1060 guard_ (*malloc_.lock_),
1061 name_ (name != 0 ? ACE_OS::strdup (name) : 0)
1063 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_LIFO_Iterator_T");
1064 // Cheap trick to make code simple.
1065 // @@ Doug, this looks like trouble...
1066 NAME_NODE temp;
1067 this->curr_ = &temp;
1068 this->curr_->next_ = malloc_.cb_ptr_->name_head_;
1070 this->advance ();
1073 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1074 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_LIFO_Iterator_T ()
1076 ACE_OS::free ((void *) this->name_);
1079 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1080 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry,
1081 const char *&name)
1083 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1085 if (this->curr_ != 0)
1087 next_entry = (char *) this->curr_->pointer_;
1088 name = this->curr_->name ();
1089 return 1;
1091 else
1092 return 0;
1095 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1096 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry)
1098 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1100 if (this->curr_ != 0)
1102 next_entry = this->curr_->pointer_;
1103 return 1;
1105 else
1106 return 0;
1109 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1110 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done () const
1112 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done");
1114 return this->curr_ == 0;
1117 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1118 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance ()
1120 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance");
1122 this->curr_ = this->curr_->next_;
1124 if (this->name_ == 0)
1125 return this->curr_ != 0;
1127 while (this->curr_ != 0
1128 && std::strcmp (this->name_, this->curr_->name ()) != 0)
1129 this->curr_ = this->curr_->next_;
1131 return this->curr_ != 0;
1134 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
1135 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump () const
1137 #if defined (ACE_HAS_DUMP)
1138 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
1140 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
1141 this->curr_->dump ();
1142 this->guard_.dump ();
1143 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("name_ = %s\n"), this->name_));
1144 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
1145 #endif /* ACE_HAS_DUMP */
1148 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1149 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,
1150 const char *name)
1151 : malloc_ (malloc),
1152 curr_ (0),
1153 guard_ (*malloc_.lock_),
1154 name_ (name != 0 ? ACE_OS::strdup (name) : 0)
1156 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_FIFO_Iterator");
1157 // Cheap trick to make code simple.
1158 // @@ Doug, this looks like trouble...
1159 NAME_NODE temp;
1160 this->curr_ = &temp;
1161 this->curr_->next_ = malloc_.cb_ptr_->name_head_;
1162 this->curr_->prev_ = 0;
1164 // Go to the first element that was inserted.
1165 this->start ();
1168 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1169 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_FIFO_Iterator_T ()
1171 ACE_OS::free ((void *) this->name_);
1174 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1175 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry,
1176 const char *&name)
1178 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1180 if (this->curr_ != 0)
1182 next_entry = (char *) this->curr_->pointer_;
1183 name = this->curr_->name ();
1184 return 1;
1186 else
1187 return 0;
1190 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1191 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry)
1193 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1195 if (this->curr_ != 0)
1197 next_entry = this->curr_->pointer_;
1198 return 1;
1200 else
1201 return 0;
1204 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1205 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done () const
1207 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done");
1209 return this->curr_ == 0;
1212 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1213 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance ()
1215 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance");
1217 this->curr_ = this->curr_->prev_;
1219 if (this->name_ == 0)
1220 return this->curr_ != 0;
1222 while (this->curr_ != 0
1223 && std::strcmp (this->name_, this->curr_->name ()) != 0)
1224 this->curr_ = this->curr_->prev_;
1226 return this->curr_ != 0;
1229 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1230 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::start ()
1232 this->curr_ = this->curr_->next_;
1233 NAME_NODE *prev = 0;
1235 // Locate the element that was inserted first.
1236 // @@ We could optimize this by making the list a circular list or
1237 // storing an extra pointer.
1238 while (this->curr_ != 0)
1240 prev = this->curr_;
1241 this->curr_ = this->curr_->next_;
1244 this->curr_ = prev;
1245 return this->curr_ != 0;
1248 ACE_END_VERSIONED_NAMESPACE_DECL
1250 #endif /* ACE_MALLOC_T_CPP */