diff options
28 files changed, 428 insertions, 92 deletions
diff --git a/ChangeLog-98a b/ChangeLog-98a index 08091d328fc..cac0b650b18 100644 --- a/ChangeLog-98a +++ b/ChangeLog-98a @@ -1,5 +1,27 @@ Wed Apr 8 01:09:52 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + * ace/Malloc_T: Added a new ACE_Static_Allocator class, which is + highly optimized for allocations where (1) all the memory size + is known in advance and (2) no deletions are done. This class + will ultimately be used in TAO to improve it's startup + performance for operation tables initialization. + + * tests/Hash_Map_Manager_Test.cpp: Enhanced the test so that it + uses the new ACE_Static_Allocator feature. + + * ace/OS: Added support for the rename() method. Thanks to Ganesh + Pai for suggesting this. + + * ace/config-win32-common.h, + config-sunos*.h: + config-irix-6*.h: + Enable the ACE_HAS_WILDCARD_BIND macro. + + * ace/ACE.cpp: Modified the bind_port() method so that it is more + efficient on platforms that interpret a 0 port to bind() as a + request for the kernel to select the port. Thanks to Chris + Cleeland for pointing this out. + * ace/Hash_Map_Manager: Made a bunch of minor changes to fix some subtle deadlocks with intra-class locking. diff --git a/ace/ACE.cpp b/ace/ACE.cpp index 109d57de86f..4899417a4c9 100644 --- a/ace/ACE.cpp +++ b/ace/ACE.cpp @@ -1543,6 +1543,13 @@ ACE::bind_port (ACE_HANDLE handle, #endif /* ACE_HAS_SIN_LEN */ sin.sin_addr.s_addr = ip_addr; +#if defined (ACE_HAS_WILDCARD_BIND) + // The OS kernel should select a free port for us. + sin.sin_port = 0; + return ACE_OS::bind (handle, (sockaddr *) &sin, sizeof sin); +#else + // We have to select the port explicitly. + for (;;) { sin.sin_port = htons (upper_limit); @@ -1572,6 +1579,7 @@ ACE::bind_port (ACE_HANDLE handle, } } } +#endif /* ACE_HAS_WILDCARD_BIND */ } // Make the current process a UNIX daemon. This is based on Stevens diff --git a/ace/Malloc.h b/ace/Malloc.h index 1c2c27c0859..27da8d5da86 100644 --- a/ace/Malloc.h +++ b/ace/Malloc.h @@ -158,33 +158,34 @@ struct ACE_Export ACE_Malloc_Stats #define AMS(X) #endif /* ACE_HAS_MALLOC_STATS */ -// ACE_MALLOC_ALIGN allows you to insure that allocated regions are at least -// <ACE_MALLOC_ALIGN> bytes long. It is especially useful when you want -// areas to be at least a page long, or 32K long, or something like that. -// It doesn't guarantee alignment to an address multiple, like 8-byte -// data alignment, etc. The allocated area's padding to your selected size -// is done with an added array of long[] and your compiler will decide how -// to align things in memory. +// ACE_MALLOC_ALIGN allows you to insure that allocated regions are at +// least <ACE_MALLOC_ALIGN> bytes long. It is especially useful when +// you want areas to be at least a page long, or 32K long, or +// something like that. It doesn't guarantee alignment to an address +// multiple, like 8-byte data alignment, etc. The allocated area's +// padding to your selected size is done with an added array of long[] +// and your compiler will decide how to align things in memory. // -// The default ACE_MALLOC_ALIGN is 'long', which will probably add a long -// of padding - it doesn't have any real affect. If you want to use this -// feature, define ACE_MALLOC_ALIGN in your config.h file and use a signed -// integer number of bytes you want. For example: -// #define ACE_MALLOC_ALIGN ((int)4096) +// The default ACE_MALLOC_ALIGN is 'long', which will probably add a +// long of padding - it doesn't have any real affect. If you want to +// use this feature, define ACE_MALLOC_ALIGN in your config.h file and +// use a signed integer number of bytes you want. For example: +// #define ACE_MALLOC_ALIGN ((int)4096) #if !defined (ACE_MALLOC_ALIGN) #define ACE_MALLOC_ALIGN ((int)(sizeof (long))) #endif /* ACE_MALLOC_ALIGN */ - union ACE_Export ACE_Malloc_Header -// TITLE -// This is a block header. { + // TITLE + // This is a block header. + struct ACE_Malloc_Control_Block { ACE_Malloc_Header *next_block_; // Points to next block if on free list. + size_t size_; // Size of this block. } s_; diff --git a/ace/Malloc_T.cpp b/ace/Malloc_T.cpp index 9d470dc8a85..ef0d922e78d 100644 --- a/ace/Malloc_T.cpp +++ b/ace/Malloc_T.cpp @@ -32,7 +32,7 @@ ACE_Cached_Allocator<T, ACE_LOCK>::~ACE_Cached_Allocator (void) delete [] tmp; } -ACE_ALLOC_HOOK_DEFINE(ACE_Malloc) +ACE_ALLOC_HOOK_DEFINE (ACE_Malloc) template <class MALLOC> ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (LPCTSTR pool_name) @@ -70,8 +70,8 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::dump (void) const ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); this->memory_pool_.dump (); - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("cb_ptr_ = %x"), this->cb_ptr_)); - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("\n"))); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("cb_ptr_ = %x"), this->cb_ptr_)); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("\n"))); #if defined (ACE_HAS_MALLOC_STATS) this->cp_ptr_->malloc_stats_.dump (); #endif /* ACE_HAS_MALLOC_STATS */ @@ -87,14 +87,14 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::print_stats (void) const ACE_GUARD (ACE_LOCK, ace_mon, this->lock_); this->cb_ptr_->malloc_stats_.dump (); - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("(%P|%t) contents of freelist:\n"))); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT (" (%P|%t) contents of freelist:\n"))); for (ACE_Malloc_Header *currp = this->cb_ptr_->freep_->s_.next_block_; ; currp = currp->s_.next_block_) { ACE_DEBUG ((LM_DEBUG, - ASYS_TEXT ("(%P|%t) ptr = %u, ACE_Malloc_Header units = %d, byte units = %d\n"), + ASYS_TEXT (" (%P|%t) ptr = %u, ACE_Malloc_Header units = %d, byte units = %d\n"), currp, currp->s_.size_, currp->s_.size_ * sizeof (ACE_Malloc_Header))); if (currp == this->cb_ptr_->freep_) @@ -135,10 +135,10 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::open (void) rounded_bytes, first_time); if (this->cb_ptr_ == 0) - ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT ("(%P|%t) %p\n"), ASYS_TEXT ("init_acquire failed")), -1); + ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT (" (%P|%t) %p\n"), ASYS_TEXT ("init_acquire failed")), -1); else if (first_time) { - // ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("(%P|%t) first time in, control block = %u\n"), this->cb_ptr_)); + // ACE_DEBUG ((LM_DEBUG, ASYS_TEXT (" (%P|%t) first time in, control block = %u\n"), this->cb_ptr_)); #if defined (ACE_HAS_MALLOC_STATS) // Call the constructor on the ACE_LOCK, using the placement @@ -227,7 +227,7 @@ template <ACE_MEM_POOL_1, class ACE_LOCK> int ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::remove (void) { ACE_TRACE ("ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::remove"); - // ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("(%P|%t) destroying ACE_Malloc\n"))); + // ACE_DEBUG ((LM_DEBUG, ASYS_TEXT (" (%P|%t) destroying ACE_Malloc\n"))); int result = 0; #if defined (ACE_HAS_MALLOC_STATS) @@ -252,7 +252,7 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::shared_malloc (size_t nbytes) // Round up request to a multiple of the ACE_Malloc_Header size. size_t nunits = - (nbytes + sizeof (ACE_Malloc_Header) - 1) / sizeof (ACE_Malloc_Header) + (nbytes + sizeof (ACE_Malloc_Header) - 1) / sizeof (ACE_Malloc_Header) + 1; // Add one for the <ACE_Malloc_Header> itself. // Begin the search starting at the place in the freelist @@ -307,7 +307,7 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::shared_malloc (size_t nbytes) currp = this->cb_ptr_->freep_; } else - ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT ("(%P|%t) %p\n"), ASYS_TEXT ("malloc")), 0); + ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT (" (%P|%t) %p\n"), ASYS_TEXT ("malloc")), 0); } } } @@ -423,7 +423,7 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::shared_bind (const char *name, // Insert new node at the head of the list. Note that (new_node) is // *not* a cast! ACE_NEW_RETURN (this->cb_ptr_->name_head_, - (new_node) ACE_Name_Node (name, pointer, + (new_node) ACE_Name_Node (name, pointer, this->cb_ptr_->name_head_), -1); return 0; @@ -546,7 +546,7 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::unbind (const char *name, void *&pointer) prev->next_ = curr->next_; // This will free up both the node and the name due to our - // sleezy trick in bind()! + // sleezy trick in bind ()! this->shared_free (curr); return 0; } @@ -574,8 +574,8 @@ ACE_Malloc_Iterator<ACE_MEM_POOL_2, ACE_LOCK>::dump (void) const ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); this->curr_->dump (); this->guard_.dump (); - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("name_ = %s"), this->name_)); - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT("\n"))); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("name_ = %s"), this->name_)); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("\n"))); ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } @@ -593,7 +593,7 @@ ACE_Malloc_Iterator<ACE_MEM_POOL_2, ACE_LOCK>::ACE_Malloc_Iterator (ACE_Malloc<A this->curr_ = &temp; this->curr_->next_ = malloc_.cb_ptr_->name_head_; - this->advance(); + this->advance (); } template <ACE_MEM_POOL_1, class ACE_LOCK> diff --git a/ace/Malloc_T.h b/ace/Malloc_T.h index 0a561873138..da731519094 100644 --- a/ace/Malloc_T.h +++ b/ace/Malloc_T.h @@ -200,6 +200,49 @@ private: // ALLOCATOR instance, which is owned by the adapter. }; +template <size_t POOL_SIZE> +class ACE_Static_Allocator : public ACE_Allocator +{ + // = TITLE + // Defines a class that provided a highly optimized memory + // management scheme for allocating memory statically. + // + // = DESCRIPTION + // This class allocates a fixed-size <POOL_SIZE> of memory and + // every time <malloc>/<calloc> is called, it simply moves an + // internal index forward and returns a pointer to the requested + // chunk. All memory is allocated statically and <free> is a + // no-op. This behavior is focused on use-cases where all the + // memory allocation needs are known in advance. +public: + ACE_Static_Allocator (void); + virtual void *malloc (size_t nbytes); + virtual void *calloc (size_t nbytes, char initial_value = '\0'); + virtual void free (void *ptr); + virtual int remove (void); + virtual int bind (const char *name, void *pointer, int duplicates = 0); + virtual int trybind (const char *name, void *&pointer); + virtual int find (const char *name, void *&pointer); + virtual int find (const char *name); + virtual int unbind (const char *name); + virtual int unbind (const char *name, void *&pointer); + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); +#if defined (ACE_HAS_MALLOC_STATS) + virtual void print_stats (void) const; +#endif /* ACE_HAS_MALLOC_STATS */ + virtual void dump (void) const; + +private: + char pool_[POOL_SIZE]; + // Byte in the pool. + + size_t offset_; + // Pointer into the <pool_> buffer. +}; + // Forward declaration. template <ACE_MEM_POOL_1, class ACE_LOCK> class ACE_Malloc_Iterator; diff --git a/ace/Malloc_T.i b/ace/Malloc_T.i index c6ca4e7fad0..04870225a64 100644 --- a/ace/Malloc_T.i +++ b/ace/Malloc_T.i @@ -184,3 +184,129 @@ ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK>::protect (void *addr, size_t len, int flags return this->memory_pool_.protect (addr, len, flags); } +template <size_t POOL_SIZE> ACE_INLINE +ACE_Static_Allocator<POOL_SIZE>::ACE_Static_Allocator (void) + : offset_ (0) +{ +} + +template <size_t POOL_SIZE> ACE_INLINE void * +ACE_Static_Allocator<POOL_SIZE>::malloc (size_t nbytes) +{ + if (this->offset_ + nbytes > POOL_SIZE) + { + errno = ENOMEM; + return 0; + } + else + { + char *ptr = &this->pool_[this->offset_]; + + this->offset_ += nbytes; + + return (void *) ptr; + } +} + +template <size_t POOL_SIZE> ACE_INLINE void * +ACE_Static_Allocator<POOL_SIZE>::calloc (size_t nbytes, + char initial_value) +{ + void *ptr = this->malloc (nbytes); + + ACE_OS::memset (ptr, initial_value, nbytes); + return (void *) ptr; +} + +template <size_t POOL_SIZE> ACE_INLINE void +ACE_Static_Allocator<POOL_SIZE>::free (void *ptr) +{ + // no-op! + // @@ We could check to see if ptr is within our pool?! +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::remove (void) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::bind (const char *, void *, int) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::trybind (const char *, void *&) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::find (const char *, void *&) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::find (const char *) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::unbind (const char *) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::unbind (const char *, void *&) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::sync (ssize_t, int) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::sync (void *, size_t, int) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::protect (ssize_t, int) +{ + return -1; +} + +template <size_t POOL_SIZE> ACE_INLINE int +ACE_Static_Allocator<POOL_SIZE>::protect (void *, size_t, int) +{ + return -1; +} + +#if defined (ACE_HAS_MALLOC_STATS) +template <size_t POOL_SIZE> ACE_INLINE void +ACE_Static_Allocator<POOL_SIZE>::print_stats (void) const +{ +} +#endif /* ACE_HAS_MALLOC_STATS */ + +template <size_t POOL_SIZE> ACE_INLINE void +ACE_Static_Allocator<POOL_SIZE>::dump (void) const +{ + ACE_TRACE ("ACE_Static_Allocator<POOL_SIZE>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("\noffset_ = %d\n"), this->offset_)); + ACE_HEX_DUMP ((LM_DEBUG, this->pool_, POOL_SIZE)); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("\n"))); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} @@ -4442,6 +4442,8 @@ public: static char *mktemp (char *t); static char *getcwd (char *, size_t); + static int rename (const char *old_name, + const char *new_name); static int unlink (const char *path); static char *tempnam (const char *dir, const char *pfx); @@ -4803,6 +4805,8 @@ public: int mode, int perms = 0, LPSECURITY_ATTRIBUTES sa = 0); + static int rename (const wchar_t *oldname, + const wchar_t *newname); static int unlink (const wchar_t *path); #if defined (ACE_HAS_WINCE) static wchar_t *dlerror (void); @@ -947,6 +947,16 @@ ACE_OS::unlink (const char *path) #endif /* VXWORKS */ } +ACE_INLINE int +ACE_OS::rename (const char *old_name, const char *new_name) +{ +#if 0 + ACE_OSCALL_RETURN (::rename (old_name, new_name), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* 0 */ +} + ACE_INLINE char * ACE_OS::tempnam (const char *dir, const char *pfx) { @@ -8670,6 +8680,20 @@ ACE_OS::access (const wchar_t *path, int amode) { #if !defined (ACE_HAS_WINCE) // ACE_TRACE ("ACE_OS::access"); + ACE_OSCALL_RETURN (::_wrename (oldname, newname), int, -1); +#else + // @@ There should be a Win32 API that can do this. + ACE_UNUSED_ARG (path); + ACE_UNUSED_ARG (amode); + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_WINCE */ +} + +ACE_INLINE int +ACE_OS::access (const wchar_t *path, int amode) +{ +#if !defined (ACE_HAS_WINCE) + // ACE_TRACE ("ACE_OS::access"); ACE_OSCALL_RETURN (::_waccess (path, amode), int, -1); #else // @@ There should be a Win32 API that can do this. diff --git a/ace/README b/ace/README index 7ec3a956fe5..414cff2a899 100644 --- a/ace/README +++ b/ace/README @@ -211,6 +211,7 @@ ACE_HAS_USING_KEYWORD Compiler supports the new using keyword for C++ namespac ACE_HAS_VERBOSE_NOTSUP Prints out console message in ACE_NOTSUP. Useful for tracking down origin of ACE_NOTSUP. ACE_HAS_VOIDPTR_MMAP Platform requires void * for mmap(). ACE_HAS_VOIDPTR_SOCKOPT OS/compiler uses void * arg 4 setsockopt() rather than const char * +ACE_HAS_WILDCARD_BIND The bind() call will select the port if it's 0. ACE_HAS_WIN32_TRYLOCK The Win32 platform support TryEnterCriticalSection() (WinNT 4.0 and beyond) ACE_HAS_WINSOCK2 The Win32 platform supports WinSock 2.0 ACE_HAS_XLI Platform has the XLI version of TLI diff --git a/ace/config-irix6.x-g++.h b/ace/config-irix6.x-g++.h index b52175681d6..d8da99c6450 100644 --- a/ace/config-irix6.x-g++.h +++ b/ace/config-irix6.x-g++.h @@ -158,4 +158,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-irix6.x-sgic++-nothreads.h b/ace/config-irix6.x-sgic++-nothreads.h index 7db41bf041c..233ca5e7970 100644 --- a/ace/config-irix6.x-sgic++-nothreads.h +++ b/ace/config-irix6.x-sgic++-nothreads.h @@ -207,4 +207,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_IRIX6X_NTHR_H */ diff --git a/ace/config-irix6.x-sgic++.h b/ace/config-irix6.x-sgic++.h index 687d48fbf6f..e78e0116693 100644 --- a/ace/config-irix6.x-sgic++.h +++ b/ace/config-irix6.x-sgic++.h @@ -49,4 +49,7 @@ #define ACE_MT_SAFE 1 #endif /* ACE_MT_SAFE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_IRIX6X_H */ diff --git a/ace/config-sunos4-g++.h b/ace/config-sunos4-g++.h index ac83a67b5ff..a8f584ca1dd 100644 --- a/ace/config-sunos4-g++.h +++ b/ace/config-sunos4-g++.h @@ -100,5 +100,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-lucid3.2.h b/ace/config-sunos4-lucid3.2.h index 8b3298ce913..ddc3b48e99c 100644 --- a/ace/config-sunos4-lucid3.2.h +++ b/ace/config-sunos4-lucid3.2.h @@ -95,4 +95,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun3.x.h b/ace/config-sunos4-sun3.x.h index 911fb9d59ac..c7663580b8c 100644 --- a/ace/config-sunos4-sun3.x.h +++ b/ace/config-sunos4-sun3.x.h @@ -90,4 +90,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun4.1.4.h b/ace/config-sunos4-sun4.1.4.h index 1ea5ba21a97..751b0650b10 100644 --- a/ace/config-sunos4-sun4.1.4.h +++ b/ace/config-sunos4-sun4.1.4.h @@ -97,4 +97,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun4.x-orbix.h b/ace/config-sunos4-sun4.x-orbix.h index 41f60b10ed0..0d858623611 100644 --- a/ace/config-sunos4-sun4.x-orbix.h +++ b/ace/config-sunos4-sun4.x-orbix.h @@ -98,4 +98,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun4.x.h b/ace/config-sunos4-sun4.x.h index 00659f4b743..45c97f20113 100644 --- a/ace/config-sunos4-sun4.x.h +++ b/ace/config-sunos4-sun4.x.h @@ -95,4 +95,7 @@ #define ACE_NTRACE 1 #endif /* ACE_NTRACE */ +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-centerline-2.x.h b/ace/config-sunos5.4-centerline-2.x.h index 9af1adca45c..a8e6ba98375 100644 --- a/ace/config-sunos5.4-centerline-2.x.h +++ b/ace/config-sunos5.4-centerline-2.x.h @@ -168,4 +168,7 @@ // Defines the page size of the system. #define ACE_PAGE_SIZE 4096 +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-g++.h b/ace/config-sunos5.4-g++.h index 3cd11f036cf..26a5bca87ff 100644 --- a/ace/config-sunos5.4-g++.h +++ b/ace/config-sunos5.4-g++.h @@ -178,4 +178,7 @@ // Defines the page size of the system. #define ACE_PAGE_SIZE 4096 +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-sunc++-4.x-orbix.h b/ace/config-sunos5.4-sunc++-4.x-orbix.h index d356414a905..691ca18aaef 100644 --- a/ace/config-sunos5.4-sunc++-4.x-orbix.h +++ b/ace/config-sunos5.4-sunc++-4.x-orbix.h @@ -187,4 +187,7 @@ // Defines the page size of the system. #define ACE_PAGE_SIZE 4096 +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-sunc++-4.x.h b/ace/config-sunos5.4-sunc++-4.x.h index 3a1b4eb8d34..2e8f2c37e88 100644 --- a/ace/config-sunos5.4-sunc++-4.x.h +++ b/ace/config-sunos5.4-sunc++-4.x.h @@ -185,4 +185,7 @@ // Defines the page size of the system. #define ACE_PAGE_SIZE 4096 +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.5-g++.h b/ace/config-sunos5.5-g++.h index d0bfc34feda..37aed0ecb05 100644 --- a/ace/config-sunos5.5-g++.h +++ b/ace/config-sunos5.5-g++.h @@ -201,4 +201,7 @@ #define ACE_HAS_STL_MAP_CONFLICT #define ACE_HAS_STL_QUEUE_CONFLICT +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.5-sunc++-4.x.h b/ace/config-sunos5.5-sunc++-4.x.h index dd476ff970c..850f54dd53a 100644 --- a/ace/config-sunos5.5-sunc++-4.x.h +++ b/ace/config-sunos5.5-sunc++-4.x.h @@ -226,4 +226,8 @@ #define ACE_HAS_STL_MAP_CONFLICT #define ACE_HAS_STL_QUEUE_CONFLICT + +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunx86-sunc++-4.x.h b/ace/config-sunx86-sunc++-4.x.h index e7a10386393..59930db605b 100644 --- a/ace/config-sunx86-sunc++-4.x.h +++ b/ace/config-sunx86-sunc++-4.x.h @@ -7,6 +7,9 @@ #if !defined (ACE_CONFIG_H) #define ACE_CONFIG_H +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + // Optimize ACE_Handle_Set for select(). #define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT diff --git a/ace/config-win32-common.h b/ace/config-win32-common.h index fa15deb0c33..48eed18cae2 100644 --- a/ace/config-win32-common.h +++ b/ace/config-win32-common.h @@ -32,6 +32,9 @@ #define ACE_LACKS_UNISTD_H #define ACE_LACKS_RLIMIT +// The OS bind() call will select the port if it's 0. +#define ACE_HAS_WILDCARD_BIND + #define ACE_SIZEOF_LONG_LONG 8 typedef unsigned __int64 ACE_UINT64; diff --git a/tests/Hash_Map_Manager_Test.cpp b/tests/Hash_Map_Manager_Test.cpp index 91ee29e109d..55f1e486009 100644 --- a/tests/Hash_Map_Manager_Test.cpp +++ b/tests/Hash_Map_Manager_Test.cpp @@ -10,16 +10,18 @@ // // = DESCRIPTION // This test illustrates the use of <ACE_Hash_Map_Manager> to -// maintain a hash table using strings. No command line arguments -// are needed to run this program. +// maintain a hash table using strings. In addition, it also +// illustrates how the <ACE_Static_Allocator> works in +// conjunction with the <ACE_Hash_Map_Manager>. // // = AUTHOR -// James Hu +// James Hu and Douglas C. Schmidt // // ============================================================================ #include "test_config.h" #include "ace/Hash_Map_Manager.h" +#include "ace/Malloc_T.h" #include "ace/SString.h" #include "ace/Synch.h" @@ -95,7 +97,7 @@ HASH_STRING_MAP::equal (char *const &id1, char *const &id2) ACE_Hash_Map_Reverse_Iterator<Dumb_String, Dumb_String, ACE_Null_Mutex> #define MAP_STRING Dumb_String -#define ENTRY ((char *)entry) +#define ENTRY ((char *) entry) Dumb_String::Dumb_String (char *s) : s_ (s ? ACE_OS::strdup (s) : s), @@ -158,67 +160,121 @@ Dumb_String::operator char * (void) const #endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */ -static const int MAX_HASH = 256; +struct String_Table +{ + char *key_; + char *value_; +}; -int -main (int, char *[]) +static String_Table string_table[] = { - ACE_START_TEST ("Hash_Map_Manager_Test"); + { "hello", + "guten Tag" + }, + { "goodbye", + "auf wiedersehen" + }, + { "funny", + "lustig" + }, + { 0, 0 } +}; - // Scoping below so that result of destruction can be seen in the log. - { - HASH_STRING_MAP hash (MAX_HASH); +static const int MAX_HASH = 256; - hash.bind ("hello", "guten Tag"); - hash.bind ("goodbye", "auf wiedersehen"); - hash.bind ("funny", "lustig"); +// @@ The following requires too much internal implementation +// information about the <ACE_Hash_Map_Manager>. We need to figure +// out how to simplify this. +static const POOL_SIZE = + sizeof (HASH_STRING_ENTRY) * 3 // Number of items in <string_table>. + + sizeof (HASH_STRING_ENTRY) * MAX_HASH; // Size of the Hash_Map_Manager table - MAP_STRING entry; +static ACE_Static_Allocator<POOL_SIZE> allocator; - if (hash.find ("hello", entry) == 0) - ACE_DEBUG ((LM_DEBUG, "`%s' found `%s'\n", "hello", ENTRY)); - if (hash.find ("goodbye", entry) == 0) - ACE_DEBUG ((LM_DEBUG, "`%s' found `%s'\n", "goodbye", ENTRY)); - if (hash.find ("funny", entry) == 0) - ACE_DEBUG ((LM_DEBUG, "`%s' found `%s'\n", "funny", ENTRY)); +static int +run_test (void) +{ + allocator.dump (); + + HASH_STRING_MAP hash (MAX_HASH, &allocator); + + size_t i; + + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.bind (string_table[i].key_, + string_table[i].value_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p failed for %s \n", + "bind", + string_table[i].key_), -1); + + MAP_STRING entry; + + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.find (string_table[i].key_, + entry) == 0) + ACE_DEBUG ((LM_DEBUG, + "`%s' found `%s'\n", + string_table[i].key_, + ENTRY)); + else + ACE_ERROR_RETURN ((LM_ERROR, + "`%s' not found\n", + string_table[i].key_), + -1); + + // Let's test the iterator while we are at it. + { + HASH_STRING_ENTRY *entry; + size_t i = 0; + + for (HASH_STRING_ITER hash_iter (hash); + hash_iter.next (entry) != 0; + hash_iter.advance (), i++) + ACE_DEBUG ((LM_DEBUG, "iterating (%d): [%s, %s]\n", + i, + (char *) entry->ext_id_, + (char *) entry->int_id_)); + } - // Let's test the iterator while we are at it. - { - HASH_STRING_ENTRY *entry; - size_t i = 0; - - for (HASH_STRING_ITER hash_iter (hash); - hash_iter.next (entry) != 0; - hash_iter.advance (), i++) - ACE_DEBUG ((LM_DEBUG, "iterating (%d): [%s, %s]\n", - i, - (char *) entry->ext_id_, - (char *) entry->int_id_)); - } + hash.unbind (string_table[2].key_, entry); + + for (i = 0; string_table[i].key_ != 0; i++) + if (hash.find (string_table[i].key_, + entry) == 0) + ACE_DEBUG ((LM_DEBUG, + "`%s' found `%s'\n", + string_table[i].key_, + ENTRY)); + else if (i != 2) + ACE_ERROR_RETURN ((LM_ERROR, + "`%s' not found\n", + string_table[i].key_), + -1); + + // Let's test the iterator backwards. + { + HASH_STRING_ENTRY *entry; + size_t i = 0; + + for (HASH_STRING_REVERSE_ITER hash_iter (hash); + hash_iter.next (entry) != 0; + hash_iter.advance (), i++) + ACE_DEBUG ((LM_DEBUG, "iterating (%d): [%s, %s]\n", + i, + (char *) entry->ext_id_, + (char *) entry->int_id_)); + } - hash.unbind ("goodbye", entry); + allocator.dump (); +} - if (hash.find ("hello", entry) == 0) - ACE_DEBUG ((LM_DEBUG, "`%s' found `%s'\n", "hello", ENTRY)); - if (hash.find ("goodbye", entry) == 0) - ACE_DEBUG ((LM_DEBUG, "OOPS! `%s' found `%s'\n", "goodbye", ENTRY)); - if (hash.find ("funny", entry) == 0) - ACE_DEBUG ((LM_DEBUG, "`%s' found `%s'\n", "funny", ENTRY)); +int +main (int, char *[]) +{ + ACE_START_TEST ("Hash_Map_Manager_Test"); - // Let's test the iterator backwards. - { - HASH_STRING_ENTRY *entry; - size_t i = 0; - - for (HASH_STRING_REVERSE_ITER hash_iter (hash); - hash_iter.next (entry) != 0; - hash_iter.advance (), i++) - ACE_DEBUG ((LM_DEBUG, "iterating (%d): [%s, %s]\n", - i, - (char *) entry->ext_id_, - (char *) entry->int_id_)); - } - } + run_test (); ACE_END_TEST; diff --git a/tests/Hash_Map_Manager_Test.h b/tests/Hash_Map_Manager_Test.h index 1e0dfade60d..0dbfc5d7a21 100644 --- a/tests/Hash_Map_Manager_Test.h +++ b/tests/Hash_Map_Manager_Test.h @@ -14,14 +14,14 @@ // // ============================================================================ -#ifndef HASH_MAP_MANAGER_TEST_H +#if !defined (HASH_MAP_MANAGER_TEST_H) #define HASH_MAP_MANAGER_TEST_H class Dumb_String +{ // = DESCRIPTION // Desperate times call for desperate measures. Bug your compiler // vendor to support template specialization. -{ public: Dumb_String (char *s = 0); // Default constructor @@ -38,7 +38,7 @@ public: int operator== (const Dumb_String &ds) const; // To satisfy Hash_Map_Manager - char * operator= (const Dumb_String &ds); + char *operator= (const Dumb_String &ds); // To satisfy Hash_Map_Manager int operator== (char const * s) const; @@ -46,14 +46,14 @@ public: // These make life a little easier private: - char * s_; - // the string + char *s_; + // The string. int ©_; - // reference counter + // Reference counter. int junk_; - // default reference counter initializer + // default reference counter initializer. }; #endif /* HASH_MAP_MANAGER_TEST_H */ |