summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog-98a22
-rw-r--r--ace/ACE.cpp8
-rw-r--r--ace/Malloc.h31
-rw-r--r--ace/Malloc_T.cpp30
-rw-r--r--ace/Malloc_T.h43
-rw-r--r--ace/Malloc_T.i126
-rw-r--r--ace/OS.h4
-rw-r--r--ace/OS.i24
-rw-r--r--ace/README1
-rw-r--r--ace/config-irix6.x-g++.h3
-rw-r--r--ace/config-irix6.x-sgic++-nothreads.h3
-rw-r--r--ace/config-irix6.x-sgic++.h3
-rw-r--r--ace/config-sunos4-g++.h2
-rw-r--r--ace/config-sunos4-lucid3.2.h3
-rw-r--r--ace/config-sunos4-sun3.x.h3
-rw-r--r--ace/config-sunos4-sun4.1.4.h3
-rw-r--r--ace/config-sunos4-sun4.x-orbix.h3
-rw-r--r--ace/config-sunos4-sun4.x.h3
-rw-r--r--ace/config-sunos5.4-centerline-2.x.h3
-rw-r--r--ace/config-sunos5.4-g++.h3
-rw-r--r--ace/config-sunos5.4-sunc++-4.x-orbix.h3
-rw-r--r--ace/config-sunos5.4-sunc++-4.x.h3
-rw-r--r--ace/config-sunos5.5-g++.h3
-rw-r--r--ace/config-sunos5.5-sunc++-4.x.h4
-rw-r--r--ace/config-sunx86-sunc++-4.x.h3
-rw-r--r--ace/config-win32-common.h3
-rw-r--r--tests/Hash_Map_Manager_Test.cpp166
-rw-r--r--tests/Hash_Map_Manager_Test.h14
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));
+}
diff --git a/ace/OS.h b/ace/OS.h
index 735283e3b75..7b81f6fb295 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -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);
diff --git a/ace/OS.i b/ace/OS.i
index 7e6c5f1f016..d7f8cde0970 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -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 &copy_;
- // reference counter
+ // Reference counter.
int junk_;
- // default reference counter initializer
+ // default reference counter initializer.
};
#endif /* HASH_MAP_MANAGER_TEST_H */