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)
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #if !defined (__ACE_INLINE__)
11 #include "ace/Malloc_T.inl"
12 #endif /* __ACE_INLINE__ */
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
)
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
)));
43 char[n_chunks
* chunk_size
]);
44 #endif /* ACE_HAS_ALLOC_HOOKS */
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_
);
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
))
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
,
84 // Check if size requested fits within pre-determined size.
85 if (nbytes
> sizeof (T
))
88 ACE_Cached_Mem_Pool_Node
<T
> *allocated
= this->free_list_
.remove ();
89 void *ptr
= allocated
== 0 ? 0 : allocated
->addr();
91 ACE_OS::memset (ptr
, initial_value
, sizeof (T
));
95 template <class T
, class ACE_LOCK
> void *
96 ACE_Cached_Allocator
<T
, ACE_LOCK
>::calloc (size_t,
100 ACE_NOTSUP_RETURN (0);
103 template <class T
, class ACE_LOCK
> void
104 ACE_Cached_Allocator
<T
, ACE_LOCK
>::free (void * ptr
)
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
)
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
]);
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_
;
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_
)
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
,
156 // Check if size requested fits within pre-determined size.
157 if (nbytes
> chunk_size_
)
160 ACE_Cached_Mem_Pool_Node
<char> *allocated
= this->free_list_
.remove ();
161 void *ptr
= allocated
== 0 ? 0 : allocated
->addr();
163 ACE_OS::memset (ptr
, initial_value
, chunk_size_
);
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
)
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
,
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
,
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
,
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
,
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
,
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
),
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
),
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)
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"),
407 currp
->size_
* sizeof (MALLOC_HEADER
)));
408 if (currp
== this->cb_ptr_
->freep_
)
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;
441 this->cb_ptr_
= (ACE_CB
*)
442 this->memory_pool_
.init_acquire (sizeof *this->cb_ptr_
,
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")),
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_
,
458 MALLOC_HEADER::init_ptr (&this->cb_ptr_
->freep_
->next_block_
,
459 this->cb_ptr_
->freep_
,
462 NAME_NODE::init_ptr (&this->cb_ptr_
->name_head_
,
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_
,
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
;
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);
503 ++this->cb_ptr_
->ref_counter_
;
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
)
510 memory_pool_ (pool_name
),
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
,
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
)
533 memory_pool_ (pool_name
, options
),
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
,
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
,
558 memory_pool_ (pool_name
, options
),
560 delete_lock_ (false),
563 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
567 this->bad_flag_
= -1;
572 this->bad_flag_
= this->open ();
573 if (this->bad_flag_
== -1)
574 ACELIB_ERROR ((LM_ERROR
,
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_
)
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
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)
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;
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.
658 // *Warning* Do not use "continue" within this while-loop.
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_
;
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_
,
679 currp
->size_
= nunits
;
681 this->cb_ptr_
->freep_
= prevp
;
683 // Skip over the MALLOC_HEADER when returning pointer.
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
),
697 void *remap_addr
= this->memory_pool_
.base_addr ();
699 this->cb_ptr_
= (ACE_CB
*) remap_addr
;
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_
,
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
718 this->shared_free (currp
+ 1);
719 currp
= this->cb_ptr_
->freep_
;
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")),
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
,
759 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
760 void *ptr
= this->malloc (nbytes
);
763 ACE_OS::memset (ptr
, initial_value
, nbytes
);
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
,
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)
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.
801 || blockp
>= (MALLOC_HEADER
*) currp
->next_block_
;
802 currp
= currp
->next_block_
)
804 if (currp
>= (MALLOC_HEADER
*) currp
->next_block_
806 || blockp
< (MALLOC_HEADER
*) currp
->next_block_
))
807 // Freed block at the start or the end of the memory pool.
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_
;
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_
;
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)
853 for (NAME_NODE
*node
= this->cb_ptr_
->name_head_
;
856 if (ACE_OS::strcmp (node
->name (),
860 ACE_SEH_EXCEPT (this->memory_pool_
.seh_selector (GetExceptionInformation ()))
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
,
870 if (this->cb_ptr_
== 0)
873 // Combine the two allocations into one to avoid overhead...
874 NAME_NODE
*new_node
= 0;
876 ACE_ALLOCATOR_RETURN (new_node
,
878 this->shared_malloc (sizeof (NAME_NODE
) +
879 ACE_OS::strlen (name
) + 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.
886 new (new_node
) NAME_NODE (name
,
888 reinterpret_cast<char *> (pointer
),
889 this->cb_ptr_
->name_head_
);
890 this->cb_ptr_
->name_head_
= result
;
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
,
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
);
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_
;
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
,
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.
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
,
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
);
943 pointer
= (char *) node
->pointer_
;
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
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)
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.
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_
);
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)
1000 NAME_NODE
*prev
= 0;
1002 for (NAME_NODE
*curr
= this->cb_ptr_
->name_head_
;
1006 if (ACE_OS::strcmp (curr
->name (), name
) == 0)
1008 pointer
= (char *) curr
->pointer_
;
1011 this->cb_ptr_
->name_head_
= curr
->next_
;
1013 prev
->next_
= 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
);
1026 // Didn't find it, so fail.
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");
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
)
1045 ACE_NEW_RETURN (p
, ACE_LOCK (name
), 0);
1047 ACE_NEW_RETURN (p
, ACE_LOCK (ACE::basename (name
,
1048 ACE_DIRECTORY_SEPARATOR_CHAR
)),
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
,
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...
1081 this->curr_
= &temp
;
1082 this->curr_
->next_
= malloc_
.cb_ptr_
->name_head_
;
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
,
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 ();
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_
;
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
,
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...
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.
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
,
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 ();
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_
;
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)
1257 this->curr_
= this->curr_
->next_
;
1261 return this->curr_
!= 0;
1264 ACE_END_VERSIONED_NAMESPACE_DECL
1266 #endif /* ACE_MALLOC_T_CPP */