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 ()
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 ()
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 ()
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
,
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 ()
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)
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.
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;
440 this->cb_ptr_
= (ACE_CB
*)
441 this->memory_pool_
.init_acquire (sizeof *this->cb_ptr_
,
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")),
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_
,
457 MALLOC_HEADER::init_ptr (&this->cb_ptr_
->freep_
->next_block_
,
458 this->cb_ptr_
->freep_
,
461 NAME_NODE::init_ptr (&this->cb_ptr_
->name_head_
,
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_
,
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);
492 ++this->cb_ptr_
->ref_counter_
;
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
)
499 memory_pool_ (pool_name
),
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
,
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
)
522 memory_pool_ (pool_name
, options
),
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
,
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
,
547 memory_pool_ (pool_name
, options
),
549 delete_lock_ (false),
552 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::ACE_Malloc_T");
556 this->bad_flag_
= -1;
561 this->bad_flag_
= this->open ();
562 if (this->bad_flag_
== -1)
563 ACELIB_ERROR ((LM_ERROR
,
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_
)
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
603 this->cb_ptr_
= nullptr;
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)
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;
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.
646 // *Warning* Do not use "continue" within this while-loop.
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_
;
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_
,
667 currp
->size_
= nunits
;
669 this->cb_ptr_
->freep_
= prevp
;
671 // Skip over the MALLOC_HEADER when returning pointer.
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
),
685 void *remap_addr
= this->memory_pool_
.base_addr ();
687 this->cb_ptr_
= (ACE_CB
*) remap_addr
;
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_
,
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
706 this->shared_free (currp
+ 1);
707 currp
= this->cb_ptr_
->freep_
;
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")),
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
,
747 ACE_TRACE ("ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::calloc");
748 void *ptr
= this->malloc (nbytes
);
751 ACE_OS::memset (ptr
, initial_value
, nbytes
);
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
,
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)
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.
788 || blockp
>= (MALLOC_HEADER
*) currp
->next_block_
;
789 currp
= currp
->next_block_
)
791 if (currp
>= (MALLOC_HEADER
*) currp
->next_block_
793 || blockp
< (MALLOC_HEADER
*) currp
->next_block_
))
794 // Freed block at the start or the end of the memory pool.
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_
;
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_
;
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 */
840 for (NAME_NODE
*node
= this->cb_ptr_
->name_head_
;
843 if (std::strcmp (node
->name (), name
) == 0)
846 ACE_SEH_EXCEPT (this->memory_pool_
.seh_selector (GetExceptionInformation ()))
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
,
859 // Combine the two allocations into one to avoid overhead...
860 NAME_NODE
*new_node
= nullptr;
862 ACE_ALLOCATOR_RETURN (new_node
,
864 this->shared_malloc (sizeof (NAME_NODE
) +
865 ACE_OS::strlen (name
) + 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.
872 new (new_node
) NAME_NODE (name
,
874 reinterpret_cast<char *> (pointer
),
875 this->cb_ptr_
->name_head_
);
876 this->cb_ptr_
->name_head_
= result
;
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
,
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
);
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_
;
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
,
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.
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
,
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
);
929 pointer
= (char *) node
->pointer_
;
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
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)
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.
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_
);
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)
988 for (NAME_NODE
*curr
= this->cb_ptr_
->name_head_
;
992 if (std::strcmp (curr
->name (), name
) == 0)
994 pointer
= (char *) curr
->pointer_
;
997 this->cb_ptr_
->name_head_
= curr
->next_
;
999 prev
->next_
= 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
);
1012 // Didn't find it, so fail.
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");
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
)
1031 ACE_NEW_RETURN (p
, ACE_LOCK (name
), 0);
1033 ACE_NEW_RETURN (p
, ACE_LOCK (ACE::basename (name
,
1034 ACE_DIRECTORY_SEPARATOR_CHAR
)),
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
,
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...
1067 this->curr_
= &temp
;
1068 this->curr_
->next_
= malloc_
.cb_ptr_
->name_head_
;
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
,
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 ();
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_
;
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
,
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...
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.
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
,
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 ();
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_
;
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)
1241 this->curr_
= this->curr_
->next_
;
1245 return this->curr_
!= 0;
1248 ACE_END_VERSIONED_NAMESPACE_DECL
1250 #endif /* ACE_MALLOC_T_CPP */