diff options
Diffstat (limited to 'ACE/ace/Malloc_T.h')
-rw-r--r-- | ACE/ace/Malloc_T.h | 911 |
1 files changed, 911 insertions, 0 deletions
diff --git a/ACE/ace/Malloc_T.h b/ACE/ace/Malloc_T.h new file mode 100644 index 00000000000..a8c11e4d0fa --- /dev/null +++ b/ACE/ace/Malloc_T.h @@ -0,0 +1,911 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Malloc_T.h + * + * $Id$ + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> and + * Irfan Pyarali <irfan@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_MALLOC_T_H +#define ACE_MALLOC_T_H +#include /**/ "ace/pre.h" + +#include "ace/Malloc.h" /* Need ACE_Control_Block */ +#include "ace/Malloc_Base.h" /* Need ACE_Allocator */ + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Malloc_Allocator.h" +#include "ace/Free_List.h" +#include "ace/Guard_T.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_Cached_Mem_Pool_Node + * + * @brief ACE_Cached_Mem_Pool_Node keeps unused memory within a free + * list. + * + * The length of a piece of unused memory must be greater than + * sizeof (void*). This makes sense because we'll waste even + * more memory if we keep them in a separate data structure. + * This class should really be placed within the ACE_Cached_Allocator + * class but this can't be done due to C++ compiler portability problems. + */ +template <class T> +class ACE_Cached_Mem_Pool_Node +{ +public: + /// Return the address of free memory. + T *addr (void); + + /// Get the next ACE_Cached_Mem_Pool_Node in a list. + ACE_Cached_Mem_Pool_Node<T> *get_next (void); + + /// Set the next ACE_Cached_Mem_Pool_Node. + void set_next (ACE_Cached_Mem_Pool_Node<T> *ptr); + +private: + /** + * Since memory is not used when placed in a free list, + * we can use it to maintain the structure of free list. + * I was using union to hide the fact of overlapping memory + * usage. However, that cause problem on MSVC. So, I now turn + * back to hack this with casting. + */ + ACE_Cached_Mem_Pool_Node<T> *next_; +}; + +/** + * @class ACE_Cached_Allocator + * + * @brief A fixed-size allocator that caches items for quicker access. + * + * This class enables caching of dynamically allocated, + * fixed-sized classes. Notice that the <code>sizeof (TYPE)</code> + * must be greater than or equal to <code> sizeof (void*) </code> for + * this to work properly. + * + * This class can be configured flexibly with different types of + * ACE_LOCK strategies that support the @a ACE_Thread_Mutex, + * @a ACE_Thread_Semaphore, @a ACE_Process_Mutex, and @a + * ACE_Process_Semaphore constructor API. + * + * @sa ACE_Dynamic_Cached_Allocator + */ +template <class T, class ACE_LOCK> +class ACE_Cached_Allocator : public ACE_New_Allocator +{ +public: + /// Create a cached memory pool with @a n_chunks chunks + /// each with sizeof (TYPE) size. + ACE_Cached_Allocator (size_t n_chunks); + + /// Clear things up. + ~ACE_Cached_Allocator (void); + + /** + * Get a chunk of memory from free list cache. Note that @a nbytes is + * only checked to make sure that it's less or equal to sizeof T, and is + * otherwise ignored since @c malloc() always returns a pointer to an + * item of sizeof (T). + */ + void *malloc (size_t nbytes = sizeof (T)); + + /** + * Get a chunk of memory from free list cache, giving them + * @a initial_value. Note that @a nbytes is only checked to make sure + * that it's less or equal to sizeof T, and is otherwise ignored since + * calloc() always returns a pointer to an item of sizeof (T). + */ + virtual void *calloc (size_t nbytes, + char initial_value = '\0'); + + /// This method is a no-op and just returns 0 since the free list + /// only works with fixed sized entities. + virtual void *calloc (size_t n_elem, + size_t elem_size, + char initial_value = '\0'); + + /// Return a chunk of memory back to free list cache. + void free (void *); + + /// Return the number of chunks available in the cache. + size_t pool_depth (void); + +private: + /// Remember how we allocate the memory in the first place so + /// we can clear things up later. + char *pool_; + + /// Maintain a cached memory free list. + ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<T>, ACE_LOCK> free_list_; +}; + +/** + * @class ACE_Dynamic_Cached_Allocator + * + * @brief A size-based allocator that caches blocks for quicker access. + * + * This class enables caching of dynamically allocated, + * fixed-size chunks. Notice that the <code>chunk_size</code> + * must be greater than or equal to <code> sizeof (void*) </code> for + * this to work properly. + * + * This class can be configured flexibly with different types of + * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a + * ACE_Process_Mutex constructor API. + * + * @sa ACE_Cached_Allocator + */ +template <class ACE_LOCK> +class ACE_Dynamic_Cached_Allocator : public ACE_New_Allocator +{ +public: + /// Create a cached memory pool with @a n_chunks chunks + /// each with @a chunk_size size. + ACE_Dynamic_Cached_Allocator (size_t n_chunks, size_t chunk_size); + + /// Clear things up. + ~ACE_Dynamic_Cached_Allocator (void); + + /** + * Get a chunk of memory from free list cache. Note that @a nbytes is + * only checked to make sure that it's less or equal to @a chunk_size, + * and is otherwise ignored since malloc() always returns a pointer to an + * item of @a chunk_size size. + */ + void *malloc (size_t nbytes = 0); + + /** + * Get a chunk of memory from free list cache, giving them + * @a initial_value. Note that @a nbytes is only checked to make sure + * that it's less or equal to @a chunk_size, and is otherwise ignored + * since calloc() always returns a pointer to an item of @a chunk_size. + */ + virtual void *calloc (size_t nbytes, + char initial_value = '\0'); + + /// This method is a no-op and just returns 0 since the free list + /// only works with fixed sized entities. + virtual void *calloc (size_t n_elem, + size_t elem_size, + char initial_value = '\0'); + + /// Return a chunk of memory back to free list cache. + void free (void *); + + /// Return the number of chunks available in the cache. + size_t pool_depth (void); + +private: + /// Remember how we allocate the memory in the first place so + /// we can clear things up later. + char *pool_; + + /// Maintain a cached memory free list. We use @c char as template + /// parameter, although sizeof(char) is usually less than + /// sizeof(void*). Really important is that @a chunk_size + /// must be greater or equal to sizeof(void*). + ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<char>, ACE_LOCK> free_list_; + + /// Remember the size of our chunks. + size_t chunk_size_; +}; + +/** + * @class ACE_Allocator_Adapter + * + * @brief This class is an Adapter that allows the ACE_Allocator to + * use the ACE_Malloc class below. + */ +template <class MALLOC> +class ACE_Allocator_Adapter : public ACE_Allocator +{ +public: + // Trait. + typedef MALLOC ALLOCATOR; + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + // The following code will break C++ compilers that don't support + // template typedefs correctly. + typedef const ACE_TYPENAME MALLOC::MEMORY_POOL_OPTIONS *MEMORY_POOL_OPTIONS; +#else + typedef const void *MEMORY_POOL_OPTIONS; +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + + // = Initialization. + /** + * Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. */ + ACE_Allocator_Adapter (const char *pool_name = 0); + + /** + * Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. + * This constructor must be inline to avoid bugs with some C++ + * compilers. */ + ACE_Allocator_Adapter (const char *pool_name, + const char *lock_name, + MEMORY_POOL_OPTIONS options = 0) + : allocator_ (ACE_TEXT_CHAR_TO_TCHAR (pool_name), + ACE_TEXT_CHAR_TO_TCHAR (lock_name), + options) + { + ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter"); + } + +#if defined (ACE_HAS_WCHAR) + /** + * Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. */ + ACE_Allocator_Adapter (const wchar_t *pool_name); + + /** + * Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. + * This constructor must be inline to avoid bugs with some C++ + * compilers. */ + ACE_Allocator_Adapter (const wchar_t *pool_name, + const wchar_t *lock_name, + MEMORY_POOL_OPTIONS options = 0) + : allocator_ (ACE_TEXT_WCHAR_TO_TCHAR (pool_name), + ACE_TEXT_WCHAR_TO_TCHAR (lock_name), + options) + { + ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter"); + } +#endif /* ACE_HAS_WCHAR */ + + /// Destructor. + virtual ~ACE_Allocator_Adapter (void); + + // = Memory Management + + /// Allocate @a nbytes, but don't give them any initial value. + virtual void *malloc (size_t nbytes); + + /// Allocate @a nbytes, giving them all an @a initial_value. + virtual void *calloc (size_t nbytes, char initial_value = '\0'); + + /// Allocate @a n_elem each of size @a elem_size, giving them + /// @a initial_value. + virtual void *calloc (size_t n_elem, + size_t elem_size, + char initial_value = '\0'); + + /// Free @a ptr (must have been allocated by ACE_Allocator::malloc()). + virtual void free (void *ptr); + + /// Remove any resources associated with this memory manager. + virtual int remove (void); + + // = Map manager like functions + + /** + * Associate @a name with @a pointer. If @a duplicates == 0 then do + * not allow duplicate @a name/pointer associations, else if + * @a duplicates> != 0 then allow duplicate @a name/pointer + * assocations. Returns 0 if successfully binds (1) a previously + * unbound @a name or (2) @a duplicates != 0, returns 1 if trying to + * bind a previously bound @a name and @a duplicates == 0, else + * returns -1 if a resource failure occurs. + */ + virtual int bind (const char *name, void *pointer, int duplicates = 0); + + /** + * Associate @a name with @a pointer. Does not allow duplicate + * name/pointer associations. Returns 0 if successfully binds + * (1) a previously unbound @a name, 1 if trying to bind a previously + * bound @a name, or returns -1 if a resource failure occurs. When + * this call returns, @a pointer's value will always reference the + * void * that @a name is associated with. Thus, if the caller needs + * to use @a pointer (e.g., to free it) a copy must be maintained by + * the caller. + */ + virtual int trybind (const char *name, void *&pointer); + + /// Locate @a name and pass out parameter via pointer. If found, + /// return 0, returns -1 if @a name isn't found. + virtual int find (const char *name, void *&pointer); + + /// Returns 0 if the name is in the mapping and -1 if not. + virtual int find (const char *name); + + /// Unbind (remove) the name from the map. Don't return the pointer + /// to the caller + virtual int unbind (const char *name); + + /// Break any association of name. Returns the value of pointer in + /// case the caller needs to deallocate memory. + virtual int unbind (const char *name, void *&pointer); + + // = Protection and "sync" (i.e., flushing data to backing store). + + /** + * Sync @a len bytes of the memory region to the backing store + * starting at @c this->base_addr_. If @a len == -1 then sync the + * whole region. + */ + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + + /// Sync @a len bytes of the memory region to the backing store + /// starting at @c addr_. + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + + /** + * Change the protection of the pages of the mapped region to @a prot + * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 + * then change protection of all pages in the mapped region. + */ + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + + /// Change the protection of the pages of the mapped region to @a prot + /// starting at @a addr up to @a len bytes. + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + + /// Returns the underlying allocator. + ALLOCATOR &alloc (void); + +#if defined (ACE_HAS_MALLOC_STATS) + /// Dump statistics of how malloc is behaving. + virtual void print_stats (void) const; +#endif /* ACE_HAS_MALLOC_STATS */ + + /// Dump the state of the object. + virtual void dump (void) const; + +private: + /// ALLOCATOR instance, which is owned by the adapter. + ALLOCATOR allocator_; +}; + +/** + * @class ACE_Static_Allocator + * + * @brief Defines a class that provided a highly optimized memory + * management scheme for allocating memory statically. + * + * This class allocates a fixed-size @c POOL_SIZE of memory and + * uses the ACE_Static_Allocator_Base class implementations of + * malloc() and calloc() to optimize memory allocation from this + * pool. + */ +template <size_t POOL_SIZE> +class ACE_Static_Allocator : public ACE_Static_Allocator_Base +{ +public: + ACE_Static_Allocator (void) + : ACE_Static_Allocator_Base (pool_, POOL_SIZE) + { + // This function <{must}> be inlined!!! + } + +private: + /// Pool contents. + char pool_[POOL_SIZE]; +}; + +// Forward declaration. +template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> +class ACE_Malloc_LIFO_Iterator_T; + +// Ensure backwards compatibility... +#define ACE_Malloc_Iterator ACE_Malloc_LIFO_Iterator + +// Forward declaration. +template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> +class ACE_Malloc_FIFO_Iterator_T; + +/** + * @class ACE_Malloc_T + * + * @brief Define a C++ class that uses parameterized types to provide + * an extensible mechanism for encapsulating various of dynamic + * memory management strategies. + * + * This class can be configured flexibly with different + * MEMORY_POOL strategies and different types of ACE_LOCK + * strategies that support the @a ACE_Thread_Mutex and @a + * ACE_Process_Mutex constructor API. + * + * Note that the @a bind() and @a find() methods use linear search, so + * it's not a good idea to use them for managing a large number of + * entities. If you need to manage a large number of entities, it's + * recommended that you @a bind() an @ ACE_Hash_Map_Manager that + * resides in shared memory, use @a find() to locate it, and then + * store/retrieve the entities in the hash map. + * */ +template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> +class ACE_Malloc_T +{ +public: + friend class ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>; + friend class ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>; + typedef ACE_MEM_POOL MEMORY_POOL; + typedef ACE_MEM_POOL_OPTIONS MEMORY_POOL_OPTIONS; + typedef ACE_TYPENAME ACE_CB::ACE_Name_Node NAME_NODE; + typedef ACE_TYPENAME ACE_CB::ACE_Malloc_Header MALLOC_HEADER; + + // = Initialization and termination methods. + /** + * Initialize ACE_Malloc. This constructor passes @a pool_name to + * initialize the memory pool, and uses ACE::basename() to + * automatically extract out the name used for the underlying lock + * name (if necessary). + * + * Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. + */ + ACE_Malloc_T (const ACE_TCHAR *pool_name = 0); + + /** + * Initialize ACE_Malloc. This constructor passes @a pool_name to + * initialize the memory pool, and uses @a lock_name to automatically + * extract out the name used for the underlying lock name (if + * necessary). In addition, @a options is passed through to + * initialize the underlying memory pool. + * + * Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. + */ + ACE_Malloc_T (const ACE_TCHAR *pool_name, + const ACE_TCHAR *lock_name, + const ACE_MEM_POOL_OPTIONS *options = 0); + + /** + * Initialize an ACE_Malloc with an external ACE_LOCK. + * This constructor passes @a pool_name and @a options to initialize + * the memory pool. @a lock is used as the pool lock, and must be + * properly set up and ready for use before being passed to this method. + */ + ACE_Malloc_T (const ACE_TCHAR *pool_name, + const ACE_MEM_POOL_OPTIONS *options, + ACE_LOCK *lock); + +#if !defined (ACE_HAS_TEMPLATE_TYPEDEFS) + /// This is necessary to work around template bugs with certain C++ + /// compilers. + ACE_Malloc_T (const ACE_TCHAR *pool_name, + const ACE_TCHAR *lock_name, + const void *options = 0); +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + + /// Destructor + ~ACE_Malloc_T (void); + + /// Get Reference counter. + int ref_counter (void); + + /// Release ref counter. + int release (int close = 0); + + /// Releases resources allocated by this object. + int remove (void); + + // = Memory management + + /// Allocate @a nbytes, but don't give them any initial value. + void *malloc (size_t nbytes); + + /// Allocate @a nbytes, giving them @a initial_value. + void *calloc (size_t nbytes, char initial_value = '\0'); + + /// Allocate @a n_elem each of size @a elem_size, giving them + /// @a initial_value. + void *calloc (size_t n_elem, + size_t elem_size, + char initial_value = '\0'); + + /// Deallocate memory pointed to by @a ptr, which must have been + /// allocated previously by malloc(). + void free (void *ptr); + + /// Returns a reference to the underlying memory pool. + MEMORY_POOL &memory_pool (void); + + // = Map manager like functions + + /** + * Associate @a name with @a pointer. If @a duplicates == 0 then do + * not allow duplicate name/pointer associations, else if + * @a duplicates != 0 then allow duplicate name/pointer + * assocations. Returns 0 if successfully binds (1) a previously + * unbound @a name or (2) @a duplicates != 0, returns 1 if trying to + * bind a previously bound @a name and @a duplicates == 0, else + * returns -1 if a resource failure occurs. + */ + int bind (const char *name, void *pointer, int duplicates = 0); + + /** + * Associate @a name with @a pointer. Does not allow duplicate + * name/pointer associations. Returns 0 if successfully binds + * (1) a previously unbound @a name, 1 if trying to bind a previously + * bound @a name, or returns -1 if a resource failure occurs. When + * this call returns @a pointer's value will always reference the + * void * that @a name is associated with. Thus, if the caller needs + * to use @a pointer (e.g., to free it) a copy must be maintained by + * the caller. + */ + int trybind (const char *name, void *&pointer); + + /// Locate @a name and pass out parameter via @a pointer. If found, + /// return 0, returns -1 if failure occurs. + int find (const char *name, void *&pointer); + + /// Returns 0 if @a name is in the mapping. -1, otherwise. + int find (const char *name); + + /** + * Unbind (remove) the name from the map. Don't return the pointer + * to the caller. If you want to remove all occurrences of @a name + * you'll need to call this method multiple times until it fails... + */ + int unbind (const char *name); + + /** + * Unbind (remove) one association of @a name to @a pointer. Returns + * the value of pointer in case the caller needs to deallocate + * memory. If you want to remove all occurrences of @a name you'll + * need to call this method multiple times until it fails... + */ + int unbind (const char *name, void *&pointer); + + // = Protection and "sync" (i.e., flushing data to backing store). + + /** + * Sync @a len bytes of the memory region to the backing store + * starting at @c this->base_addr_. If @a len == -1 then sync the + * whole region. + */ + int sync (ssize_t len = -1, int flags = MS_SYNC); + + /// Sync @a len bytes of the memory region to the backing store + /// starting at @c addr_. + int sync (void *addr, size_t len, int flags = MS_SYNC); + + /** + * Change the protection of the pages of the mapped region to @a prot + * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 + * then change protection of all pages in the mapped region. + */ + int protect (ssize_t len = -1, int prot = PROT_RDWR); + + /// Change the protection of the pages of the mapped region to @a prot + /// starting at @a addr up to @a len bytes. + int protect (void *addr, size_t len, int prot = PROT_RDWR); + + /** + * Returns a count of the number of available chunks that can hold + * @a size byte allocations. Function can be used to determine if you + * have reached a water mark. This implies a fixed amount of allocated + * memory. + * + * @param size The chunk size of that you would like a count of + * @return Function returns the number of chunks of the given size + * that would fit in the currently allocated memory. + */ + ssize_t avail_chunks (size_t size) const; + +#if defined (ACE_HAS_MALLOC_STATS) + /// Dump statistics of how malloc is behaving. + void print_stats (void) const; +#endif /* ACE_HAS_MALLOC_STATS */ + + /// Returns a pointer to the lock used to provide mutual exclusion to + /// an ACE_Malloc allocator. + ACE_LOCK &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Return cb_ptr value. + void *base_addr (void); + + /** + * Bad flag. This operation should be called immediately after the + * construction of the Malloc object to query whether the object was + * constructed successfully. If not, the user should invoke @c + * remove and release the object (it is not usable.) + * @retval 0 if all is fine. non-zero if this malloc object is + * unuable. + */ + int bad (void); + +private: + /// Initialize the Malloc pool. + int open (void); + + /// Associate @a name with @a pointer. Assumes that locks are held by + /// callers. + int shared_bind (const char *name, + void *pointer); + + /** + * Try to locate @a name. If found, return the associated + * ACE_Name_Node, else returns 0 if can't find the @a name. + * Assumes that locks are held by callers. Remember to cast the + * return value to ACE_CB::ACE_Name_Node*. + */ + void *shared_find (const char *name); + + /// Allocate memory. Assumes that locks are held by callers. + void *shared_malloc (size_t nbytes); + + /// Deallocate memory. Assumes that locks are held by callers. + void shared_free (void *ptr); + + /// Pointer to the control block that is stored in memory controlled + /// by <MEMORY_POOL>. + ACE_CB *cb_ptr_; + + /// Pool of memory used by ACE_Malloc to manage its freestore. + MEMORY_POOL memory_pool_; + + /// Lock that ensures mutual exclusion for the memory pool. + ACE_LOCK *lock_; + + /// True if destructor should delete the lock + bool delete_lock_; + + /// Keep track of failure in constructor. + int bad_flag_; +}; + +/*****************************************************************************/ + +/** + * @class ACE_Malloc_Lock_Adapter_T + * + * @brief Template functor adapter for lock strategies used with ACE_Malloc_T. + * + * This class acts as a factory for lock strategies that have various ctor + * signatures. If the lock strategy's ctor takes an ACE_TCHAR* as the first + * and only required parameter, it will just work. Otherwise use template + * specialization to create a version that matches the lock strategy's ctor + * signature. See ACE_Process_Semaphore and ACE_Thread_Semaphore for + * examples. + * + */ +/*****************************************************************************/ + +/** + * @class ACE_Malloc_LIFO_Iterator_T + * + * @brief LIFO iterator for names stored in Malloc'd memory. + * + * This class can be configured flexibly with different types of + * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a + * ACE_Process_Mutex constructor API. + * + * Does not support deletions while iteration is occurring. + */ +template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> +class ACE_Malloc_LIFO_Iterator_T +{ +public: + typedef ACE_TYPENAME ACE_CB::ACE_Name_Node NAME_NODE; + typedef ACE_TYPENAME ACE_CB::ACE_Malloc_Header MALLOC_HEADER; + + // = Initialization method. + /// If @a name = 0 it will iterate through everything else only + /// through those entries whose @a name match. + ACE_Malloc_LIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc, + const char *name = 0); + + /// Destructor. + ~ACE_Malloc_LIFO_Iterator_T (void); + + // = Iteration methods. + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Pass back the next entry in the set that hasn't yet been + /// visited. Returns 0 when all items have been seen, else 1. + int next (void *&next_entry); + + /** + * Pass back the next entry (and the name associated with it) in + * the set that hasn't yet been visited. Returns 0 when all items + * have been seen, else 1. + */ + int next (void *&next_entry, + const char *&name); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Malloc we are iterating over. + ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc_; + + /// Keeps track of how far we've advanced... + NAME_NODE *curr_; + + /// Lock Malloc for the lifetime of the iterator. + ACE_Read_Guard<ACE_LOCK> guard_; + + /// Name that we are searching for. + const char *name_; +}; + +/** + * @class ACE_Malloc_FIFO_Iterator_T + * + * @brief FIFO iterator for names stored in Malloc'd memory. + * + * This class can be configured flexibly with different types of + * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a + * ACE_Process_Mutex constructor API. + * + * Does not support deletions while iteration is occurring. + */ +template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> +class ACE_Malloc_FIFO_Iterator_T +{ +public: + typedef ACE_TYPENAME ACE_CB::ACE_Name_Node NAME_NODE; + typedef ACE_TYPENAME ACE_CB::ACE_Malloc_Header MALLOC_HEADER; + + // = Initialization method. + /// If @a name = 0 it will iterate through everything else only + /// through those entries whose @a name match. + ACE_Malloc_FIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc, + const char *name = 0); + + /// Destructor. + ~ACE_Malloc_FIFO_Iterator_T (void); + + // = Iteration methods. + + /// Returns 1 when all items have been seen, else 0. + int done (void) const; + + /// Pass back the next entry in the set that hasn't yet been + /// visited. Returns 0 when all items have been seen, else 1. + int next (void *&next_entry); + + /** + * Pass back the next entry (and the name associated with it) in + * the set that hasn't yet been visited. Returns 0 when all items + * have been seen, else 1. + */ + int next (void *&next_entry, + const char *&name); + + /// Move forward by one element in the set. Returns 0 when all the + /// items in the set have been seen, else 1. + int advance (void); + + /// Go to the starting element that was inserted first. Returns 0 + /// when there is no item in the set, else 1. + int start (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +private: + /// Malloc we are iterating over. + ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc_; + + /// Keeps track of how far we've advanced... + NAME_NODE *curr_; + + /// Lock Malloc for the lifetime of the iterator. + ACE_Read_Guard<ACE_LOCK> guard_; + + /// Name that we are searching for. + const char *name_; +}; + +template <ACE_MEM_POOL_1, class ACE_LOCK> +class ACE_Malloc : public ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> +{ +public: + // = Initialization and termination methods. + /** + * Initialize ACE_Malloc. This constructor passes @a pool_name to + * initialize the memory pool, and uses ACE::basename() to + * automatically extract out the name used for the underlying lock + * name (if necessary). Note that @a pool_name should be located in + * a directory with the appropriate visibility and protection so + * that all processes that need to access it can do so. + */ + ACE_Malloc (const ACE_TCHAR *pool_name = 0); + + /** + * Initialize ACE_Malloc. This constructor passes @a pool_name to + * initialize the memory pool, and uses @a lock_name to automatically + * extract out the name used for the underlying lock name (if + * necessary). In addition, @a options is passed through to + * initialize the underlying memory pool. Note that @a pool_name + * should be located in a directory with the appropriate visibility + * and protection so that all processes that need to access it can + * do so. + */ + ACE_Malloc (const ACE_TCHAR *pool_name, + const ACE_TCHAR *lock_name, + const ACE_MEM_POOL_OPTIONS *options = 0); + +#if !defined (ACE_HAS_TEMPLATE_TYPEDEFS) + /// This is necessary to work around template bugs with certain C++ + /// compilers. + ACE_Malloc (const ACE_TCHAR *pool_name, + const ACE_TCHAR *lock_name, + const void *options = 0); +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ +}; + +template <ACE_MEM_POOL_1, class ACE_LOCK> +class ACE_Malloc_LIFO_Iterator : public ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> +{ +public: + // = Initialization method. + /// If @a name = 0 it will iterate through everything else only + /// through those entries whose @a name match. + ACE_Malloc_LIFO_Iterator (ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK> &malloc, + const char *name = 0); +}; + +template <ACE_MEM_POOL_1, class ACE_LOCK> +class ACE_Malloc_FIFO_Iterator : public ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> +{ +public: + // = Initialization method. + /// If @a name = 0 it will iterate through everything else only + /// through those entries whose @a name match. + ACE_Malloc_FIFO_Iterator (ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK> &malloc, + const char *name = 0); +}; + +template <class ACE_LOCK> +class ACE_Malloc_Lock_Adapter_T +{ +public: + ACE_LOCK * operator () (const ACE_TCHAR *myname); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/Malloc_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Malloc_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Malloc_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_MALLOC_H */ |