GitHub Actions: Try MSVC builds with /std:c++17 and 20
[ACE_TAO.git] / ACE / ace / Malloc_T.cpp
blob0f966f99c8f648940eafc6fb2a9b064fbee4f339
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"
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 (void)
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 (void)
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 (void)
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 (void)
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 (void)
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 (void) 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 (void) 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 (void) 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 (void) 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.
432 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
433 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::open (void)
435 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::open");
436 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
438 size_t rounded_bytes = 0;
439 int first_time = 0;
441 this->cb_ptr_ = (ACE_CB *)
442 this->memory_pool_.init_acquire (sizeof *this->cb_ptr_,
443 rounded_bytes,
444 first_time);
445 if (this->cb_ptr_ == 0)
446 ACELIB_ERROR_RETURN ((LM_ERROR,
447 ACE_TEXT ("(%P|%t) %p\n"),
448 ACE_TEXT ("init_acquire failed")),
449 -1);
450 else if (first_time)
452 // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) first time in, control block = %@\n"), this->cb_ptr_));
454 MALLOC_HEADER::init_ptr (&this->cb_ptr_->freep_,
455 &this->cb_ptr_->base_,
456 this->cb_ptr_);
458 MALLOC_HEADER::init_ptr (&this->cb_ptr_->freep_->next_block_,
459 this->cb_ptr_->freep_,
460 this->cb_ptr_);
462 NAME_NODE::init_ptr (&this->cb_ptr_->name_head_,
464 this->cb_ptr_);
466 this->cb_ptr_->freep_->size_ = 0;
467 this->cb_ptr_->ref_counter_ = 1;
469 if (rounded_bytes > (sizeof *this->cb_ptr_ + sizeof (MALLOC_HEADER)))
471 // If we've got any extra space at the end of the control
472 // block, then skip past the dummy <MALLOC_HEADER> to
473 // point at the first free block.
474 MALLOC_HEADER *p = ((MALLOC_HEADER *) (this->cb_ptr_->freep_)) + 1;
476 MALLOC_HEADER::init_ptr (&p->next_block_,
478 this->cb_ptr_);
480 // Why aC++ in 64-bit mode can't grok this, I have no
481 // idea... but it ends up with an extra bit set which makes
482 // size_ really big without this hack.
483 #if defined (__hpux) && defined (__LP64__)
484 size_t hpux11_hack = (rounded_bytes - sizeof *this->cb_ptr_)
485 / sizeof (MALLOC_HEADER);
486 p->size_ = hpux11_hack;
487 #else
488 p->size_ = (rounded_bytes - sizeof *this->cb_ptr_)
489 / sizeof (MALLOC_HEADER);
490 #endif /* (__hpux) && defined (__LP64__) */
492 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nchunks_);
493 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
494 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
496 // Insert the newly allocated chunk of memory into the free
497 // list. Add "1" to skip over the <MALLOC_HEADER> when
498 // freeing the pointer.
499 this->shared_free (p + 1);
502 else
503 ++this->cb_ptr_->ref_counter_;
504 return 0;
507 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
508 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name)
509 : cb_ptr_ (0),
510 memory_pool_ (pool_name),
511 bad_flag_ (0)
513 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
514 this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(pool_name);
515 if (this->lock_ != 0)
517 this->delete_lock_ = true;
519 this->bad_flag_ = this->open ();
521 if (this->bad_flag_ == -1)
522 ACELIB_ERROR ((LM_ERROR,
523 ACE_TEXT ("%p\n"),
524 ACE_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
528 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
529 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
530 const ACE_TCHAR *lock_name,
531 const ACE_MEM_POOL_OPTIONS *options)
532 : cb_ptr_ (0),
533 memory_pool_ (pool_name, options),
534 bad_flag_ (0)
536 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
537 // Use pool_name for lock_name if lock_name not passed.
538 const ACE_TCHAR *name = lock_name ? lock_name : pool_name;
539 this->lock_ = ACE_Malloc_Lock_Adapter_T<ACE_LOCK> ()(name);
540 if (this->lock_ != 0)
542 this->delete_lock_ = true;
544 this->bad_flag_ = this->open ();
545 if (this->bad_flag_ == -1)
546 ACELIB_ERROR ((LM_ERROR,
547 ACE_TEXT ("%p\n"),
548 ACE_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
553 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
554 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T (const ACE_TCHAR *pool_name,
555 const ACE_MEM_POOL_OPTIONS *options,
556 ACE_LOCK *lock)
557 : cb_ptr_ (0),
558 memory_pool_ (pool_name, options),
559 lock_ (lock),
560 delete_lock_ (false),
561 bad_flag_ (0)
563 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
565 if (lock == 0)
567 this->bad_flag_ = -1;
568 errno = EINVAL;
569 return;
572 this->bad_flag_ = this->open ();
573 if (this->bad_flag_ == -1)
574 ACELIB_ERROR ((LM_ERROR,
575 ACE_TEXT ("%p\n"),
576 ACE_TEXT ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T")));
579 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
580 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_T (void)
582 ACE_TRACE ("ACE_Malloc_T<MEM_POOL>::~ACE_Malloc_T<MEM_POOL>");
583 if (this->delete_lock_)
585 delete this->lock_;
586 this->lock_ = 0;
590 // Clean up the resources allocated by ACE_Malloc_T.
592 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
593 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::remove (void)
595 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::remove");
596 // ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) destroying ACE_Malloc_T\n")));
598 #if defined (ACE_HAS_MALLOC_STATS)
599 this->print_stats ();
600 #endif /* ACE_HAS_MALLOC_STATS */
602 // Remove the ACE_LOCK.
603 if (this->delete_lock_)
604 this->lock_->remove ();
606 // Give the memory pool a chance to release its resources.
607 int const result = this->memory_pool_.release ();
609 // Reset this->cb_ptr_ as it is no longer valid.
610 // There's also no need to keep the reference counter as the
611 // underlying memory pool has been destroyed.
612 // Also notice that we are leaving the decision of removing
613 // the pool to users so they can map to the same mmap file
614 // again.
615 this->cb_ptr_ = 0;
617 return result;
620 // General-purpose memory allocator. Assumes caller holds the locks.
622 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
623 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_malloc (size_t nbytes)
625 #if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
626 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_malloc");
627 #endif /* !ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
629 if (this->cb_ptr_ == 0)
630 return 0;
632 // Round up request to a multiple of the MALLOC_HEADER size.
633 size_t const nunits =
634 (nbytes + sizeof (MALLOC_HEADER) - 1) / sizeof (MALLOC_HEADER)
635 + 1; // Add one for the <MALLOC_HEADER> itself.
637 MALLOC_HEADER *prevp = 0;
638 MALLOC_HEADER *currp = 0;
640 ACE_SEH_TRY
642 // Begin the search starting at the place in the freelist where the
643 // last block was found.
644 prevp = this->cb_ptr_->freep_;
645 currp = prevp->next_block_;
647 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
648 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
650 currp = prevp->next_block_;
652 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
654 // Search the freelist to locate a block of the appropriate size.
656 while (1)
658 // *Warning* Do not use "continue" within this while-loop.
661 ACE_SEH_TRY
663 if (currp->size_ >= nunits) // Big enough
665 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
666 if (currp->size_ == nunits)
667 // Exact size, just update the pointers.
668 prevp->next_block_ = currp->next_block_;
669 else
671 // Remaining chunk is larger than requested block, so
672 // allocate at tail end.
673 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
674 currp->size_ -= nunits;
675 currp += currp->size_;
676 MALLOC_HEADER::init_ptr (&currp->next_block_,
678 this->cb_ptr_);
679 currp->size_ = nunits;
681 this->cb_ptr_->freep_ = prevp;
683 // Skip over the MALLOC_HEADER when returning pointer.
684 return currp + 1;
686 else if (currp == this->cb_ptr_->freep_)
688 // We've wrapped around freelist without finding a
689 // block. Therefore, we need to ask the memory pool for
690 // a new chunk of bytes.
692 size_t chunk_bytes = 0;
694 currp = (MALLOC_HEADER *)
695 this->memory_pool_.acquire (nunits * sizeof (MALLOC_HEADER),
696 chunk_bytes);
697 void *remap_addr = this->memory_pool_.base_addr ();
698 if (remap_addr != 0)
699 this->cb_ptr_ = (ACE_CB *) remap_addr;
701 if (currp != 0)
703 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nblocks_);
704 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.nchunks_);
705 ACE_MALLOC_STATS (++this->cb_ptr_->malloc_stats_.ninuse_);
707 MALLOC_HEADER::init_ptr (&currp->next_block_,
709 this->cb_ptr_);
710 // Compute the chunk size in MALLOC_HEADER units.
711 currp->size_ = chunk_bytes / sizeof (MALLOC_HEADER);
713 // Insert the newly allocated chunk of memory into the
714 // free list. Add "1" to skip over the
715 // <MALLOC_HEADER> when freeing the pointer since
716 // the first thing <free> does is decrement by this
717 // amount.
718 this->shared_free (currp + 1);
719 currp = this->cb_ptr_->freep_;
721 else
722 return 0;
723 // Shouldn't do this here because of errors with the wchar ver
724 // This is because ACELIB_ERROR_RETURN converts the __FILE__ to
725 // wchar before printing out. The compiler will complain
726 // about this since a destructor would present in a SEH block
727 //ACELIB_ERROR_RETURN ((LM_ERROR,
728 // ACE_TEXT ("(%P|%t) %p\n"),
729 // ACE_TEXT ("malloc")),
730 // 0);
732 prevp = currp;
733 currp = currp->next_block_;
735 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
739 ACE_NOTREACHED (return 0;)
742 // General-purpose memory allocator.
744 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
745 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::malloc (size_t nbytes)
747 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::malloc");
748 ACE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, 0);
750 return this->shared_malloc (nbytes);
753 // General-purpose memory allocator.
755 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void *
756 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc (size_t nbytes,
757 char initial_value)
759 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
760 void *ptr = this->malloc (nbytes);
762 if (ptr != 0)
763 ACE_OS::memset (ptr, initial_value, nbytes);
765 return ptr;
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>::calloc (size_t n_elem,
770 size_t elem_size,
771 char initial_value)
773 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
775 return this->calloc (n_elem * elem_size, initial_value);
778 // Put block AP in the free list (must be called with locks held!)
780 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
781 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_free (void *ap)
783 #if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
784 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_free");
785 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
787 if (ap == 0 || this->cb_ptr_ == 0)
788 return;
790 // Adjust AP to point to the block MALLOC_HEADER
791 MALLOC_HEADER *blockp = ((MALLOC_HEADER *) ap) - 1;
792 MALLOC_HEADER *currp = this->cb_ptr_->freep_;
794 // Search until we find the location where the blocks belongs. Note
795 // that addresses are kept in sorted order.
797 ACE_SEH_TRY
799 for (;
800 blockp <= currp
801 || blockp >= (MALLOC_HEADER *) currp->next_block_;
802 currp = currp->next_block_)
804 if (currp >= (MALLOC_HEADER *) currp->next_block_
805 && (blockp > currp
806 || blockp < (MALLOC_HEADER *) currp->next_block_))
807 // Freed block at the start or the end of the memory pool.
808 break;
811 // Join to upper neighbor.
812 if ((blockp + blockp->size_) == currp->next_block_)
814 ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.nblocks_);
815 blockp->size_ += currp->next_block_->size_;
816 blockp->next_block_ = currp->next_block_->next_block_;
818 else
819 blockp->next_block_ = currp->next_block_;
821 // Join to lower neighbor.
822 if ((currp + currp->size_) == blockp)
824 ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.nblocks_);
825 currp->size_ += blockp->size_;
826 currp->next_block_ = blockp->next_block_;
828 else
829 currp->next_block_ = blockp;
831 ACE_MALLOC_STATS (--this->cb_ptr_->malloc_stats_.ninuse_);
832 this->cb_ptr_->freep_ = currp;
834 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
839 // No locks held here, caller must acquire/release lock.
841 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void*
842 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_find (const char *name)
844 #if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
845 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_find");
846 #endif /* !ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
848 if (this->cb_ptr_ == 0)
849 return 0;
851 ACE_SEH_TRY
853 for (NAME_NODE *node = this->cb_ptr_->name_head_;
854 node != 0;
855 node = node->next_)
856 if (ACE_OS::strcmp (node->name (),
857 name) == 0)
858 return node;
860 ACE_SEH_EXCEPT (this->memory_pool_.seh_selector (GetExceptionInformation ()))
863 return 0;
866 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
867 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::shared_bind (const char *name,
868 void *pointer)
870 if (this->cb_ptr_ == 0)
871 return -1;
873 // Combine the two allocations into one to avoid overhead...
874 NAME_NODE *new_node = 0;
876 ACE_ALLOCATOR_RETURN (new_node,
877 (NAME_NODE *)
878 this->shared_malloc (sizeof (NAME_NODE) +
879 ACE_OS::strlen (name) + 1),
880 -1);
881 char *name_ptr = (char *) (new_node + 1);
883 // Use operator placement new to insert <new_node> at the head of
884 // the linked list of <NAME_NODE>s.
885 NAME_NODE *result =
886 new (new_node) NAME_NODE (name,
887 name_ptr,
888 reinterpret_cast<char *> (pointer),
889 this->cb_ptr_->name_head_);
890 this->cb_ptr_->name_head_ = result;
891 return 0;
894 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
895 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::trybind (const char *name,
896 void *&pointer)
898 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::trybind");
899 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
901 NAME_NODE *node = (NAME_NODE *) this->shared_find (name);
903 if (node == 0)
904 // Didn't find it, so insert it.
905 return this->shared_bind (name, pointer);
907 // Found it, so return a copy of the current entry.
908 pointer = (char *) node->pointer_;
909 return 1;
912 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
913 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::bind (const char *name,
914 void *pointer,
915 int duplicates)
917 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::bind");
918 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
920 if (duplicates == 0 && this->shared_find (name) != 0)
921 // If we're not allowing duplicates, then if the name is already
922 // present, return 1.
923 return 1;
925 // If we get this far, either we're allowing duplicates or we didn't
926 // find the name yet.
927 return this->shared_bind (name, pointer);
930 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
931 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find (const char *name,
932 void *&pointer)
934 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find");
936 ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
938 NAME_NODE *node = (NAME_NODE *) this->shared_find (name);
940 if (node == 0)
941 return -1;
943 pointer = (char *) node->pointer_;
944 return 0;
947 // Returns a count of the number of available chunks that can hold
948 // <size> byte allocations. Function can be used to determine if you
949 // have reached a water mark. This implies a fixed amount of allocated
950 // memory.
952 // @param size - the chunk size of that you would like a count of
953 // @return function returns the number of chunks of the given size
954 // that would fit in the currently allocated memory
956 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> ssize_t
957 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::avail_chunks (size_t size) const
959 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::avail_chunks");
960 ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
962 if (this->cb_ptr_ == 0)
963 return -1;
965 size_t count = 0;
966 // Avoid dividing by 0...
967 size = size == 0 ? 1 : size;
968 MALLOC_HEADER *currp = this->cb_ptr_->freep_;
970 // Calculate how many will fit in this block.
971 do {
972 size_t avail_size = currp->size_ == 0 ? 0 : currp->size_ - 1;
973 if (avail_size * sizeof (MALLOC_HEADER) >= size)
974 count += avail_size * sizeof (MALLOC_HEADER) / size;
975 currp = currp->next_block_;
977 while (currp != this->cb_ptr_->freep_);
979 return count;
982 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
983 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find (const char *name)
985 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::find");
986 ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
988 return this->shared_find (name) == 0 ? -1 : 0;
991 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
992 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name, void *&pointer)
994 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind");
995 ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, *this->lock_, -1);
997 if (this->cb_ptr_ == 0)
998 return -1;
1000 NAME_NODE *prev = 0;
1002 for (NAME_NODE *curr = this->cb_ptr_->name_head_;
1003 curr != 0;
1004 curr = curr->next_)
1006 if (ACE_OS::strcmp (curr->name (), name) == 0)
1008 pointer = (char *) curr->pointer_;
1010 if (prev == 0)
1011 this->cb_ptr_->name_head_ = curr->next_;
1012 else
1013 prev->next_ = curr->next_;
1015 if (curr->next_)
1016 curr->next_->prev_ = prev;
1018 // This will free up both the node and the name due to our
1019 // clever trick in <bind>!
1020 this->shared_free (curr);
1021 return 0;
1023 prev = curr;
1026 // Didn't find it, so fail.
1027 return -1;
1030 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1031 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name)
1033 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind");
1034 void *temp = 0;
1035 return this->unbind (name, temp);
1038 /*****************************************************************************/
1040 template <class ACE_LOCK> ACE_LOCK *
1041 ACE_Malloc_Lock_Adapter_T<ACE_LOCK>::operator () (const ACE_TCHAR *name)
1043 ACE_LOCK *p = 0;
1044 if (name == 0)
1045 ACE_NEW_RETURN (p, ACE_LOCK (name), 0);
1046 else
1047 ACE_NEW_RETURN (p, ACE_LOCK (ACE::basename (name,
1048 ACE_DIRECTORY_SEPARATOR_CHAR)),
1050 return p;
1053 /*****************************************************************************/
1055 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
1056 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump (void) const
1058 #if defined (ACE_HAS_DUMP)
1059 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
1061 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
1062 this->curr_->dump ();
1063 this->guard_.dump ();
1064 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("name_ = %C\n"), this->name_));
1065 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
1066 #endif /* ACE_HAS_DUMP */
1069 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1070 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,
1071 const char *name)
1072 : malloc_ (malloc),
1073 curr_ (0),
1074 guard_ (*malloc_.lock_),
1075 name_ (name != 0 ? ACE_OS::strdup (name) : 0)
1077 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_LIFO_Iterator_T");
1078 // Cheap trick to make code simple.
1079 // @@ Doug, this looks like trouble...
1080 NAME_NODE temp;
1081 this->curr_ = &temp;
1082 this->curr_->next_ = malloc_.cb_ptr_->name_head_;
1084 this->advance ();
1087 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1088 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_LIFO_Iterator_T (void)
1090 ACE_OS::free ((void *) this->name_);
1093 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1094 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry,
1095 const char *&name)
1097 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1099 if (this->curr_ != 0)
1101 next_entry = (char *) this->curr_->pointer_;
1102 name = this->curr_->name ();
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>::next (void *&next_entry)
1112 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1114 if (this->curr_ != 0)
1116 next_entry = this->curr_->pointer_;
1117 return 1;
1119 else
1120 return 0;
1123 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1124 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done (void) const
1126 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done");
1128 return this->curr_ == 0;
1131 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1132 ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance (void)
1134 ACE_TRACE ("ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance");
1136 this->curr_ = this->curr_->next_;
1138 if (this->name_ == 0)
1139 return this->curr_ != 0;
1141 while (this->curr_ != 0
1142 && ACE_OS::strcmp (this->name_,
1143 this->curr_->name ()) != 0)
1144 this->curr_ = this->curr_->next_;
1146 return this->curr_ != 0;
1149 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> void
1150 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump (void) const
1152 #if defined (ACE_HAS_DUMP)
1153 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::dump");
1155 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
1156 this->curr_->dump ();
1157 this->guard_.dump ();
1158 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("name_ = %s\n"), this->name_));
1159 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
1160 #endif /* ACE_HAS_DUMP */
1163 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1164 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,
1165 const char *name)
1166 : malloc_ (malloc),
1167 curr_ (0),
1168 guard_ (*malloc_.lock_),
1169 name_ (name != 0 ? ACE_OS::strdup (name) : 0)
1171 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_FIFO_Iterator");
1172 // Cheap trick to make code simple.
1173 // @@ Doug, this looks like trouble...
1174 NAME_NODE temp;
1175 this->curr_ = &temp;
1176 this->curr_->next_ = malloc_.cb_ptr_->name_head_;
1177 this->curr_->prev_ = 0;
1179 // Go to the first element that was inserted.
1180 this->start ();
1183 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB>
1184 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::~ACE_Malloc_FIFO_Iterator_T (void)
1186 ACE_OS::free ((void *) this->name_);
1189 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1190 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry,
1191 const char *&name)
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 = (char *) this->curr_->pointer_;
1198 name = this->curr_->name ();
1199 return 1;
1201 else
1202 return 0;
1205 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1206 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next (void *&next_entry)
1208 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::next");
1210 if (this->curr_ != 0)
1212 next_entry = this->curr_->pointer_;
1213 return 1;
1215 else
1216 return 0;
1219 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1220 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done (void) const
1222 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::done");
1224 return this->curr_ == 0;
1227 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1228 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance (void)
1230 ACE_TRACE ("ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::advance");
1232 this->curr_ = this->curr_->prev_;
1234 if (this->name_ == 0)
1235 return this->curr_ != 0;
1237 while (this->curr_ != 0
1238 && ACE_OS::strcmp (this->name_,
1239 this->curr_->name ()) != 0)
1240 this->curr_ = this->curr_->prev_;
1242 return this->curr_ != 0;
1245 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> int
1246 ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::start (void)
1248 this->curr_ = this->curr_->next_;
1249 NAME_NODE *prev = 0;
1251 // Locate the element that was inserted first.
1252 // @@ We could optimize this by making the list a circular list or
1253 // storing an extra pointer.
1254 while (this->curr_ != 0)
1256 prev = this->curr_;
1257 this->curr_ = this->curr_->next_;
1260 this->curr_ = prev;
1261 return this->curr_ != 0;
1264 ACE_END_VERSIONED_NAMESPACE_DECL
1266 #endif /* ACE_MALLOC_T_CPP */