summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjtc <jtc@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2004-10-11 18:46:56 +0000
committerjtc <jtc@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2004-10-11 18:46:56 +0000
commita060cde8d37b75e0f52a971e785173fbebdfbdc8 (patch)
tree66e9a4720d3b3596dc27eff38ee6b6ed7f67658a
parent1dae2ac679b1e4dbbf27e394111d7f45f39fb409 (diff)
downloadATCD-a060cde8d37b75e0f52a971e785173fbebdfbdc8.tar.gz
ChangeLogTag: Mon Oct 11 10:14:36 2004 J.T. Conklin <jtc@acorntoolworks.com>
-rw-r--r--ChangeLog40
-rw-r--r--ace/Local_Memory_Pool.cpp148
-rw-r--r--ace/Local_Memory_Pool.h128
-rw-r--r--ace/MMAP_Memory_Pool.cpp518
-rw-r--r--ace/MMAP_Memory_Pool.h288
-rw-r--r--ace/Makefile.am15
-rw-r--r--ace/Memory_Pool.cpp1352
-rw-r--r--ace/Memory_Pool.h794
-rw-r--r--ace/Memory_Pool.inl269
-rw-r--r--ace/Pagefile_Memory_Pool.cpp362
-rw-r--r--ace/Pagefile_Memory_Pool.h192
-rw-r--r--ace/Pagefile_Memory_Pool.inl48
-rw-r--r--ace/Sbrk_Memory_Pool.cpp119
-rw-r--r--ace/Sbrk_Memory_Pool.h107
-rw-r--r--ace/Shared_Memory_Pool.cpp449
-rw-r--r--ace/Shared_Memory_Pool.h200
-rw-r--r--ace/ace.mpc6
-rw-r--r--examples/System_V_IPC/SV_Semaphores/Semaphores_1.cpp1
-rw-r--r--tests/SV_Shared_Memory_Test.cpp3
19 files changed, 2625 insertions, 2414 deletions
diff --git a/ChangeLog b/ChangeLog
index 0d7d4425907..911a2c9838b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+Mon Oct 11 10:14:36 2004 J.T. Conklin <jtc@acorntoolworks.com>
+
+ * examples/System_V_IPC/SV_Semaphores/Semaphores_1.cpp:
+ * tests/SV_Shared_Memory_Test.cpp:
+
+ Changed to #include ace/SV_Sempahore_Complex.h, which had been
+ implicitly included via Memory_Pool.h, even though it was not
+ needed by the interface or implementation.
+
+ * ace/Makefile.am:
+ * ace/ace.mpc:
+
+ Updated.
+
+ * ace/Local_Memory_Pool.cpp:
+ * ace/Local_Memory_Pool.h:
+ * ace/MMAP_Memory_Pool.cpp:
+ * ace/MMAP_Memory_Pool.h:
+ * ace/Pagefile_Memory_Pool.cpp:
+ * ace/Pagefile_Memory_Pool.h:
+ * ace/Pagefile_Memory_Pool.inl:
+ * ace/Sbrk_Memory_Pool.cpp:
+ * ace/Sbrk_Memory_Pool.h:
+ * ace/Shared_Memory_Pool.cpp:
+ * ace/Shared_Memory_Pool.h:
+
+ New files.
+
+ * ace/Memory_Pool.cpp:
+ * ace/Memory_Pool.inl:
+ * ace/Memory_Pool.h:
+
+ Split apart Memory_Pool.{cpp,h,inl} into a separate set of files
+ for each class and "outlining" inlined virtual functions. Since
+ the implementations are related by interface, not inheritance;
+ locating them all in the same file typically results in static
+ footprint bloat.
+
+ Removed Memory_Pool.{cpp,inl}.
+
Mon Oct 10 12:48:03 2004 Martin Corino <mcorino@remedy.nl>
* ace/config-hpux-11.00.h:
diff --git a/ace/Local_Memory_Pool.cpp b/ace/Local_Memory_Pool.cpp
new file mode 100644
index 00000000000..8f12592e871
--- /dev/null
+++ b/ace/Local_Memory_Pool.cpp
@@ -0,0 +1,148 @@
+// $Id$
+
+// Local_Memory_Pool.cpp
+#include "ace/Local_Memory_Pool.h"
+#include "ace/Auto_Ptr.h"
+
+ACE_RCSID(ace, Local_Memory_Pool, "$Id$")
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Local_Memory_Pool)
+
+void
+ACE_Local_Memory_Pool::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_Local_Memory_Pool::dump");
+#endif /* ACE_HAS_DUMP */
+}
+
+ACE_Local_Memory_Pool::ACE_Local_Memory_Pool (const ACE_TCHAR *,
+ const OPTIONS *)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::ACE_Local_Memory_Pool");
+}
+
+ACE_Local_Memory_Pool::~ACE_Local_Memory_Pool (void)
+{
+ // Free up all memory allocated by this pool.
+ this->release ();
+}
+
+// Ask system for initial chunk of local memory.
+void *
+ACE_Local_Memory_Pool::init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::init_acquire");
+ // Note that we assume that when ACE_Local_Memory_Pool is used,
+ // ACE_Malloc's constructor will only get called once. If this
+ // assumption doesn't hold, we are in deep trouble!
+
+ first_time = 1;
+ return this->acquire (nbytes, rounded_bytes);
+}
+
+void *
+ACE_Local_Memory_Pool::acquire (size_t nbytes,
+ size_t &rounded_bytes)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::acquire");
+ rounded_bytes = this->round_up (nbytes);
+
+ char *temp = 0;
+ ACE_NEW_RETURN (temp,
+ char[rounded_bytes],
+ 0);
+
+ ACE_Auto_Basic_Array_Ptr<char> cp (temp);
+
+ if (this->allocated_chunks_.insert (cp.get ()) != 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) insertion into set failed\n")),
+ 0);
+
+ return cp.release ();
+}
+
+int
+ACE_Local_Memory_Pool::release (int)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::release");
+
+ // Zap the memory we allocated.
+ for (ACE_Unbounded_Set<char *>::iterator i = this->allocated_chunks_.begin ();
+ i != this->allocated_chunks_.end ();
+ ++i)
+ delete [] *i;
+ this->allocated_chunks_.reset ();
+ return 0;
+}
+
+int
+ACE_Local_Memory_Pool::sync (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Local_Memory_Pool::sync (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Local_Memory_Pool::protect (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::protect");
+ return 0;
+}
+
+int
+ACE_Local_Memory_Pool::protect (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::protect");
+ return 0;
+}
+
+#if defined (ACE_WIN32)
+int
+ACE_Local_Memory_Pool::seh_selector (void *)
+{
+ return 0;
+ // Continue propagate the structural exception up.
+}
+#endif /* ACE_WIN32 */
+
+int
+ACE_Local_Memory_Pool::remap (void *)
+{
+ return 0;
+ // Not much can be done.
+}
+
+void *
+ACE_Local_Memory_Pool::base_addr (void) const
+{
+ return 0;
+}
+
+// Let the underlying new operator figure out the alignment...
+size_t
+ACE_Local_Memory_Pool::round_up (size_t nbytes)
+{
+ ACE_TRACE ("ACE_Local_Memory_Pool::round_up");
+ return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Auto_Basic_Array_Ptr<char>;
+template class ACE_Unbounded_Set<char *>;
+template class ACE_Unbounded_Set_Iterator<char *>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Auto_Basic_Array_Ptr<char>
+#pragma instantiate ACE_Unbounded_Set<char *>
+#pragma instantiate ACE_Unbounded_Set_Iterator<char *>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/ace/Local_Memory_Pool.h b/ace/Local_Memory_Pool.h
new file mode 100644
index 00000000000..a4a0add9ff6
--- /dev/null
+++ b/ace/Local_Memory_Pool.h
@@ -0,0 +1,128 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Memory_Pool.h
+ *
+ * $Id$
+ *
+ * @author Dougls C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Prashant Jain <pjain@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_LOCAL_MEMORY_POOL_H
+#define ACE_LOCAL_MEMORY_POOL_H
+#include /**/ "ace/pre.h"
+
+#include "ace/ACE.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Unbounded_Set.h"
+
+/**
+ * @class ACE_Local_Memory_Pool_Options
+ *
+ * @brief Helper class for Local Memory Pool constructor options.
+ *
+ * This should be a nested class, but that breaks too many
+ * compilers.
+ */
+class ACE_Export ACE_Local_Memory_Pool_Options
+{
+};
+
+/**
+ * @class ACE_Local_Memory_Pool
+ *
+ * @brief Make a memory pool that is based on C++ new/delete. This is
+ * useful for integrating existing components that use new/delete
+ * into the ACE Malloc scheme...
+ */
+class ACE_Export ACE_Local_Memory_Pool
+{
+public:
+ typedef ACE_Local_Memory_Pool_Options OPTIONS;
+
+ /// Initialize the pool.
+ ACE_Local_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
+ const OPTIONS *options = 0);
+
+ virtual ~ACE_Local_Memory_Pool (void);
+
+ /// Ask system for initial chunk of local memory.
+ virtual void *init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time);
+
+ /// Acquire at least @a nbytes from the memory pool. @a rounded_bytes is
+ /// the actual number of bytes allocated.
+ virtual void *acquire (size_t nbytes,
+ size_t &rounded_bytes);
+
+ /// Instruct the memory pool to release all of its resources.
+ virtual int release (int destroy = 1);
+
+ /**
+ * Sync <len> bytes of the memory region to the backing store
+ * starting at <this->base_addr_>. If <len> == -1 then sync the
+ * whole region.
+ */
+ virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
+
+ /// Sync <len> bytes of the memory region to the backing store
+ /// starting at <addr_>.
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+
+ /**
+ * Change the protection of the pages of the mapped region to <prot>
+ * starting at <this->base_addr_> up to <len> bytes. If <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 <prot>
+ /// starting at <addr> up to <len> bytes.
+ virtual int protect (void *addr, size_t len, int prot = PROT_RDWR);
+
+#if defined (ACE_WIN32)
+ /**
+ * Win32 Structural exception selector. The return value decides
+ * how to handle memory pool related structural exceptions. Returns
+ * 1, 0, or , -1.
+ */
+ virtual int seh_selector (void *);
+#endif /* ACE_WIN32 */
+
+ /**
+ * Try to extend the virtual address space so that <addr> is now
+ * covered by the address mapping. Always returns 0 since we can't
+ * remap a local memory pool.
+ */
+ virtual int remap (void *addr);
+
+ /// Return the base address of this memory pool, 0 if base_addr
+ /// never changes.
+ virtual void *base_addr (void) const;
+
+ /// Dump the state of an object.
+ virtual void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+protected:
+ /// List of memory that we have allocated.
+ ACE_Unbounded_Set<char *> allocated_chunks_;
+
+ /// Implement the algorithm for rounding up the request to an
+ /// appropriate chunksize.
+ virtual size_t round_up (size_t nbytes);
+
+};
+
+#include /**/ "ace/post.h"
+#endif /* ACE_LOCAL_MEMORY_POOL_H */
diff --git a/ace/MMAP_Memory_Pool.cpp b/ace/MMAP_Memory_Pool.cpp
new file mode 100644
index 00000000000..85800b3ecd8
--- /dev/null
+++ b/ace/MMAP_Memory_Pool.cpp
@@ -0,0 +1,518 @@
+// $Id$
+
+// MMAP_Memory_Pool.cpp
+#include "ace/MMAP_Memory_Pool.h"
+#include "ace/OS_NS_sys_mman.h"
+#include "ace/OS_NS_unistd.h"
+
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+#include "ace/Based_Pointer_T.h"
+#include "ace/Based_Pointer_Repository.h"
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+
+ACE_RCSID(ace, MMAP_Memory_Pool, "$Id$")
+
+ACE_ALLOC_HOOK_DEFINE(ACE_MMAP_Memory_Pool)
+
+void
+ACE_MMAP_Memory_Pool::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::dump");
+#endif /* ACE_HAS_DUMP */
+}
+
+int
+ACE_MMAP_Memory_Pool::release (int destroy)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::release");
+
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+ ACE_BASED_POINTER_REPOSITORY::instance ()->unbind (this->mmap_.addr ());
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+
+ if (destroy)
+ this->mmap_.remove ();
+ else
+ this->mmap_.close ();
+ return 0;
+}
+
+int
+ACE_MMAP_Memory_Pool::sync (ssize_t len, int flags)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
+
+ if (len < 0)
+ len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
+
+ return this->mmap_.sync (len, flags);
+}
+
+// Sync <len> bytes of the memory region to the backing store starting
+// at <addr_>.
+
+int
+ACE_MMAP_Memory_Pool::sync (void *addr, size_t len, int flags)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
+ return ACE_OS::msync (addr, len, flags);
+}
+
+// Change the protection of the pages of the mapped region to <prot>
+// starting at <this->base_addr_> up to <len> bytes. If <len> == -1
+// then change protection of all pages in the mapped region.
+
+int
+ACE_MMAP_Memory_Pool::protect (ssize_t len, int prot)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
+
+ if (len < 0)
+ len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
+
+ return this->mmap_.protect (len, prot);
+}
+
+// Change the protection of the pages of the mapped region to <prot>
+// starting at <addr> up to <len> bytes.
+
+int
+ACE_MMAP_Memory_Pool::protect (void *addr, size_t len, int prot)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
+ return ACE_OS::mprotect (addr, len, prot);
+}
+
+ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
+ const OPTIONS *options)
+ : base_addr_ (0),
+ use_fixed_addr_(0),
+ flags_ (MAP_SHARED),
+ write_each_page_ (0),
+ minimum_bytes_ (0),
+ sa_ (0),
+ file_mode_ (ACE_DEFAULT_FILE_PERMS)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool");
+
+#if (defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)) || defined (ACE_WIN32)
+ // For plaforms that give the faulting address.
+ guess_on_fault_ = 0;
+#else
+ // For plaforms that do NOT give the faulting address, let the
+ // options decide whether to guess or not.
+ if (options)
+ guess_on_fault_ = options->guess_on_fault_;
+ else
+ // If no options are specified, default to true.
+ guess_on_fault_ = 1;
+#endif /* (defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)) || defined (ACE_WIN32) */
+
+ // Only change the defaults if <options> != 0.
+ if (options)
+ {
+ if (options->flags_ != 0)
+ this->flags_ = options->flags_;
+ use_fixed_addr_ = options->use_fixed_addr_;
+
+ if (use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED)
+ {
+ this->base_addr_ = const_cast<void *> (options->base_addr_);
+ ACE_SET_BITS (flags_, MAP_FIXED);
+ }
+ this->write_each_page_ = options->write_each_page_;
+ this->minimum_bytes_ = options->minimum_bytes_;
+ if (options->sa_ != 0)
+ this->sa_ = options->sa_;
+ this->file_mode_ = options->file_mode_;
+ }
+
+ if (backing_store_name == 0)
+ {
+ // Only create a new unique filename for the backing store file
+ // if the user didn't supply one...
+#if defined (ACE_DEFAULT_BACKING_STORE)
+ // Create a temporary file.
+ ACE_OS::strcpy (this->backing_store_name_,
+ ACE_DEFAULT_BACKING_STORE);
+#else /* ACE_DEFAULT_BACKING_STORE */
+ if (ACE::get_temp_dir (this->backing_store_name_,
+ MAXPATHLEN - 17) == -1)
+ // -17 for ace-malloc-XXXXXX
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("Temporary path too long, ")
+ ACE_LIB_TEXT ("defaulting to current directory\n")));
+ this->backing_store_name_[0] = 0;
+ }
+
+ // Add the filename to the end
+ ACE_OS::strcat (this->backing_store_name_,
+ ACE_LIB_TEXT ("ace-malloc-XXXXXX"));
+
+#endif /* ACE_DEFAULT_BACKING_STORE */
+ }
+ else
+ ACE_OS::strsncpy (this->backing_store_name_,
+ backing_store_name,
+ (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
+
+#if !defined (ACE_WIN32) && !defined (CHORUS)
+ if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n", this->backing_store_name_));
+#endif /* ACE_WIN32 */
+}
+
+ACE_MMAP_Memory_Pool::~ACE_MMAP_Memory_Pool (void)
+{
+}
+
+// Compute the new map_size of the backing store and commit the
+// memory.
+int
+ACE_MMAP_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
+ off_t &map_size)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store_name");
+
+#if defined (CHORUS)
+ map_size = rounded_bytes;
+#else
+ size_t seek_len;
+
+ if (this->write_each_page_)
+ // Write to the end of every block to ensure that we have enough
+ // space in the backing store.
+ seek_len = this->round_up (1); // round_up(1) is one page.
+ else
+ // We're willing to risk it all in the name of efficiency...
+ seek_len = rounded_bytes;
+
+ // The following loop will execute multiple times (if
+ // this->write_each_page == 1) or just once (if
+ // this->write_each_page == 0).
+
+ for (size_t cur_block = 0;
+ cur_block < rounded_bytes;
+ cur_block += seek_len)
+ {
+ map_size = ACE_OS::lseek (this->mmap_.handle (),
+ static_cast<off_t> (seek_len - 1),
+ SEEK_END);
+
+ if (map_size == -1
+ || ACE_OS::write (this->mmap_.handle (),
+ "",
+ 1) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ this->backing_store_name_),
+ -1);
+ }
+
+#if defined (ACE_OPENVMS)
+ ::fsync(this->mmap_.handle());
+#endif
+
+ // Increment by one to put us at the beginning of the next chunk...
+ map_size++;
+#endif /* CHORUS */
+ return 0;
+}
+
+// Memory map the file up to <map_size> bytes.
+
+int
+ACE_MMAP_Memory_Pool::map_file (off_t map_size)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::map_file");
+
+ // Unmap the existing mapping.
+ this->mmap_.unmap ();
+
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+ if(use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::NEVER_FIXED)
+ this->base_addr_ = 0;
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+
+ // Remap the file.
+ if (this->mmap_.map (map_size,
+ PROT_RDWR,
+ this->flags_,
+ this->base_addr_,
+ 0,
+ this->sa_) == -1
+ || this->base_addr_ != 0
+#ifdef ACE_HAS_WINCE
+ && this->mmap_.addr () == 0) // WinCE does not allow users to specify alloc addr.
+#else
+ && this->mmap_.addr () != this->base_addr_)
+#endif // ACE_HAS_WINCE
+ {
+#if 0
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) addr = %u, base_addr = %u, map_size = %u, %p\n"),
+ this->mmap_.addr (),
+ this->base_addr_,
+ map_size,
+ this->backing_store_name_));
+#endif /* 0 */
+ return -1;
+ }
+ else
+ {
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+ this->base_addr_ = this->mmap_.addr ();
+ ACE_BASED_POINTER_REPOSITORY::instance ()->bind (this->base_addr_,
+ map_size);
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+ return 0;
+ }
+}
+
+// Ask operating system for more shared memory, increasing the mapping
+// accordingly. Note that this routine assumes that the appropriate
+// locks are held when it is called.
+
+void *
+ACE_MMAP_Memory_Pool::acquire (size_t nbytes,
+ size_t &rounded_bytes)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::acquire");
+ rounded_bytes = this->round_up (nbytes);
+
+ // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquiring more chunks, nbytes =
+ // %d, rounded_bytes = %d\n", nbytes, rounded_bytes));
+
+ off_t map_size;
+
+ if (this->commit_backing_store_name (rounded_bytes,
+ map_size) == -1)
+ return 0;
+ else if (this->map_file (map_size) == -1)
+ return 0;
+
+ // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d,
+ // rounded_bytes = %d, map_size = %d\n", nbytes, rounded_bytes,
+ // map_size));
+
+ return (void *) ((char *) this->mmap_.addr () + (this->mmap_.size () - rounded_bytes));
+}
+
+// Ask system for initial chunk of shared memory.
+
+void *
+ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::init_acquire");
+
+ first_time = 0;
+
+ if (nbytes < (size_t) this->minimum_bytes_)
+ nbytes = this->minimum_bytes_;
+
+ if (this->mmap_.open (this->backing_store_name_,
+ O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
+ this->file_mode_, this->sa_) != -1)
+ {
+ // First time in, so need to acquire memory.
+ first_time = 1;
+ return this->acquire (nbytes, rounded_bytes);
+ }
+ else if (errno == EEXIST)
+ {
+ errno = 0;
+ // Reopen file *without* using O_EXCL...
+ if (this->mmap_.map (this->backing_store_name_,
+#if defined (CHORUS)
+ nbytes,
+#else
+ -1,
+#endif /* CHORUS */
+ O_RDWR,
+ this->file_mode_,
+ PROT_RDWR,
+ this->flags_,
+ this->base_addr_,
+ 0,
+ this->sa_) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("%p\n"),
+ ACE_LIB_TEXT ("open")),
+ 0);
+
+ return this->mmap_.addr ();
+ }
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("%p\n"),
+ ACE_LIB_TEXT ("open")),
+ 0);
+}
+
+#if defined (ACE_WIN32)
+int
+ACE_MMAP_Memory_Pool::seh_selector (void *ep)
+{
+ DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
+
+ if (ecode == EXCEPTION_ACCESS_VIOLATION)
+ {
+ void * fault_addr = (void *)
+ ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
+
+ if (this->remap (fault_addr) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+#endif /* ACE_WIN32 */
+
+int
+ACE_MMAP_Memory_Pool::remap (void *addr)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::remap");
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Remapping with fault address at: %X\n"), addr));
+ off_t current_map_size = ACE_OS::filesize (this->mmap_.handle ());
+ // ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
+
+ if (!(addr < (void *) ((char *) this->mmap_.addr () + current_map_size)
+ && addr >= this->mmap_.addr ()))
+ return -1;
+
+ // Extend the mapping to cover the size of the backing store.
+ return this->map_file (current_map_size);
+}
+
+ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options (const void *base_addr,
+ int use_fixed_addr,
+ int write_each_page,
+ off_t minimum_bytes,
+ u_int flags,
+ int guess_on_fault,
+ LPSECURITY_ATTRIBUTES sa,
+ mode_t file_mode)
+ : base_addr_ (base_addr),
+ use_fixed_addr_ (use_fixed_addr),
+ write_each_page_ (write_each_page),
+ minimum_bytes_ (minimum_bytes),
+ flags_ (flags),
+ guess_on_fault_ (guess_on_fault),
+ sa_ (sa),
+ file_mode_ (file_mode)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options");
+ // for backwards compatability
+ if (base_addr_ == 0 && use_fixed_addr_ == ALWAYS_FIXED)
+ use_fixed_addr_ = FIRSTCALL_FIXED;
+}
+
+// Handle SIGSEGV and SIGBUS signals to remap memory properly. When a
+// process reads or writes to non-mapped memory a signal (SIGBUS or
+// SIGSEGV) will be triggered. At that point, the ACE_Sig_Handler
+// (which is part of the ACE_Reactor) will catch the signal and
+// dispatch the handle_signal() method defined here. If the SIGSEGV
+// signal occurred due to the fact that the mapping wasn't uptodate
+// with respect to the backing store, the handler method below will
+// update the mapping accordingly. When the signal handler returns,
+// the instruction should be restarted and the operation should work.
+
+int
+ACE_MMAP_Memory_Pool::handle_signal (int signum, siginfo_t *siginfo, ucontext_t *)
+{
+ if (signum != SIGSEGV)
+ return -1;
+ else
+ ; // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) received %S\n"), signum));
+
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) new mapping address = %u\n"), (char *) this->base_addr_ + current_map_size));
+
+#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
+ // Make sure that the pointer causing the problem is within the
+ // range of the backing store.
+
+ if (siginfo != 0)
+ {
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) si_signo = %d, si_code = %d, addr = %u\n"), siginfo->si_signo, siginfo->si_code, siginfo->si_addr));
+ if (this->remap ((void *) siginfo->si_addr) == -1)
+ return -1;
+ // ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) address %u out of range\n",
+ // siginfo->si_addr), -1);
+ return 0;
+ }
+#else
+ ACE_UNUSED_ARG(siginfo);
+#endif /* ACE_HAS_SIGINFO_T && !defined ACE_LACKS_SI_ADDR */
+ // If guess_on_fault_ is true, then we want to try to remap without
+ // knowing the faulting address. guess_on_fault_ can only be true
+ // on platforms that do not provide the faulting address through
+ // signals or exceptions. We check to see if the mapping is up to
+ // date. If it is, then this fault isn't due to this mapping and we
+ // pass it on.
+ if (guess_on_fault_)
+ {
+ // Check if the current mapping is up to date.
+ off_t current_map_size = ACE_OS::filesize (this->mmap_.handle ());
+
+ if (static_cast<size_t> (current_map_size) == this->mmap_.size ())
+ {
+ // The mapping is up to date so this really is a bad
+ // address. Thus, remove current signal handler so process
+ // will fail with default action and core file will be
+ // written.
+ this->signal_handler_.remove_handler (SIGSEGV);
+ return 0;
+ }
+
+ // Extend the mapping to cover the size of the backing store.
+ return this->map_file (current_map_size);
+ }
+ else
+ return -1;
+}
+
+void *
+ACE_MMAP_Memory_Pool::base_addr (void) const
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::base_addr");
+ return this->base_addr_;
+}
+
+size_t
+ACE_MMAP_Memory_Pool::round_up (size_t nbytes)
+{
+ ACE_TRACE ("ACE_MMAP_Memory_Pool::round_up");
+ return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Lite_MMAP_Memory_Pool)
+
+ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
+ const OPTIONS *options)
+ : ACE_MMAP_Memory_Pool (backing_store_name, options)
+{
+ ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool");
+}
+
+ACE_Lite_MMAP_Memory_Pool::~ACE_Lite_MMAP_Memory_Pool (void)
+{
+}
+
+int
+ACE_Lite_MMAP_Memory_Pool::sync (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Lite_MMAP_Memory_Pool::sync (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
+ return 0;
+}
diff --git a/ace/MMAP_Memory_Pool.h b/ace/MMAP_Memory_Pool.h
new file mode 100644
index 00000000000..864bea00cbf
--- /dev/null
+++ b/ace/MMAP_Memory_Pool.h
@@ -0,0 +1,288 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Memory_Pool.h
+ *
+ * $Id$
+ *
+ * @author Dougls C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Prashant Jain <pjain@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_MMAP_MEMORY_POOL_H
+#define ACE_MMAP_MEMORY_POOL_H
+#include /**/ "ace/pre.h"
+
+#include "ace/ACE.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Event_Handler.h"
+#include "ace/Signal.h"
+#include "ace/Mem_Map.h"
+
+/**
+ * @class ACE_MMAP_Memory_Pool_Options
+ *
+ * @brief Helper class for MMAP Memory Pool constructor options.
+ *
+ * This should be a nested class, but that breaks too many
+ * compilers.
+ */
+class ACE_Export ACE_MMAP_Memory_Pool_Options
+{
+public:
+ enum
+ {
+ /**
+ * The base address from the first call to mmap will be used for subsequent
+ * calls to mmap.
+ */
+ FIRSTCALL_FIXED = 0,
+
+ /**
+ * The base address specified in base_addr will be used in all calls to
+ * mmap.
+ */
+ ALWAYS_FIXED = 1,
+
+ /**
+ * The base address will be selected by the OS for each call to mmap.
+ * Caution should be used with this mode since a call that requires the
+ * backing store to grow may change pointers that are cached by the
+ * application.
+ */
+ NEVER_FIXED = 2
+ };
+
+ // = Initialization method.
+ ACE_MMAP_Memory_Pool_Options (const void *base_addr = ACE_DEFAULT_BASE_ADDR,
+ int use_fixed_addr = ALWAYS_FIXED,
+ int write_each_page = 1,
+ off_t minimum_bytes = 0,
+ u_int flags = 0,
+ int guess_on_fault = 1,
+ LPSECURITY_ATTRIBUTES sa = 0,
+ mode_t file_mode = ACE_DEFAULT_FILE_PERMS);
+
+ /// Base address of the memory-mapped backing store.
+ const void *base_addr_;
+
+ /**
+ * Determines whether we set @c base_addr_ or if mmap(2) selects it
+ * FIRSTCALL_FIXED The base address from the first call to mmap
+ * will be used for subsequent calls to mmap
+ * ALWAYS_FIXED The base address specified in base_addr will be
+ * used in all calls to mmap.
+ * NEVER_FIXED The base address will be selected by the OS for
+ * each call to mmap. Caution should be used with
+ * this mode since a call that requires the backing
+ * store to grow may change pointers that are
+ * cached by the application.
+ */
+ int use_fixed_addr_;
+
+ /// Should each page be written eagerly to avoid surprises later
+ /// on?
+ int write_each_page_;
+
+ /// What the minimim bytes of the initial segment should be.
+ off_t minimum_bytes_;
+
+ /// Any special flags that need to be used for @c mmap.
+ u_int flags_;
+
+ /**
+ * Try to remap without knowing the faulting address. This
+ * parameter is ignored on platforms that know the faulting address
+ * (UNIX with SI_ADDR and Win32).
+ */
+ int guess_on_fault_;
+
+ /// Pointer to a security attributes object. Only used on NT.
+ LPSECURITY_ATTRIBUTES sa_;
+
+ /// File mode for mmaped file, if it is created.
+ mode_t file_mode_;
+};
+
+/**
+ * @class ACE_MMAP_Memory_Pool
+ *
+ * @brief Make a memory pool that is based on @c mmap(2). This
+ * implementation allows memory to be shared between processes.
+ */
+class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler
+{
+public:
+ typedef ACE_MMAP_Memory_Pool_Options OPTIONS;
+
+ // = Initialization and termination methods.
+
+ /// Initialize the pool.
+ ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
+ const OPTIONS *options = 0);
+
+ /// Destructor.
+ virtual ~ACE_MMAP_Memory_Pool (void);
+
+ /// Ask system for initial chunk of shared memory.
+ virtual void *init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time);
+
+ /**
+ * Acquire at least @a nbytes from the memory pool. @a rounded_bytes
+ * is the actual number of bytes allocated. Also acquires an
+ * internal semaphore that ensures proper serialization of
+ * ACE_MMAP_Memory_Pool initialization across processes.
+ */
+ virtual void *acquire (size_t nbytes,
+ size_t &rounded_bytes);
+
+ /// Instruct the memory pool to release all of its resources.
+ virtual int release (int destroy = 1);
+
+ /// Sync the memory region to the backing store starting at
+ /// @c this->base_addr_.
+ virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
+
+ /// Sync the memory region to the backing store starting at @a addr.
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+
+ /**
+ * Change the protection of the pages of the mapped region to <prot>
+ * starting at <this->base_addr_> up to <len> bytes. If <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);
+
+#if defined (ACE_WIN32)
+ /**
+ * Win32 Structural exception selector. The return value decides
+ * how to handle memory pool related structural exceptions. Returns
+ * 1, 0, or , -1.
+ */
+ virtual int seh_selector (void *);
+#endif /* ACE_WIN32 */
+
+ /**
+ * Try to extend the virtual address space so that @a addr is now
+ * covered by the address mapping. The method succeeds and returns
+ * 0 if the backing store has adequate memory to cover this address.
+ * Otherwise, it returns -1. This method is typically called by a
+ * UNIX signal handler for SIGSEGV or a Win32 structured exception
+ * when another process has grown the backing store (and its
+ * mapping) and our process now incurs a fault because our mapping
+ * isn't in range (yet).
+ */
+ virtual int remap (void *addr);
+
+ /// Return the base address of this memory pool.
+ virtual void *base_addr (void) const;
+
+ /// Dump the state of an object.
+ virtual void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+protected:
+ /// Implement the algorithm for rounding up the request to an
+ /// appropriate chunksize.
+ virtual size_t round_up (size_t nbytes);
+
+ /// Compute the new @a map_size of the backing store and commit the
+ /// memory.
+ virtual int commit_backing_store_name (size_t rounded_bytes,
+ off_t &map_size);
+
+ /// Memory map the file up to @a map_size bytes.
+ virtual int map_file (off_t map_size);
+
+ /// Handle SIGSEGV and SIGBUS signals to remap shared memory
+ /// properly.
+ virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
+
+ /// Handles SIGSEGV.
+ ACE_Sig_Handler signal_handler_;
+
+ /// Memory-mapping object.
+ ACE_Mem_Map mmap_;
+
+ /**
+ * Base of mapped region. If this has the value of 0 then the OS is
+ * free to select any address to map the file, otherwise this value
+ * is what the OS must try to use to mmap the file.
+ */
+ void *base_addr_;
+
+ /// Must we use the @c base_addr_ or can we let mmap(2) select it?
+ int use_fixed_addr_;
+
+ /// Flags passed into <ACE_OS::mmap>.
+ int flags_;
+
+ /// Should we write a byte to each page to forceably allocate memory
+ /// for this backing store?
+ int write_each_page_;
+
+ /// What the minimum bytes of the initial segment should be.
+ off_t minimum_bytes_;
+
+ /// Name of the backing store where the shared memory pool is kept.
+ ACE_TCHAR backing_store_name_[MAXPATHLEN + 1];
+
+ /**
+ * Try to remap without knowing the faulting address. This
+ * parameter is ignored on platforms that know the faulting address
+ * (UNIX with SI_ADDR and Win32).
+ */
+ int guess_on_fault_;
+
+ /// Security attributes object, only used on NT.
+ LPSECURITY_ATTRIBUTES sa_;
+
+ /// Protection mode for mmaped file.
+ mode_t file_mode_;
+};
+
+/**
+ * @class ACE_Lite_MMAP_Memory_Pool
+ *
+ * @brief Make a ``lighter-weight'' memory pool based <ACE_Mem_Map>.
+ *
+ * This implementation allows memory to be shared between
+ * processes. However, unlike the <ACE_MMAP_Memory_Pool>
+ * the <sync> methods are no-ops, which means that we don't pay
+ * for the price of flushing the memory to the backing store on
+ * every update. Naturally, this trades off increased
+ * performance for less reliability if the machine crashes.
+ */
+class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool
+{
+public:
+ /// Initialize the pool.
+ ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
+ const OPTIONS *options = 0);
+
+ /// Destructor.
+ virtual ~ACE_Lite_MMAP_Memory_Pool (void);
+
+ /// Overwrite the default sync behavior with no-op
+ virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
+
+ /// Overwrite the default sync behavior with no-op
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+};
+
+#include /**/ "ace/post.h"
+#endif /* ACE_MMAP_MEMORY_POOL_H */
diff --git a/ace/Makefile.am b/ace/Makefile.am
index ad77a83e45c..0fb01af0677 100644
--- a/ace/Makefile.am
+++ b/ace/Makefile.am
@@ -316,18 +316,22 @@ Streams = \
Memory = \
Based_Pointer_Repository.cpp \
+ Local_Memory_Pool.cpp \
+ MMAP_Memory_Pool.cpp \
Malloc.cpp \
Malloc_Allocator.cpp \
Malloc_Instantiations.cpp \
Mem_Map.cpp \
- Memory_Pool.cpp \
Obchunk.cpp \
Obstack.cpp \
+ Pagefile_Memory_Pool.cpp \
PI_Malloc.cpp \
Read_Buffer.cpp \
+ Sbrk_Memory_Pool.cpp \
Shared_Memory.cpp \
Shared_Memory_MM.cpp \
- Shared_Memory_SV.cpp
+ Shared_Memory_SV.cpp \
+ Shared_Memory_Pool.cpp
Timer = \
Basic_Stats.cpp \
@@ -510,6 +514,7 @@ nobase_include_HEADERS = \
LSOCK_Dgram.h \
LSOCK_Stream.h \
Lib_Find.h \
+ Local_Memory_Pool.h \
Local_Name_Space.h \
Local_Name_Space_T.h \
Local_Tokens.h \
@@ -530,6 +535,7 @@ nobase_include_HEADERS = \
MEM_IO.h \
MEM_SAP.h \
MEM_Stream.h \
+ MMAP_Memory_Pool.h \
Malloc.h \
Malloc_Allocator.h \
Malloc_Base.h \
@@ -615,6 +621,7 @@ nobase_include_HEADERS = \
POSIX_Asynch_IO.h \
POSIX_CB_Proactor.h \
POSIX_Proactor.h \
+ Pagefile_Memory_Pool.h \
Pair.h \
Pair_T.h \
Parse_Node.h \
@@ -673,6 +680,7 @@ nobase_include_HEADERS = \
SV_Semaphore_Simple.h \
SV_Shared_Memory.h \
Sample_History.h \
+ Sbrk_Memory_Pool.h \
Sched_Params.h \
Select_Reactor.h \
Select_Reactor_Base.h \
@@ -687,6 +695,7 @@ nobase_include_HEADERS = \
Shared_Memory.h \
Shared_Memory_MM.h \
Shared_Memory_SV.h \
+ Shared_Memory_Pool.h \
Shared_Object.h \
Signal.h \
Singleton.h \
@@ -984,7 +993,6 @@ nobase_include_HEADERS = \
Map_Manager.inl \
Map_T.inl \
Mem_Map.inl \
- Memory_Pool.inl \
Message_Block.inl \
Message_Block_T.inl \
Message_Queue.inl \
@@ -1039,6 +1047,7 @@ nobase_include_HEADERS = \
PI_Malloc.inl \
POSIX_CB_Proactor.inl \
POSIX_Proactor.inl \
+ Pagefile_Memory_Pool.inl \
Pair_T.inl \
Parse_Node.inl \
Ping_Socket.inl \
diff --git a/ace/Memory_Pool.cpp b/ace/Memory_Pool.cpp
deleted file mode 100644
index e5de1f19fdf..00000000000
--- a/ace/Memory_Pool.cpp
+++ /dev/null
@@ -1,1352 +0,0 @@
-// $Id$
-
-// Memory_Pool.cpp
-#include "ace/Memory_Pool.h"
-
-#if !defined (__ACE_INLINE__)
-#include "ace/Memory_Pool.inl"
-#endif /* __ACE_INLINE__ */
-
-#include "ace/Log_Msg.h"
-#include "ace/Auto_Ptr.h"
-#include "ace/RW_Thread_Mutex.h"
-#include "ace/OS_NS_sys_mman.h"
-#include "ace/OS_NS_string.h"
-#include "ace/OS_NS_sys_stat.h"
-#include "ace/OS_NS_sys_shm.h"
-#include "ace/OS_NS_unistd.h"
-
-#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
-#include "ace/Based_Pointer_T.h"
-#include "ace/Based_Pointer_Repository.h"
-#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
-
-ACE_RCSID(ace, Memory_Pool, "$Id$")
-
-ACE_ALLOC_HOOK_DEFINE(ACE_Local_Memory_Pool)
-
-void
-ACE_Local_Memory_Pool::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- ACE_TRACE ("ACE_Local_Memory_Pool::dump");
-#endif /* ACE_HAS_DUMP */
-}
-
-ACE_Local_Memory_Pool::ACE_Local_Memory_Pool (const ACE_TCHAR *,
- const OPTIONS *)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::ACE_Local_Memory_Pool");
-}
-
-void *
-ACE_Local_Memory_Pool::acquire (size_t nbytes,
- size_t &rounded_bytes)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::acquire");
- rounded_bytes = this->round_up (nbytes);
-
- char *temp = 0;
- ACE_NEW_RETURN (temp,
- char[rounded_bytes],
- 0);
-
- ACE_Auto_Basic_Array_Ptr<char> cp (temp);
-
- if (this->allocated_chunks_.insert (cp.get ()) != 0)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) insertion into set failed\n")),
- 0);
-
- return cp.release ();
-}
-
-int
-ACE_Local_Memory_Pool::release (int)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::release");
-
- // Zap the memory we allocated.
- for (ACE_Unbounded_Set<char *>::iterator i = this->allocated_chunks_.begin ();
- i != this->allocated_chunks_.end ();
- ++i)
- delete [] *i;
- this->allocated_chunks_.reset ();
- return 0;
-}
-
-#if defined (ACE_WIN32)
-int
-ACE_Local_Memory_Pool::seh_selector (void *)
-{
- return 0;
- // Continue propagate the structural exception up.
-}
-#endif /* ACE_WIN32 */
-
-int
-ACE_Local_Memory_Pool::remap (void *)
-{
- return 0;
- // Not much can be done.
-}
-
-ACE_ALLOC_HOOK_DEFINE(ACE_MMAP_Memory_Pool)
-
-void
-ACE_MMAP_Memory_Pool::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- ACE_TRACE ("ACE_MMAP_Memory_Pool::dump");
-#endif /* ACE_HAS_DUMP */
-}
-
-int
-ACE_MMAP_Memory_Pool::release (int destroy)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::release");
-
-#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
- ACE_BASED_POINTER_REPOSITORY::instance ()->unbind (this->mmap_.addr ());
-#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
-
- if (destroy)
- this->mmap_.remove ();
- else
- this->mmap_.close ();
- return 0;
-}
-
-int
-ACE_MMAP_Memory_Pool::sync (ssize_t len, int flags)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
-
- if (len < 0)
- len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
-
- return this->mmap_.sync (len, flags);
-}
-
-// Sync <len> bytes of the memory region to the backing store starting
-// at <addr_>.
-
-int
-ACE_MMAP_Memory_Pool::sync (void *addr, size_t len, int flags)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
- return ACE_OS::msync (addr, len, flags);
-}
-
-// Change the protection of the pages of the mapped region to <prot>
-// starting at <this->base_addr_> up to <len> bytes. If <len> == -1
-// then change protection of all pages in the mapped region.
-
-int
-ACE_MMAP_Memory_Pool::protect (ssize_t len, int prot)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
-
- if (len < 0)
- len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
-
- return this->mmap_.protect (len, prot);
-}
-
-// Change the protection of the pages of the mapped region to <prot>
-// starting at <addr> up to <len> bytes.
-
-int
-ACE_MMAP_Memory_Pool::protect (void *addr, size_t len, int prot)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
- return ACE_OS::mprotect (addr, len, prot);
-}
-
-ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
- const OPTIONS *options)
- : base_addr_ (0),
- use_fixed_addr_(0),
- flags_ (MAP_SHARED),
- write_each_page_ (0),
- minimum_bytes_ (0),
- sa_ (0),
- file_mode_ (ACE_DEFAULT_FILE_PERMS)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool");
-
-#if (defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)) || defined (ACE_WIN32)
- // For plaforms that give the faulting address.
- guess_on_fault_ = 0;
-#else
- // For plaforms that do NOT give the faulting address, let the
- // options decide whether to guess or not.
- if (options)
- guess_on_fault_ = options->guess_on_fault_;
- else
- // If no options are specified, default to true.
- guess_on_fault_ = 1;
-#endif /* (defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)) || defined (ACE_WIN32) */
-
- // Only change the defaults if <options> != 0.
- if (options)
- {
- if (options->flags_ != 0)
- this->flags_ = options->flags_;
- use_fixed_addr_ = options->use_fixed_addr_;
-
- if (use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED)
- {
- this->base_addr_ = const_cast<void *> (options->base_addr_);
- ACE_SET_BITS (flags_, MAP_FIXED);
- }
- this->write_each_page_ = options->write_each_page_;
- this->minimum_bytes_ = options->minimum_bytes_;
- if (options->sa_ != 0)
- this->sa_ = options->sa_;
- this->file_mode_ = options->file_mode_;
- }
-
- if (backing_store_name == 0)
- {
- // Only create a new unique filename for the backing store file
- // if the user didn't supply one...
-#if defined (ACE_DEFAULT_BACKING_STORE)
- // Create a temporary file.
- ACE_OS::strcpy (this->backing_store_name_,
- ACE_DEFAULT_BACKING_STORE);
-#else /* ACE_DEFAULT_BACKING_STORE */
- if (ACE::get_temp_dir (this->backing_store_name_,
- MAXPATHLEN - 17) == -1)
- // -17 for ace-malloc-XXXXXX
- {
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("Temporary path too long, ")
- ACE_LIB_TEXT ("defaulting to current directory\n")));
- this->backing_store_name_[0] = 0;
- }
-
- // Add the filename to the end
- ACE_OS::strcat (this->backing_store_name_,
- ACE_LIB_TEXT ("ace-malloc-XXXXXX"));
-
-#endif /* ACE_DEFAULT_BACKING_STORE */
- }
- else
- ACE_OS::strsncpy (this->backing_store_name_,
- backing_store_name,
- (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
-
-#if !defined (ACE_WIN32) && !defined (CHORUS)
- if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
- ACE_ERROR ((LM_ERROR,
- "%p\n", this->backing_store_name_));
-#endif /* ACE_WIN32 */
-}
-
-// Compute the new map_size of the backing store and commit the
-// memory.
-int
-ACE_MMAP_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
- off_t &map_size)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store_name");
-
-#if defined (CHORUS)
- map_size = rounded_bytes;
-#else
- size_t seek_len;
-
- if (this->write_each_page_)
- // Write to the end of every block to ensure that we have enough
- // space in the backing store.
- seek_len = this->round_up (1); // round_up(1) is one page.
- else
- // We're willing to risk it all in the name of efficiency...
- seek_len = rounded_bytes;
-
- // The following loop will execute multiple times (if
- // this->write_each_page == 1) or just once (if
- // this->write_each_page == 0).
-
- for (size_t cur_block = 0;
- cur_block < rounded_bytes;
- cur_block += seek_len)
- {
- map_size = ACE_OS::lseek (this->mmap_.handle (),
- static_cast<off_t> (seek_len - 1),
- SEEK_END);
-
- if (map_size == -1
- || ACE_OS::write (this->mmap_.handle (),
- "",
- 1) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- this->backing_store_name_),
- -1);
- }
-
-#if defined (ACE_OPENVMS)
- ::fsync(this->mmap_.handle());
-#endif
-
- // Increment by one to put us at the beginning of the next chunk...
- map_size++;
-#endif /* CHORUS */
- return 0;
-}
-
-// Memory map the file up to <map_size> bytes.
-
-int
-ACE_MMAP_Memory_Pool::map_file (off_t map_size)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::map_file");
-
- // Unmap the existing mapping.
- this->mmap_.unmap ();
-
-#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
- if(use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::NEVER_FIXED)
- this->base_addr_ = 0;
-#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
-
- // Remap the file.
- if (this->mmap_.map (map_size,
- PROT_RDWR,
- this->flags_,
- this->base_addr_,
- 0,
- this->sa_) == -1
- || this->base_addr_ != 0
-#ifdef ACE_HAS_WINCE
- && this->mmap_.addr () == 0) // WinCE does not allow users to specify alloc addr.
-#else
- && this->mmap_.addr () != this->base_addr_)
-#endif // ACE_HAS_WINCE
- {
-#if 0
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) addr = %u, base_addr = %u, map_size = %u, %p\n"),
- this->mmap_.addr (),
- this->base_addr_,
- map_size,
- this->backing_store_name_));
-#endif /* 0 */
- return -1;
- }
- else
- {
-#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
- this->base_addr_ = this->mmap_.addr ();
- ACE_BASED_POINTER_REPOSITORY::instance ()->bind (this->base_addr_,
- map_size);
-#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
- return 0;
- }
-}
-
-// Ask operating system for more shared memory, increasing the mapping
-// accordingly. Note that this routine assumes that the appropriate
-// locks are held when it is called.
-
-void *
-ACE_MMAP_Memory_Pool::acquire (size_t nbytes,
- size_t &rounded_bytes)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::acquire");
- rounded_bytes = this->round_up (nbytes);
-
- // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquiring more chunks, nbytes =
- // %d, rounded_bytes = %d\n", nbytes, rounded_bytes));
-
- off_t map_size;
-
- if (this->commit_backing_store_name (rounded_bytes,
- map_size) == -1)
- return 0;
- else if (this->map_file (map_size) == -1)
- return 0;
-
- // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d,
- // rounded_bytes = %d, map_size = %d\n", nbytes, rounded_bytes,
- // map_size));
-
- return (void *) ((char *) this->mmap_.addr () + (this->mmap_.size () - rounded_bytes));
-}
-
-// Ask system for initial chunk of shared memory.
-
-void *
-ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::init_acquire");
-
- first_time = 0;
-
- if (nbytes < (size_t) this->minimum_bytes_)
- nbytes = this->minimum_bytes_;
-
- if (this->mmap_.open (this->backing_store_name_,
- O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
- this->file_mode_, this->sa_) != -1)
- {
- // First time in, so need to acquire memory.
- first_time = 1;
- return this->acquire (nbytes, rounded_bytes);
- }
- else if (errno == EEXIST)
- {
- errno = 0;
- // Reopen file *without* using O_EXCL...
- if (this->mmap_.map (this->backing_store_name_,
-#if defined (CHORUS)
- nbytes,
-#else
- -1,
-#endif /* CHORUS */
- O_RDWR,
- this->file_mode_,
- PROT_RDWR,
- this->flags_,
- this->base_addr_,
- 0,
- this->sa_) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("open")),
- 0);
-
- return this->mmap_.addr ();
- }
- else
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("open")),
- 0);
-}
-
-#if defined (ACE_WIN32)
-int
-ACE_MMAP_Memory_Pool::seh_selector (void *ep)
-{
- DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
-
- if (ecode == EXCEPTION_ACCESS_VIOLATION)
- {
- void * fault_addr = (void *)
- ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
-
- if (this->remap (fault_addr) == 0)
- return 1;
- }
-
- return 0;
-}
-#endif /* ACE_WIN32 */
-
-int
-ACE_MMAP_Memory_Pool::remap (void *addr)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::remap");
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Remapping with fault address at: %X\n"), addr));
- off_t current_map_size = ACE_OS::filesize (this->mmap_.handle ());
- // ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
-
- if (!(addr < (void *) ((char *) this->mmap_.addr () + current_map_size)
- && addr >= this->mmap_.addr ()))
- return -1;
-
- // Extend the mapping to cover the size of the backing store.
- return this->map_file (current_map_size);
-}
-
-ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options (const void *base_addr,
- int use_fixed_addr,
- int write_each_page,
- off_t minimum_bytes,
- u_int flags,
- int guess_on_fault,
- LPSECURITY_ATTRIBUTES sa,
- mode_t file_mode)
- : base_addr_ (base_addr),
- use_fixed_addr_ (use_fixed_addr),
- write_each_page_ (write_each_page),
- minimum_bytes_ (minimum_bytes),
- flags_ (flags),
- guess_on_fault_ (guess_on_fault),
- sa_ (sa),
- file_mode_ (file_mode)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options");
- // for backwards compatability
- if (base_addr_ == 0 && use_fixed_addr_ == ALWAYS_FIXED)
- use_fixed_addr_ = FIRSTCALL_FIXED;
-}
-
-// Handle SIGSEGV and SIGBUS signals to remap memory properly. When a
-// process reads or writes to non-mapped memory a signal (SIGBUS or
-// SIGSEGV) will be triggered. At that point, the ACE_Sig_Handler
-// (which is part of the ACE_Reactor) will catch the signal and
-// dispatch the handle_signal() method defined here. If the SIGSEGV
-// signal occurred due to the fact that the mapping wasn't uptodate
-// with respect to the backing store, the handler method below will
-// update the mapping accordingly. When the signal handler returns,
-// the instruction should be restarted and the operation should work.
-
-int
-ACE_MMAP_Memory_Pool::handle_signal (int signum, siginfo_t *siginfo, ucontext_t *)
-{
- if (signum != SIGSEGV)
- return -1;
- else
- ; // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) received %S\n"), signum));
-
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) new mapping address = %u\n"), (char *) this->base_addr_ + current_map_size));
-
-#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
- // Make sure that the pointer causing the problem is within the
- // range of the backing store.
-
- if (siginfo != 0)
- {
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) si_signo = %d, si_code = %d, addr = %u\n"), siginfo->si_signo, siginfo->si_code, siginfo->si_addr));
- if (this->remap ((void *) siginfo->si_addr) == -1)
- return -1;
- // ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) address %u out of range\n",
- // siginfo->si_addr), -1);
- return 0;
- }
-#else
- ACE_UNUSED_ARG(siginfo);
-#endif /* ACE_HAS_SIGINFO_T && !defined ACE_LACKS_SI_ADDR */
- // If guess_on_fault_ is true, then we want to try to remap without
- // knowing the faulting address. guess_on_fault_ can only be true
- // on platforms that do not provide the faulting address through
- // signals or exceptions. We check to see if the mapping is up to
- // date. If it is, then this fault isn't due to this mapping and we
- // pass it on.
- if (guess_on_fault_)
- {
- // Check if the current mapping is up to date.
- off_t current_map_size = ACE_OS::filesize (this->mmap_.handle ());
-
- if (static_cast<size_t> (current_map_size) == this->mmap_.size ())
- {
- // The mapping is up to date so this really is a bad
- // address. Thus, remove current signal handler so process
- // will fail with default action and core file will be
- // written.
- this->signal_handler_.remove_handler (SIGSEGV);
- return 0;
- }
-
- // Extend the mapping to cover the size of the backing store.
- return this->map_file (current_map_size);
- }
- else
- return -1;
-}
-
-ACE_ALLOC_HOOK_DEFINE(ACE_Lite_MMAP_Memory_Pool)
-
-ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
- const OPTIONS *options)
- : ACE_MMAP_Memory_Pool (backing_store_name, options)
-{
- ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool");
-}
-
-int
-ACE_Lite_MMAP_Memory_Pool::sync (ssize_t, int)
-{
- ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
- return 0;
-}
-
-int
-ACE_Lite_MMAP_Memory_Pool::sync (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
- return 0;
-}
-
-#if !defined (ACE_LACKS_SBRK)
-ACE_ALLOC_HOOK_DEFINE(ACE_Sbrk_Memory_Pool)
-
-// Ask system for more local memory via sbrk(2).
-
-void *
-ACE_Sbrk_Memory_Pool::acquire (size_t nbytes,
- size_t &rounded_bytes)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::acquire");
- rounded_bytes = this->round_up (nbytes);
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes));
- void *cp = ACE_OS::sbrk (rounded_bytes);
-
- if (cp == MAP_FAILED)
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) cp = %u\n",
- cp),
- 0);
- else
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d, new break = %u\n"), nbytes, rounded_bytes, cp));
- return cp;
-}
-
-void
-ACE_Sbrk_Memory_Pool::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::dump");
-#endif /* ACE_HAS_DUMP */
-}
-
-ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool (const ACE_TCHAR *,
- const OPTIONS *)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool");
-}
-#endif /* !ACE_LACKS_SBRK */
-
-#if !defined (ACE_LACKS_SYSV_SHMEM)
-ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_Pool)
-
-ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options (const char *base_addr,
- size_t max_segments,
- size_t file_perms,
- off_t minimum_bytes,
- size_t segment_size)
- : base_addr_ (base_addr),
- max_segments_ (max_segments),
- minimum_bytes_ (minimum_bytes),
- file_perms_ (file_perms),
- segment_size_ (segment_size)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options");
-}
-
-void
-ACE_Shared_Memory_Pool::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- ACE_TRACE ("ACE_Shared_Memory_Pool::dump");
-#endif /* ACE_HAS_DUMP */
-}
-
-int
-ACE_Shared_Memory_Pool::in_use (off_t &offset,
- size_t &counter)
-{
- offset = 0;
- SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
- shmid_ds buf;
-
- for (counter = 0;
- counter < this->max_segments_ && st[counter].used_ == 1;
- counter++)
- {
- if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("shmctl")),
- -1);
- offset += buf.shm_segsz;
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset));
- }
-
- return 0;
-}
-
-int
-ACE_Shared_Memory_Pool::find_seg (const void* const searchPtr,
- off_t &offset,
- size_t &counter)
-{
- offset = 0;
- SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
- shmid_ds buf;
-
- for (counter = 0;
- counter < this->max_segments_
- && st[counter].used_ == 1;
- counter++)
- {
- if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("shmctl")),
- -1);
- offset += buf.shm_segsz;
-
- // If segment 'counter' starts at a location greater than the
- // place we are searching for. We then decrement the offset to
- // the start of counter-1. (flabar@vais.net)
- if (((ptrdiff_t) offset + (ptrdiff_t) (this->base_addr_)) > (ptrdiff_t) searchPtr)
- {
- --counter;
- offset -= buf.shm_segsz;
- return 0;
- }
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset));
- }
-
- return 0;
-}
-
-int
-ACE_Shared_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
- off_t &offset)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::commit_backing_store_name");
-
- size_t counter;
- SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
-
- if (this->in_use (offset, counter) == -1)
- return -1;
-
- if (counter == this->max_segments_)
- ACE_ERROR_RETURN ((LM_ERROR,
- "exceeded max number of segments = %d, base = %u, offset = %u\n",
- counter,
- this->base_addr_,
- offset),
- -1);
- else
- {
- int shmid = ACE_OS::shmget (st[counter].key_,
- rounded_bytes,
- this->file_perms_ | IPC_CREAT | IPC_EXCL);
- if (shmid == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("shmget")),
- -1);
- st[counter].shmid_ = shmid;
- st[counter].used_ = 1;
-
- void *address = (void *) (((char *) this->base_addr_) + offset);
- void *shmem = ACE_OS::shmat (st[counter].shmid_,
- (char *) address,
- 0);
-
- if (shmem != address)
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) %p, shmem = %u, address = %u\n",
- "shmat",
- shmem,
- address),
- -1);
- }
- return 0;
-}
-
-// Handle SIGSEGV and SIGBUS signals to remap shared memory properly.
-
-int
-ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::handle_signal");
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("signal %S occurred\n"), signum));
-
-#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
- off_t offset;
- // Make sure that the pointer causing the problem is within the
- // range of the backing store.
-
- if (siginfo != 0)
- {
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) si_signo = %d, si_code = %d, addr = %u\n"), siginfo->si_signo, siginfo->si_code, siginfo->si_addr));
- size_t counter;
- if (this->in_use (offset, counter) == -1)
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("in_use")));
-#if !defined(_UNICOS)
- else if (!(siginfo->si_code == SEGV_MAPERR
- && siginfo->si_addr < (((char *) this->base_addr_) + offset)
- && siginfo->si_addr >= ((char *) this->base_addr_)))
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) address %u out of range\n",
- siginfo->si_addr),
- -1);
-#else /* ! _UNICOS */
- else if (!(siginfo->si_code == SEGV_MEMERR
- && siginfo->si_addr < (((unsigned long) this->base_addr_) + offset)
- && siginfo->si_addr >= ((unsigned long) this->base_addr_)))
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) address %u out of range\n",
- siginfo->si_addr),
- -1);
-#endif /* ! _UNICOS */
- }
-
- // The above if case will check to see that the address is in the
- // proper range. Therefore there is a segment out there that the
- // pointer wants to point into. Find the segment that someone else
- // has used and attach to it (flabar@vais.net)
-
- size_t counter; // ret value to get shmid from the st table.
-
-#if !defined(_UNICOS)
- if (this->find_seg (siginfo->si_addr, offset, counter) == -1)
-#else /* ! _UNICOS */
- if (this->find_seg ((const void *)siginfo->si_addr, offset, counter) == -1)
-#endif /* ! _UNICOS */
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("in_use")),
- -1);
-
- void *address = (void *) (((char *) this->base_addr_) + offset);
- SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
-
- void *shmem = ACE_OS::shmat (st[counter].shmid_, (char *) address, 0);
-
- if (shmem != address)
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) %p, shmem = %u, address = %u\n",
- "shmat",
- shmem,
- address),
- -1);
-
- // NOTE: this won't work if we dont have SIGINFO_T or SI_ADDR
-#else
- ACE_UNUSED_ARG (siginfo);
-#endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */
-
- return 0;
-}
-
-ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name,
- const OPTIONS *options)
- : base_addr_ (0),
- file_perms_ (ACE_DEFAULT_FILE_PERMS),
- max_segments_ (ACE_DEFAULT_MAX_SEGMENTS),
- minimum_bytes_ (0),
- segment_size_ (ACE_DEFAULT_SEGMENT_SIZE)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool");
-
- // Only change the defaults if <options> != 0.
- if (options)
- {
- this->base_addr_ =
- reinterpret_cast<void *> (const_cast<char *> (options->base_addr_));
- this->max_segments_ = options->max_segments_;
- this->file_perms_ = options->file_perms_;
- this->minimum_bytes_ = options->minimum_bytes_;
- this->segment_size_ = options->segment_size_;
- }
-
- if (backing_store_name)
- {
- // Convert the string into a number that is used as the segment
- // key.
-
- int segment_key;
- int result = ::sscanf (ACE_TEXT_ALWAYS_CHAR (backing_store_name),
- "%d",
- &segment_key);
-
- if (result == 0 || result == EOF)
- // The conversion to a number failed so hash with crc32
- // ACE::crc32 is also used in <SV_Semaphore_Simple>.
- this->base_shm_key_ =
- (key_t) ACE::crc32 (ACE_TEXT_ALWAYS_CHAR (backing_store_name));
- else
- this->base_shm_key_ = segment_key;
-
- if (this->base_shm_key_ == IPC_PRIVATE)
- // Make sure that the segment can be shared between unrelated
- // processes.
- this->base_shm_key_ = ACE_DEFAULT_SHM_KEY;
- }
- else
- this->base_shm_key_ = ACE_DEFAULT_SHM_KEY;
-
- if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE_Sig_Handler::register_handler")));
-}
-
-// Ask system for more shared memory.
-
-void *
-ACE_Shared_Memory_Pool::acquire (size_t nbytes,
- size_t &rounded_bytes)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::acquire");
-
- rounded_bytes = this->round_up (nbytes);
-
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes));
-
- off_t offset;
-
- if (this->commit_backing_store_name (rounded_bytes, offset) == -1)
- return 0;
-
- // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes));
- return ((char *) this->base_addr_) + offset;
-}
-
-// Ask system for initial chunk of shared memory.
-
-void *
-ACE_Shared_Memory_Pool::init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire");
-
- off_t shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE));
- rounded_bytes = this->round_up (nbytes > (size_t) this->minimum_bytes_
- ? nbytes
- : (size_t) this->minimum_bytes_);
-
- // Acquire the semaphore to serialize initialization and prevent
- // race conditions.
-
- int shmid = ACE_OS::shmget (this->base_shm_key_,
- rounded_bytes + shm_table_offset,
- this->file_perms_ | IPC_CREAT | IPC_EXCL);
- if (shmid == -1)
- {
- if (errno != EEXIST)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("shmget")),
- 0);
- first_time = 0;
-
- shmid = ACE_OS::shmget (this->base_shm_key_, 0, 0);
-
- if (shmid == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("(%P|%t) %p\n"),
- ACE_LIB_TEXT ("shmget")),
- 0);
-
- // This implementation doesn't care if we don't get the key we
- // want...
- this->base_addr_ =
- ACE_OS::shmat (shmid,
- reinterpret_cast<char *> (this->base_addr_),
- 0);
- if (this->base_addr_ == reinterpret_cast<void *> (-1))
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) %p, base_addr = %u\n",
- "shmat",
- this->base_addr_),
- 0);
- }
- else
- {
- first_time = 1;
-
- // This implementation doesn't care if we don't get the key we
- // want...
- this->base_addr_ =
- ACE_OS::shmat (shmid,
- reinterpret_cast<char *> (this->base_addr_),
- 0);
- if (this->base_addr_ == reinterpret_cast<char *> (-1))
- ACE_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) %p, base_addr = %u\n",
- "shmat",
- this->base_addr_), 0);
-
- SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
- st[0].key_ = this->base_shm_key_;
- st[0].shmid_ = shmid;
-
- st[0].used_ = 1;
-
- for (size_t counter = 1; // Skip over the first entry...
- counter < this->max_segments_;
- counter++)
- {
- st[counter].key_ = this->base_shm_key_ + counter;
- st[counter].shmid_ = 0;
- st[counter].used_ = 0;
- }
- }
-
- return (void *) (((char *) this->base_addr_) + shm_table_offset);
-}
-
-// Instruct the memory pool to release all of its resources.
-
-int
-ACE_Shared_Memory_Pool::release (int)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::release");
-
- int result = 0;
- SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
-
- for (size_t counter = 0;
- counter < this->max_segments_ && st[counter].used_ == 1;
- counter++)
- if (ACE_OS::shmctl (st[counter].shmid_, IPC_RMID, 0) == -1)
- result = -1;
-
- return result;
-}
-#endif /* !ACE_LACKS_SYSV_SHMEM */
-
-#if defined (ACE_WIN32)
-#if !defined (ACE_HAS_WINCE)
-#define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
- MapViewOfFileEx (_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)
-#else //if !defined (ACE_HAS_WINCE)
-#define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
- MapViewOfFile (_hnd, _access, _offHigh, _offLow, _nBytes)
-#endif /* !defined (ACE_HAS_WINCE) */
-
-ACE_Pagefile_Memory_Pool_Options::ACE_Pagefile_Memory_Pool_Options (void *base_addr,
- size_t max_size)
- : base_addr_ (base_addr),
- max_size_ (max_size)
-{
-}
-
-int
-ACE_Pagefile_Memory_Pool::release (int)
-{
- return this->unmap ();
-}
-
-ACE_Pagefile_Memory_Pool::ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name,
- const OPTIONS *options)
- : shared_cb_ (0),
- object_handle_ (0),
- page_size_ (ACE_Pagefile_Memory_Pool::round_to_page_size (1))
-{
- // Initialize local copy of pool statistics.
- if (options != 0)
- {
- this->local_cb_.req_base_ = options->base_addr_;
- this->local_cb_.mapped_base_ = 0;
- this->local_cb_.sh_.max_size_ =
- options->max_size_;
- this->local_cb_.sh_.mapped_size_ = 0;
- this->local_cb_.sh_.free_offset_ =
- this->local_cb_.sh_.mapped_size_;
- this->local_cb_.sh_.free_size_ = 0;
- }
-
- if (backing_store_name == 0)
- // Only create a new unique filename for the backing store file if
- // the user didn't supply one...
- backing_store_name = ACE_DEFAULT_PAGEFILE_POOL_NAME;
-
- ACE_OS::strsncpy (this->backing_store_name_,
- backing_store_name,
- (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
-}
-
-void *
-ACE_Pagefile_Memory_Pool::acquire (size_t nbytes,
- size_t &rounded_bytes)
-{
- rounded_bytes = round_to_page_size (nbytes);
- void *result = 0;
- int first_time = 0;
-
- // Check local_cb_ for consistency. Remap, if extra space is too
- // small and/or we didn't map the whole shared memory section
- if (this->shared_cb_->sh_.mapped_size_
- > this->local_cb_.sh_.mapped_size_
- || this->shared_cb_->sh_.free_size_ < rounded_bytes)
- {
- size_t append = 0;
- if (rounded_bytes > this->shared_cb_->sh_.free_size_)
- append = rounded_bytes - this->shared_cb_->sh_.free_size_;
-
- if (this->map (first_time, append) < 0)
- return result;
- }
-
- // Get the block from extra space and update shared and local
- // control block
- if (this->shared_cb_->sh_.free_size_ < rounded_bytes)
- return result;
-
- result = (void *)((char *) this->local_cb_.mapped_base_
- + this->shared_cb_->sh_.free_offset_);
- this->shared_cb_->sh_.free_offset_ += rounded_bytes;
- this->shared_cb_->sh_.free_size_ -= rounded_bytes;
- this->local_cb_.sh_ = this->shared_cb_->sh_;
-
- return result;
-}
-
-void *
-ACE_Pagefile_Memory_Pool::init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time)
-{
- // Map the shared memory and get information, if we created the
- // shared memory.
- if (this->map (first_time) < 0)
- return 0;
-
- if (first_time != 0)
- // We created the shared memory. So we have to allocate the
- // requested memory.
- return this->acquire (nbytes, rounded_bytes);
- else
- // We just mapped the memory and return the base address
- return (void *)((char *) this->local_cb_.mapped_base_
- + ACE_Pagefile_Memory_Pool::round_to_page_size
- ((int) sizeof (Control_Block)));
-}
-
-int
-ACE_Pagefile_Memory_Pool::seh_selector (void *ep)
-{
- DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
-
- if (ecode == EXCEPTION_ACCESS_VIOLATION)
- {
- void * fault_addr = (void *)
- ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
-
- if (this->remap (fault_addr) == 0)
- return 1;
- }
-
- return 0;
-}
-
-int
-ACE_Pagefile_Memory_Pool::remap (void *addr)
-{
- // If the shared memory is not mapped or the address, that caused
- // the memory fault is outside of the commited range of chunks, we
- // return.
- if (this->shared_cb_ == 0
- || addr < this->local_cb_.mapped_base_
- || addr >= (void *)((char *) this->local_cb_.mapped_base_
- + this->shared_cb_->sh_.mapped_size_))
- return -1;
-
- // We can solve the problem by committing additional chunks.
- int first_time = 0;
- return this->map (first_time);
-}
-
-int
-ACE_Pagefile_Memory_Pool::unmap (void)
-{
-#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
- ACE_BASED_POINTER_REPOSITORY::instance ()->unbind
- (this->local_cb_.mapped_base_);
-#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
-
- // Cleanup cached pool pointer.
- this->shared_cb_ = 0;
-
- if (this->local_cb_.sh_.mapped_size_ > 0)
- ::UnmapViewOfFile (this->local_cb_.mapped_base_);
-
- // Reset local pool statistics.
- this->local_cb_.req_base_ =
- ACE_DEFAULT_PAGEFILE_POOL_BASE;
- this->local_cb_.mapped_base_ = 0;
- this->local_cb_.sh_.max_size_ =
- ACE_DEFAULT_PAGEFILE_POOL_SIZE;
- this->local_cb_.sh_.mapped_size_ = 0;
- this->local_cb_.sh_.free_offset_ =
- this->local_cb_.sh_.mapped_size_;
- this->local_cb_.sh_.free_size_ = 0;
-
- // Release the pool
- if (this->object_handle_ != 0)
- {
- ::CloseHandle (this->object_handle_);
- this->object_handle_ = 0;
- }
- return 0;
-}
-
-int
-ACE_Pagefile_Memory_Pool::map (int &first_time,
- size_t append_bytes)
-{
- size_t map_size;
- void *map_addr;
-
- // Create file mapping, if not yet done
- if (object_handle_ == 0)
- {
-#if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
- // Allow access by all users.
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
- ::InitializeSecurityDescriptor (&sd,
- SECURITY_DESCRIPTOR_REVISION);
- ::SetSecurityDescriptorDacl (&sd,
- TRUE,
- 0,
- FALSE);
- sa.nLength = sizeof (SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = &sd;
- sa.bInheritHandle = FALSE;
-#endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */
-
- // Get an object handle to the named reserved memory object.
- DWORD size_high;
- DWORD size_low;
-#if defined (ACE_WIN64)
- size_high = static_cast<DWORD> (this->local_cb_.sh_.max_size_ >> 32);
- size_low = static_cast<DWORD> (this->local_cb_.sh_.max_size_ & 0xFFFFFFFF);
-#else
- size_high = 0;
- size_low = this->local_cb_.sh_.max_size_;
-#endif
-
- object_handle_ =
- ACE_TEXT_CreateFileMapping (INVALID_HANDLE_VALUE,
-#if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
- &sa,
-#else
- 0,
-#endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */
- PAGE_READWRITE | SEC_RESERVE,
- size_high,
- size_low,
- this->backing_store_name_);
- if (object_handle_ == 0)
- return -1;
- first_time =
- ::GetLastError () == ERROR_ALREADY_EXISTS
- ? 0
- : 1;
- }
-
- // Do the initial mapping.
- if (this->shared_cb_ == 0)
- {
- // Map a view to the shared memory. Note: <MapViewOfFile[Ex]>
- // does *not* commit the pages!
- this->shared_cb_ = (ACE_Pagefile_Memory_Pool::Control_Block *)
- ACE_MAP_FILE (this->object_handle_,
- FILE_MAP_WRITE,
- 0,
- 0,
- this->local_cb_.sh_.max_size_,
- this->local_cb_.req_base_);
- if (this->shared_cb_ == 0)
- return -1;
-
- // There was no previous mapping, so we map the first chunk and
- // initialize the shared pool statistics.
- if (first_time)
- {
- // 1st block is used to keep shared memory statistics.
- map_size =
- ACE_Pagefile_Memory_Pool::round_to_chunk_size
- (ACE_Pagefile_Memory_Pool::round_to_page_size
- ((int) sizeof(Control_Block))
- + append_bytes);
-
- if (::VirtualAlloc ((void *) this->shared_cb_,
- map_size,
- MEM_COMMIT,
- PAGE_READWRITE) == 0)
- return -1;
-
- this->shared_cb_->req_base_ = 0;
- this->shared_cb_->mapped_base_ = 0;
- this->local_cb_.mapped_base_ = this->shared_cb_;
- this->local_cb_.sh_.mapped_size_ = map_size;
- this->local_cb_.sh_.free_offset_ =
- round_to_page_size ((int) sizeof (Control_Block));
- this->local_cb_.sh_.free_size_ =
- this->local_cb_.sh_.mapped_size_ -
- this->local_cb_.sh_.free_offset_;
- this->shared_cb_->sh_ = this->local_cb_.sh_;
- }
-
- // The shared memory exists, so we map the first chunk to the
- // base address of the pool to get the shared pool statistics.
- else
- {
- // 1st block is used to keep shared memory statistics.
- map_size =
- ACE_Pagefile_Memory_Pool::round_to_chunk_size
- ((int) sizeof (Control_Block));
-
- if (::VirtualAlloc ((void *) this->shared_cb_,
- map_size,
- MEM_COMMIT,
- PAGE_READWRITE) == 0)
- return -1;
- this->local_cb_.mapped_base_ = this->shared_cb_;
- this->local_cb_.sh_.mapped_size_ = map_size;
- }
- }
-
- // If the shared memory is larger than the part we've already
- // committed, we have to remap it.
- if (this->shared_cb_->sh_.mapped_size_ >
- this->local_cb_.sh_.mapped_size_
- || append_bytes > 0)
- {
- map_size =
- (this->shared_cb_->sh_.mapped_size_ -
- this->local_cb_.sh_.mapped_size_)
- + ACE_Pagefile_Memory_Pool::round_to_chunk_size
- (append_bytes);
-
- map_addr = (void *)((char *) this->shared_cb_ +
- this->local_cb_.sh_.mapped_size_);
-
- if (::VirtualAlloc (map_addr,
- map_size,
- MEM_COMMIT,
- PAGE_READWRITE) == 0)
- return -1;
- else if (append_bytes > 0)
- {
- this->shared_cb_->sh_.mapped_size_ +=
- round_to_chunk_size (append_bytes);
- this->shared_cb_->sh_.free_size_ =
- this->shared_cb_->sh_.mapped_size_ -
- this->shared_cb_->sh_.free_offset_;
- }
- }
-
- // Update local copy of the shared memory statistics.
- this->local_cb_.sh_ =
- this->shared_cb_->sh_;
-#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
- ACE_BASED_POINTER_REPOSITORY::instance ()->bind
- (this->local_cb_.mapped_base_,
- this->local_cb_.sh_.mapped_size_);
-#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
-
- return 0;
-}
-
-#endif /* ACE_WIN32 */
-
-#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-template class ACE_Auto_Basic_Array_Ptr<char>;
-template class ACE_Unbounded_Set<char *>;
-template class ACE_Unbounded_Set_Iterator<char *>;
-#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#pragma instantiate ACE_Auto_Basic_Array_Ptr<char>
-#pragma instantiate ACE_Unbounded_Set<char *>
-#pragma instantiate ACE_Unbounded_Set_Iterator<char *>
-#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/ace/Memory_Pool.h b/ace/Memory_Pool.h
index 521378370b6..628a6e09c24 100644
--- a/ace/Memory_Pool.h
+++ b/ace/Memory_Pool.h
@@ -21,795 +21,11 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "ace/Event_Handler.h"
-#include "ace/Signal.h"
-#include "ace/Mem_Map.h"
-#if !defined (ACE_WIN32)
-#include "ace/SV_Semaphore_Complex.h"
-#endif /* !ACE_WIN32 */
-
-#include "ace/Unbounded_Set.h"
-
-#if !defined (ACE_LACKS_SBRK)
-/**
- * @class ACE_Sbrk_Memory_Pool_Options
- *
- * @brief Helper class for Sbrk Memory Pool constructor options.
- *
- * This should be a nested class, but that breaks too many
- * compilers.
- */
-class ACE_Export ACE_Sbrk_Memory_Pool_Options
-{
-};
-
-/**
- * @class ACE_Sbrk_Memory_Pool
- *
- * @brief Make a memory pool that is based on <sbrk(2)>.
- */
-class ACE_Export ACE_Sbrk_Memory_Pool
-{
-public:
- typedef ACE_Sbrk_Memory_Pool_Options OPTIONS;
-
- /// Initialize the pool.
- ACE_Sbrk_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
- const OPTIONS *options = 0);
-
- virtual ~ACE_Sbrk_Memory_Pool (void);
-
- // = Implementor operations.
- /// Ask system for initial chunk of local memory.
- virtual void *init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time);
-
- /// Acquire at least @a nbytes from the memory pool. @a rounded_bytes is
- /// the actual number of bytes allocated.
- virtual void *acquire (size_t nbytes,
- size_t &rounded_bytes);
-
- /// Instruct the memory pool to release all of its resources.
- virtual int release (int destroy = 1);
-
- /**
- * 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 @a addr.
- virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
-
- /**
- * Change the protection of the pages of the mapped region to <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);
-
- /// Dump the state of an object.
- virtual void dump (void) const;
-
- /// Return the base address of this memory pool, 0 if base_addr
- /// never changes.
- virtual void *base_addr (void) const;
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
-protected:
- /// Implement the algorithm for rounding up the request to an
- /// appropriate chunksize.
- virtual size_t round_up (size_t nbytes);
-};
-#endif /* !ACE_LACKS_SBRK */
-
-#if !defined (ACE_LACKS_SYSV_SHMEM)
-
-/**
- * @class ACE_Shared_Memory_Pool_Options
- *
- * @brief Helper class for Shared Memory Pool constructor options.
- *
- * This should be a nested class, but that breaks too many
- * compilers.
- */
-class ACE_Export ACE_Shared_Memory_Pool_Options
-{
-public:
- /// Initialization method.
- ACE_Shared_Memory_Pool_Options (const char *base_addr = ACE_DEFAULT_BASE_ADDR,
- size_t max_segments = ACE_DEFAULT_MAX_SEGMENTS,
- size_t file_perms = ACE_DEFAULT_FILE_PERMS,
- off_t minimum_bytes = 0,
- size_t segment_size = ACE_DEFAULT_SEGMENT_SIZE);
-
- /// Base address of the memory-mapped backing store.
- const char *base_addr_;
-
- /// Number of shared memory segments to allocate.
- size_t max_segments_;
-
- /// What the minimum bytes of the initial segment should be.
- off_t minimum_bytes_;
-
- /// File permissions to use when creating/opening a segment.
- size_t file_perms_;
-
- /// Shared memory segment size.
- size_t segment_size_;
-};
-
-/**
- * @class ACE_Shared_Memory_Pool
- *
- * @brief Make a memory pool that is based on System V shared memory
- * (shmget(2) etc.). This implementation allows memory to be
- * shared between processes. If your platform doesn't support
- * System V shared memory (e.g., Win32 and many RTOS platforms
- * do not) then you should use ACE_MMAP_Memory_Pool instead of this
- * class. In fact, you should probably use ACE_MMAP_Memory_Pool on
- * platforms that *do* support System V shared memory since it
- * provides more powerful features, such as persistent backing store
- * and greatly scalability.
- */
-class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler
-{
-public:
- typedef ACE_Shared_Memory_Pool_Options OPTIONS;
-
- /// Initialize the pool.
- ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
- const OPTIONS *options = 0);
-
- virtual ~ACE_Shared_Memory_Pool (void);
-
- /// Ask system for initial chunk of local memory.
- virtual void *init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time);
-
- /**
- * Acquire at least @a nbytes from the memory pool. @a rounded_byes is
- * the actual number of bytes allocated. Also acquires an internal
- * semaphore that ensures proper serialization of Memory_Pool
- * initialization across processes.
- */
- virtual void *acquire (size_t nbytes,
- size_t &rounded_bytes);
-
- /// Instruct the memory pool to release all of its resources.
- virtual int release (int destroy = 1);
-
- /// Sync the memory region to the backing store starting at
- /// @c this->base_addr_.
- virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
-
- /// Sync the memory region to the backing store starting at @a addr.
- virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
-
- /**
- * Change the protection of the pages of the mapped region to <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 <prot>
- /// starting at <addr> up to <len> bytes.
- virtual int protect (void *addr, size_t len, int prot = PROT_RDWR);
-
- /// Return the base address of this memory pool, 0 if base_addr
- /// never changes.
- virtual void *base_addr (void) const;
-
- /// Dump the state of an object.
- virtual void dump (void) const;
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
-protected:
- /// Implement the algorithm for rounding up the request to an
- /// appropriate chunksize.
- virtual size_t round_up (size_t nbytes);
-
- /**
- * Commits a new shared memory segment if necessary after an
- * <acquire> or a signal. <offset> is set to the new offset into
- * the backing store.
- */
- virtual int commit_backing_store_name (size_t rounded_bytes,
- off_t &offset);
-
- /// Keeps track of all the segments being used.
- struct SHM_TABLE
- {
- /// Shared memory segment key.
- key_t key_;
-
- /// Shared memory segment internal id.
- int shmid_;
-
- /// Is the segment currently used.;
- int used_;
- };
-
- /**
- * Base address of the shared memory segment. If this has the value
- * of 0 then the OS is free to select any address, otherwise this
- * value is what the OS must try to use to map the shared memory
- * segment.
- */
- void *base_addr_;
-
- /// File permissions to use when creating/opening a segment.
- size_t file_perms_;
-
- /// Number of shared memory segments in the <SHM_TABLE> table.
- size_t max_segments_;
-
- /// What the minimim bytes of the initial segment should be.
- off_t minimum_bytes_;
-
- /// Shared memory segment size.
- size_t segment_size_;
-
- /// Base shared memory key for the segment.
- key_t base_shm_key_;
-
- /// Find the segment that contains the @a searchPtr
- virtual int find_seg (const void *const searchPtr,
- off_t &offset,
- size_t &counter);
-
- /// Determine how much memory is currently in use.
- virtual int in_use (off_t &offset,
- size_t &counter);
-
- /// Handles SIGSEGV.
- ACE_Sig_Handler signal_handler_;
-
- /// Handle SIGSEGV and SIGBUS signals to remap shared memory
- /// properly.
- virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
-};
-#endif /* !ACE_LACKS_SYSV_SHMEM */
-
-/**
- * @class ACE_Local_Memory_Pool_Options
- *
- * @brief Helper class for Local Memory Pool constructor options.
- *
- * This should be a nested class, but that breaks too many
- * compilers.
- */
-class ACE_Export ACE_Local_Memory_Pool_Options
-{
-};
-
-/**
- * @class ACE_Local_Memory_Pool
- *
- * @brief Make a memory pool that is based on C++ new/delete. This is
- * useful for integrating existing components that use new/delete
- * into the ACE Malloc scheme...
- */
-class ACE_Export ACE_Local_Memory_Pool
-{
-public:
- typedef ACE_Local_Memory_Pool_Options OPTIONS;
-
- /// Initialize the pool.
- ACE_Local_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
- const OPTIONS *options = 0);
-
- virtual ~ACE_Local_Memory_Pool (void);
-
- /// Ask system for initial chunk of local memory.
- virtual void *init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time);
-
- /// Acquire at least @a nbytes from the memory pool. @a rounded_bytes is
- /// the actual number of bytes allocated.
- virtual void *acquire (size_t nbytes,
- size_t &rounded_bytes);
-
- /// Instruct the memory pool to release all of its resources.
- virtual int release (int destroy = 1);
-
- /**
- * Sync <len> bytes of the memory region to the backing store
- * starting at <this->base_addr_>. If <len> == -1 then sync the
- * whole region.
- */
- virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
-
- /// Sync <len> bytes of the memory region to the backing store
- /// starting at <addr_>.
- virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
-
- /**
- * Change the protection of the pages of the mapped region to <prot>
- * starting at <this->base_addr_> up to <len> bytes. If <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 <prot>
- /// starting at <addr> up to <len> bytes.
- virtual int protect (void *addr, size_t len, int prot = PROT_RDWR);
-
-#if defined (ACE_WIN32)
- /**
- * Win32 Structural exception selector. The return value decides
- * how to handle memory pool related structural exceptions. Returns
- * 1, 0, or , -1.
- */
- virtual int seh_selector (void *);
-#endif /* ACE_WIN32 */
-
- /**
- * Try to extend the virtual address space so that <addr> is now
- * covered by the address mapping. Always returns 0 since we can't
- * remap a local memory pool.
- */
- virtual int remap (void *addr);
-
- /// Return the base address of this memory pool, 0 if base_addr
- /// never changes.
- virtual void *base_addr (void) const;
-
- /// Dump the state of an object.
- virtual void dump (void) const;
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
-protected:
- /// List of memory that we have allocated.
- ACE_Unbounded_Set<char *> allocated_chunks_;
-
- /// Implement the algorithm for rounding up the request to an
- /// appropriate chunksize.
- virtual size_t round_up (size_t nbytes);
-
-};
-
-/**
- * @class ACE_MMAP_Memory_Pool_Options
- *
- * @brief Helper class for MMAP Memory Pool constructor options.
- *
- * This should be a nested class, but that breaks too many
- * compilers.
- */
-class ACE_Export ACE_MMAP_Memory_Pool_Options
-{
-public:
- enum
- {
- /**
- * The base address from the first call to mmap will be used for subsequent
- * calls to mmap.
- */
- FIRSTCALL_FIXED = 0,
-
- /**
- * The base address specified in base_addr will be used in all calls to
- * mmap.
- */
- ALWAYS_FIXED = 1,
-
- /**
- * The base address will be selected by the OS for each call to mmap.
- * Caution should be used with this mode since a call that requires the
- * backing store to grow may change pointers that are cached by the
- * application.
- */
- NEVER_FIXED = 2
- };
-
- // = Initialization method.
- ACE_MMAP_Memory_Pool_Options (const void *base_addr = ACE_DEFAULT_BASE_ADDR,
- int use_fixed_addr = ALWAYS_FIXED,
- int write_each_page = 1,
- off_t minimum_bytes = 0,
- u_int flags = 0,
- int guess_on_fault = 1,
- LPSECURITY_ATTRIBUTES sa = 0,
- mode_t file_mode = ACE_DEFAULT_FILE_PERMS);
-
- /// Base address of the memory-mapped backing store.
- const void *base_addr_;
-
- /**
- * Determines whether we set @c base_addr_ or if mmap(2) selects it
- * FIRSTCALL_FIXED The base address from the first call to mmap
- * will be used for subsequent calls to mmap
- * ALWAYS_FIXED The base address specified in base_addr will be
- * used in all calls to mmap.
- * NEVER_FIXED The base address will be selected by the OS for
- * each call to mmap. Caution should be used with
- * this mode since a call that requires the backing
- * store to grow may change pointers that are
- * cached by the application.
- */
- int use_fixed_addr_;
-
- /// Should each page be written eagerly to avoid surprises later
- /// on?
- int write_each_page_;
-
- /// What the minimim bytes of the initial segment should be.
- off_t minimum_bytes_;
-
- /// Any special flags that need to be used for @c mmap.
- u_int flags_;
-
- /**
- * Try to remap without knowing the faulting address. This
- * parameter is ignored on platforms that know the faulting address
- * (UNIX with SI_ADDR and Win32).
- */
- int guess_on_fault_;
-
- /// Pointer to a security attributes object. Only used on NT.
- LPSECURITY_ATTRIBUTES sa_;
-
- /// File mode for mmaped file, if it is created.
- mode_t file_mode_;
-};
-
-/**
- * @class ACE_MMAP_Memory_Pool
- *
- * @brief Make a memory pool that is based on @c mmap(2). This
- * implementation allows memory to be shared between processes.
- */
-class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler
-{
-public:
- typedef ACE_MMAP_Memory_Pool_Options OPTIONS;
-
- // = Initialization and termination methods.
-
- /// Initialize the pool.
- ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
- const OPTIONS *options = 0);
-
- /// Destructor.
- virtual ~ACE_MMAP_Memory_Pool (void);
-
- /// Ask system for initial chunk of shared memory.
- virtual void *init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time);
-
- /**
- * Acquire at least @a nbytes from the memory pool. @a rounded_bytes
- * is the actual number of bytes allocated. Also acquires an
- * internal semaphore that ensures proper serialization of
- * ACE_MMAP_Memory_Pool initialization across processes.
- */
- virtual void *acquire (size_t nbytes,
- size_t &rounded_bytes);
-
- /// Instruct the memory pool to release all of its resources.
- virtual int release (int destroy = 1);
-
- /// Sync the memory region to the backing store starting at
- /// @c this->base_addr_.
- virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
-
- /// Sync the memory region to the backing store starting at @a addr.
- virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
-
- /**
- * Change the protection of the pages of the mapped region to <prot>
- * starting at <this->base_addr_> up to <len> bytes. If <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);
-
-#if defined (ACE_WIN32)
- /**
- * Win32 Structural exception selector. The return value decides
- * how to handle memory pool related structural exceptions. Returns
- * 1, 0, or , -1.
- */
- virtual int seh_selector (void *);
-#endif /* ACE_WIN32 */
-
- /**
- * Try to extend the virtual address space so that @a addr is now
- * covered by the address mapping. The method succeeds and returns
- * 0 if the backing store has adequate memory to cover this address.
- * Otherwise, it returns -1. This method is typically called by a
- * UNIX signal handler for SIGSEGV or a Win32 structured exception
- * when another process has grown the backing store (and its
- * mapping) and our process now incurs a fault because our mapping
- * isn't in range (yet).
- */
- virtual int remap (void *addr);
-
- /// Return the base address of this memory pool.
- virtual void *base_addr (void) const;
-
- /// Dump the state of an object.
- virtual void dump (void) const;
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
-protected:
- /// Implement the algorithm for rounding up the request to an
- /// appropriate chunksize.
- virtual size_t round_up (size_t nbytes);
-
- /// Compute the new @a map_size of the backing store and commit the
- /// memory.
- virtual int commit_backing_store_name (size_t rounded_bytes,
- off_t &map_size);
-
- /// Memory map the file up to @a map_size bytes.
- virtual int map_file (off_t map_size);
-
- /// Handle SIGSEGV and SIGBUS signals to remap shared memory
- /// properly.
- virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
-
- /// Handles SIGSEGV.
- ACE_Sig_Handler signal_handler_;
-
- /// Memory-mapping object.
- ACE_Mem_Map mmap_;
-
- /**
- * Base of mapped region. If this has the value of 0 then the OS is
- * free to select any address to map the file, otherwise this value
- * is what the OS must try to use to mmap the file.
- */
- void *base_addr_;
-
- /// Must we use the @c base_addr_ or can we let mmap(2) select it?
- int use_fixed_addr_;
-
- /// Flags passed into <ACE_OS::mmap>.
- int flags_;
-
- /// Should we write a byte to each page to forceably allocate memory
- /// for this backing store?
- int write_each_page_;
-
- /// What the minimum bytes of the initial segment should be.
- off_t minimum_bytes_;
-
- /// Name of the backing store where the shared memory pool is kept.
- ACE_TCHAR backing_store_name_[MAXPATHLEN + 1];
-
- /**
- * Try to remap without knowing the faulting address. This
- * parameter is ignored on platforms that know the faulting address
- * (UNIX with SI_ADDR and Win32).
- */
- int guess_on_fault_;
-
- /// Security attributes object, only used on NT.
- LPSECURITY_ATTRIBUTES sa_;
-
- /// Protection mode for mmaped file.
- mode_t file_mode_;
-};
-
-/**
- * @class ACE_Lite_MMAP_Memory_Pool
- *
- * @brief Make a ``lighter-weight'' memory pool based <ACE_Mem_Map>.
- *
- * This implementation allows memory to be shared between
- * processes. However, unlike the <ACE_MMAP_Memory_Pool>
- * the <sync> methods are no-ops, which means that we don't pay
- * for the price of flushing the memory to the backing store on
- * every update. Naturally, this trades off increased
- * performance for less reliability if the machine crashes.
- */
-class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool
-{
-public:
- /// Initialize the pool.
- ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
- const OPTIONS *options = 0);
-
- /// Destructor.
- virtual ~ACE_Lite_MMAP_Memory_Pool (void);
-
- /// Overwrite the default sync behavior with no-op
- virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
-
- /// Overwrite the default sync behavior with no-op
- virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
-};
-
-#if defined (ACE_WIN32)
-
-/**
- * @class ACE_Pagefile_Memory_Pool_Options
- *
- * @brief Helper class for Pagefile Memory Pool constructor options.
- *
- * This should be a nested class, but that breaks too many
- * compilers.
- */
-class ACE_Export ACE_Pagefile_Memory_Pool_Options
-{
-public:
- /// Initialization method.
- ACE_Pagefile_Memory_Pool_Options (void *base_addr = ACE_DEFAULT_PAGEFILE_POOL_BASE,
- size_t max_size = ACE_DEFAULT_PAGEFILE_POOL_SIZE);
-
- /// Base address of the memory-mapped backing store.
- void *base_addr_;
-
- /// Maximum size the pool may grow.
- size_t max_size_;
-};
-
-/**
- * @class ACE_Pagefile_Memory_Pool
- *
- * @brief Make a memory pool that is based on "anonymous" memory
- * regions allocated from the Win32 page file.
- */
-class ACE_Export ACE_Pagefile_Memory_Pool
-{
-public:
- typedef ACE_Pagefile_Memory_Pool_Options OPTIONS;
-
- /// Initialize the pool.
- ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
- const OPTIONS *options = 0);
-
- /// Ask system for initial chunk of shared memory.
- void *init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time);
-
- /// Acquire at least <nbytes> from the memory pool. <rounded_bytes>
- /// is the actual number of bytes allocated.
- void *acquire (size_t nbytes,
- size_t &rounded_bytes);
-
- /// Instruct the memory pool to release all of its resources.
- int release (int destroy = 1);
-
- /**
- * Win32 Structural exception selector. The return value decides
- * how to handle memory pool related structural exceptions. Returns
- * 1, 0, or , -1.
- */
- virtual int seh_selector (void *);
-
- /**
- * Try to extend the virtual address space so that <addr> is now
- * covered by the address mapping. The method succeeds and returns
- * 0 if the backing store has adequate memory to cover this address.
- * Otherwise, it returns -1. This method is typically called by an
- * exception handler for a Win32 structured exception when another
- * process has grown the backing store (and its mapping) and our
- * process now incurs a fault because our mapping isn't in range
- * (yet).
- */
- int remap (void *addr);
-
- /// Round up to system page size.
- size_t round_to_page_size (size_t nbytes);
-
- /// Round up to the chunk size required by the operation system
- size_t round_to_chunk_size (size_t nbytes);
-
- // = Don't need this methods here ...
- int sync (ssize_t = -1, int = MS_SYNC);
- int sync (void *, size_t, int = MS_SYNC);
- int protect (ssize_t = -1, int = PROT_RDWR);
- int protect (void *, size_t, int = PROT_RDWR);
-
- /// Return the base address of this memory pool, 0 if base_addr
- /// never changes.
- virtual void *base_addr (void) const;
-
- void dump (void) const {}
-
-protected:
-
- /**
- * Map portions or the entire pool into the local virtual address
- * space. To do this, we compute the new @c file_offset of the
- * backing store and commit the memory.
- */
- int map (int &firstTime, size_t appendBytes = 0);
-
- /// Release the mapping.
- int unmap (void);
-
-private:
-
- /**
- * @class Control_Block
- *
- * @brief Attributes that are meaningful in local storage only.
- */
- class Control_Block
- {
- public:
- /// Required base address
- void *req_base_;
-
- /// Base address returned from system call
- void *mapped_base_;
-
- /**
- * @class Shared_Control_Block
- *
- * @brief Pool statistics
- */
- class Shared_Control_Block
- {
- public:
- /// Maximum size the pool may grow
- size_t max_size_;
-
- /// Size of mapped shared memory segment
- size_t mapped_size_;
-
- /// Offset to mapped but not yet acquired address space
- ptrdiff_t free_offset_;
-
- /// Size of mapped but not yet acquired address space
- size_t free_size_;
- };
-
- Shared_Control_Block sh_;
- };
-
- // Base of mapped region. If this has the value of 0 then the OS is
- // free to select any address to map the file, otherwise this value
- // is what the OS must try to use to mmap the file.
-
- /// Description of what our process mapped.
- Control_Block local_cb_;
-
- /// Shared memory pool statistics.
- Control_Block *shared_cb_;
-
- /// File mapping handle.
- ACE_HANDLE object_handle_;
-
- /// System page size.
- size_t page_size_;
-
- /// Name of the backing store where the shared memory pool is kept.
- ACE_TCHAR backing_store_name_[MAXPATHLEN];
-};
-
-#endif /* ACE_WIN32 */
-
-#if defined (__ACE_INLINE__)
-#include "ace/Memory_Pool.inl"
-#endif /* __ACE_INLINE__ */
+#include "ace/Local_Memory_Pool.h"
+#include "ace/MMAP_Memory_Pool.h"
+#include "ace/Sbrk_Memory_Pool.h"
+#include "ace/Shared_Memory_Pool.h"
+#include "ace/Pagefile_Memory_Pool.h"
#include /**/ "ace/post.h"
#endif /* ACE_MEMORY_POOL_H */
diff --git a/ace/Memory_Pool.inl b/ace/Memory_Pool.inl
deleted file mode 100644
index de87de3b331..00000000000
--- a/ace/Memory_Pool.inl
+++ /dev/null
@@ -1,269 +0,0 @@
-/* -*- C++ -*- */
-// $Id$
-
-ACE_INLINE
-ACE_Local_Memory_Pool::~ACE_Local_Memory_Pool (void)
-{
- // Free up all memory allocated by this pool.
- this->release ();
-}
-
-ACE_INLINE int
-ACE_Local_Memory_Pool::sync (ssize_t, int)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::sync");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Local_Memory_Pool::sync (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::sync");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Local_Memory_Pool::protect (ssize_t, int)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::protect");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Local_Memory_Pool::protect (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::protect");
- return 0;
-}
-
-ACE_INLINE void *
-ACE_Local_Memory_Pool::base_addr (void) const
-{
- return 0;
-}
-
-ACE_INLINE
-ACE_MMAP_Memory_Pool::~ACE_MMAP_Memory_Pool (void)
-{
-}
-
-ACE_INLINE
-ACE_Lite_MMAP_Memory_Pool::~ACE_Lite_MMAP_Memory_Pool (void)
-{
-}
-
-ACE_INLINE size_t
-ACE_MMAP_Memory_Pool::round_up (size_t nbytes)
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::round_up");
- return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
-}
-
-ACE_INLINE void *
-ACE_MMAP_Memory_Pool::base_addr (void) const
-{
- ACE_TRACE ("ACE_MMAP_Memory_Pool::base_addr");
- return this->base_addr_;
-}
-
-// Ask system for initial chunk of local memory.
-
-ACE_INLINE void *
-ACE_Local_Memory_Pool::init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::init_acquire");
- // Note that we assume that when ACE_Local_Memory_Pool is used,
- // ACE_Malloc's constructor will only get called once. If this
- // assumption doesn't hold, we are in deep trouble!
-
- first_time = 1;
- return this->acquire (nbytes, rounded_bytes);
-}
-
-// Let the underlying new operator figure out the alignment...
-
-ACE_INLINE size_t
-ACE_Local_Memory_Pool::round_up (size_t nbytes)
-{
- ACE_TRACE ("ACE_Local_Memory_Pool::round_up");
- return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
-}
-
-#if !defined (ACE_LACKS_SYSV_SHMEM)
-// Implement the algorithm for rounding up the request to an
-// appropriate chunksize.
-
-ACE_INLINE
-ACE_Shared_Memory_Pool::~ACE_Shared_Memory_Pool (void)
-{
-}
-
-ACE_INLINE size_t
-ACE_Shared_Memory_Pool::round_up (size_t nbytes)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::round_up");
- if (nbytes < this->segment_size_)
- nbytes = this->segment_size_;
-
- return ACE::round_to_pagesize (nbytes);
-}
-
-ACE_INLINE int
-ACE_Shared_Memory_Pool::sync (ssize_t, int)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::sync");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Shared_Memory_Pool::sync (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::sync");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Shared_Memory_Pool::protect (ssize_t, int)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::protect");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Shared_Memory_Pool::protect (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::protect");
- return 0;
-}
-
-ACE_INLINE void *
-ACE_Shared_Memory_Pool::base_addr (void) const
-{
- ACE_TRACE ("ACE_Shared_Memory_Pool::base_addr");
- return this->base_addr_;
-}
-#endif /* !ACE_LACKS_SYSV_SHMEM */
-
-#if !defined (ACE_LACKS_SBRK)
-
-ACE_INLINE
-ACE_Sbrk_Memory_Pool::~ACE_Sbrk_Memory_Pool (void)
-{
-}
-
-ACE_INLINE void *
-ACE_Sbrk_Memory_Pool::base_addr (void) const
-{
- return 0;
-}
-
-// Ask system for initial chunk of local memory.
-
-ACE_INLINE void *
-ACE_Sbrk_Memory_Pool::init_acquire (size_t nbytes,
- size_t &rounded_bytes,
- int &first_time)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::init_acquire");
- // Note that we assume that when ACE_Sbrk_Memory_Pool is used,
- // ACE_Malloc's constructor will only get called once. If this
- // assumption doesn't hold, we are in deep trouble!
-
- first_time = 1;
- return this->acquire (nbytes, rounded_bytes);
-}
-
-// Round up the request to a multiple of the page size.
-
-ACE_INLINE size_t
-ACE_Sbrk_Memory_Pool::round_up (size_t nbytes)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::round_up");
- return ACE::round_to_pagesize (nbytes);
-}
-
-/* No-op for now... */
-
-ACE_INLINE int
-ACE_Sbrk_Memory_Pool::release (int)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::release");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Sbrk_Memory_Pool::sync (ssize_t, int)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::sync");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Sbrk_Memory_Pool::sync (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::sync");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Sbrk_Memory_Pool::protect (ssize_t, int)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::protect");
- return 0;
-}
-
-ACE_INLINE int
-ACE_Sbrk_Memory_Pool::protect (void *, size_t, int)
-{
- ACE_TRACE ("ACE_Sbrk_Memory_Pool::protect");
- return 0;
-}
-#endif /* !ACE_LACKS_SBRK */
-
-#if defined (ACE_WIN32)
-
-ACE_INLINE size_t
-ACE_Pagefile_Memory_Pool::round_to_chunk_size (size_t nbytes)
-{
- return (nbytes + ACE_DEFAULT_PAGEFILE_POOL_CHUNK - 1)
- & (~(ACE_DEFAULT_PAGEFILE_POOL_CHUNK - 1));
-}
-
-ACE_INLINE size_t
-ACE_Pagefile_Memory_Pool::round_to_page_size (size_t nbytes)
-{
- return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
-}
-
-ACE_INLINE int
-ACE_Pagefile_Memory_Pool::sync (ssize_t, int)
-{
- return 0;
-}
-
-ACE_INLINE int
-ACE_Pagefile_Memory_Pool::sync (void *, size_t, int)
-{
- return 0;
-}
-
-ACE_INLINE int
-ACE_Pagefile_Memory_Pool::protect (ssize_t, int)
-{
- return 0;
-}
-
-ACE_INLINE int
-ACE_Pagefile_Memory_Pool::protect (void *, size_t, int)
-{
- return 0;
-}
-
-ACE_INLINE void *
-ACE_Pagefile_Memory_Pool::base_addr (void) const
-{
- return 0;
-}
-#endif /* ACE_WIN32 */
diff --git a/ace/Pagefile_Memory_Pool.cpp b/ace/Pagefile_Memory_Pool.cpp
new file mode 100644
index 00000000000..99a80760893
--- /dev/null
+++ b/ace/Pagefile_Memory_Pool.cpp
@@ -0,0 +1,362 @@
+// $Id$
+
+// Pagefile_Memory_Pool.cpp
+#include "ace/Pagefile_Memory_Pool.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Pagefile_Memory_Pool.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/Log_Msg.h"
+#include "ace/Auto_Ptr.h"
+#include "ace/RW_Thread_Mutex.h"
+#include "ace/OS_NS_sys_mman.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_sys_stat.h"
+#include "ace/OS_NS_unistd.h"
+
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+#include "ace/Based_Pointer_T.h"
+#include "ace/Based_Pointer_Repository.h"
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+
+ACE_RCSID(ace, Pagefile_Memory_Pool, "$Id$")
+
+#if defined (ACE_WIN32)
+#if !defined (ACE_HAS_WINCE)
+#define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
+ MapViewOfFileEx (_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)
+#else //if !defined (ACE_HAS_WINCE)
+#define ACE_MAP_FILE(_hnd, _access, _offHigh, _offLow, _nBytes, _baseAdd)\
+ MapViewOfFile (_hnd, _access, _offHigh, _offLow, _nBytes)
+#endif /* !defined (ACE_HAS_WINCE) */
+
+ACE_Pagefile_Memory_Pool_Options::ACE_Pagefile_Memory_Pool_Options (void *base_addr,
+ size_t max_size)
+ : base_addr_ (base_addr),
+ max_size_ (max_size)
+{
+}
+
+int
+ACE_Pagefile_Memory_Pool::release (int)
+{
+ return this->unmap ();
+}
+
+ACE_Pagefile_Memory_Pool::ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name,
+ const OPTIONS *options)
+ : shared_cb_ (0),
+ object_handle_ (0),
+ page_size_ (ACE_Pagefile_Memory_Pool::round_to_page_size (1))
+{
+ // Initialize local copy of pool statistics.
+ if (options != 0)
+ {
+ this->local_cb_.req_base_ = options->base_addr_;
+ this->local_cb_.mapped_base_ = 0;
+ this->local_cb_.sh_.max_size_ =
+ options->max_size_;
+ this->local_cb_.sh_.mapped_size_ = 0;
+ this->local_cb_.sh_.free_offset_ =
+ this->local_cb_.sh_.mapped_size_;
+ this->local_cb_.sh_.free_size_ = 0;
+ }
+
+ if (backing_store_name == 0)
+ // Only create a new unique filename for the backing store file if
+ // the user didn't supply one...
+ backing_store_name = ACE_DEFAULT_PAGEFILE_POOL_NAME;
+
+ ACE_OS::strsncpy (this->backing_store_name_,
+ backing_store_name,
+ (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
+}
+
+void *
+ACE_Pagefile_Memory_Pool::acquire (size_t nbytes,
+ size_t &rounded_bytes)
+{
+ rounded_bytes = round_to_page_size (nbytes);
+ void *result = 0;
+ int first_time = 0;
+
+ // Check local_cb_ for consistency. Remap, if extra space is too
+ // small and/or we didn't map the whole shared memory section
+ if (this->shared_cb_->sh_.mapped_size_
+ > this->local_cb_.sh_.mapped_size_
+ || this->shared_cb_->sh_.free_size_ < rounded_bytes)
+ {
+ size_t append = 0;
+ if (rounded_bytes > this->shared_cb_->sh_.free_size_)
+ append = rounded_bytes - this->shared_cb_->sh_.free_size_;
+
+ if (this->map (first_time, append) < 0)
+ return result;
+ }
+
+ // Get the block from extra space and update shared and local
+ // control block
+ if (this->shared_cb_->sh_.free_size_ < rounded_bytes)
+ return result;
+
+ result = (void *)((char *) this->local_cb_.mapped_base_
+ + this->shared_cb_->sh_.free_offset_);
+ this->shared_cb_->sh_.free_offset_ += rounded_bytes;
+ this->shared_cb_->sh_.free_size_ -= rounded_bytes;
+ this->local_cb_.sh_ = this->shared_cb_->sh_;
+
+ return result;
+}
+
+void *
+ACE_Pagefile_Memory_Pool::init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time)
+{
+ // Map the shared memory and get information, if we created the
+ // shared memory.
+ if (this->map (first_time) < 0)
+ return 0;
+
+ if (first_time != 0)
+ // We created the shared memory. So we have to allocate the
+ // requested memory.
+ return this->acquire (nbytes, rounded_bytes);
+ else
+ // We just mapped the memory and return the base address
+ return (void *)((char *) this->local_cb_.mapped_base_
+ + ACE_Pagefile_Memory_Pool::round_to_page_size
+ ((int) sizeof (Control_Block)));
+}
+
+int
+ACE_Pagefile_Memory_Pool::seh_selector (void *ep)
+{
+ DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
+
+ if (ecode == EXCEPTION_ACCESS_VIOLATION)
+ {
+ void * fault_addr = (void *)
+ ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
+
+ if (this->remap (fault_addr) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+ACE_Pagefile_Memory_Pool::remap (void *addr)
+{
+ // If the shared memory is not mapped or the address, that caused
+ // the memory fault is outside of the commited range of chunks, we
+ // return.
+ if (this->shared_cb_ == 0
+ || addr < this->local_cb_.mapped_base_
+ || addr >= (void *)((char *) this->local_cb_.mapped_base_
+ + this->shared_cb_->sh_.mapped_size_))
+ return -1;
+
+ // We can solve the problem by committing additional chunks.
+ int first_time = 0;
+ return this->map (first_time);
+}
+
+int
+ACE_Pagefile_Memory_Pool::unmap (void)
+{
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+ ACE_BASED_POINTER_REPOSITORY::instance ()->unbind
+ (this->local_cb_.mapped_base_);
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+
+ // Cleanup cached pool pointer.
+ this->shared_cb_ = 0;
+
+ if (this->local_cb_.sh_.mapped_size_ > 0)
+ ::UnmapViewOfFile (this->local_cb_.mapped_base_);
+
+ // Reset local pool statistics.
+ this->local_cb_.req_base_ =
+ ACE_DEFAULT_PAGEFILE_POOL_BASE;
+ this->local_cb_.mapped_base_ = 0;
+ this->local_cb_.sh_.max_size_ =
+ ACE_DEFAULT_PAGEFILE_POOL_SIZE;
+ this->local_cb_.sh_.mapped_size_ = 0;
+ this->local_cb_.sh_.free_offset_ =
+ this->local_cb_.sh_.mapped_size_;
+ this->local_cb_.sh_.free_size_ = 0;
+
+ // Release the pool
+ if (this->object_handle_ != 0)
+ {
+ ::CloseHandle (this->object_handle_);
+ this->object_handle_ = 0;
+ }
+ return 0;
+}
+
+int
+ACE_Pagefile_Memory_Pool::map (int &first_time,
+ size_t append_bytes)
+{
+ size_t map_size;
+ void *map_addr;
+
+ // Create file mapping, if not yet done
+ if (object_handle_ == 0)
+ {
+#if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
+ // Allow access by all users.
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+ ::InitializeSecurityDescriptor (&sd,
+ SECURITY_DESCRIPTOR_REVISION);
+ ::SetSecurityDescriptorDacl (&sd,
+ TRUE,
+ 0,
+ FALSE);
+ sa.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = &sd;
+ sa.bInheritHandle = FALSE;
+#endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */
+
+ // Get an object handle to the named reserved memory object.
+ DWORD size_high;
+ DWORD size_low;
+#if defined (ACE_WIN64)
+ size_high = static_cast<DWORD> (this->local_cb_.sh_.max_size_ >> 32);
+ size_low = static_cast<DWORD> (this->local_cb_.sh_.max_size_ & 0xFFFFFFFF);
+#else
+ size_high = 0;
+ size_low = this->local_cb_.sh_.max_size_;
+#endif
+
+ object_handle_ =
+ ACE_TEXT_CreateFileMapping (INVALID_HANDLE_VALUE,
+#if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
+ &sa,
+#else
+ 0,
+#endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */
+ PAGE_READWRITE | SEC_RESERVE,
+ size_high,
+ size_low,
+ this->backing_store_name_);
+ if (object_handle_ == 0)
+ return -1;
+ first_time =
+ ::GetLastError () == ERROR_ALREADY_EXISTS
+ ? 0
+ : 1;
+ }
+
+ // Do the initial mapping.
+ if (this->shared_cb_ == 0)
+ {
+ // Map a view to the shared memory. Note: <MapViewOfFile[Ex]>
+ // does *not* commit the pages!
+ this->shared_cb_ = (ACE_Pagefile_Memory_Pool::Control_Block *)
+ ACE_MAP_FILE (this->object_handle_,
+ FILE_MAP_WRITE,
+ 0,
+ 0,
+ this->local_cb_.sh_.max_size_,
+ this->local_cb_.req_base_);
+ if (this->shared_cb_ == 0)
+ return -1;
+
+ // There was no previous mapping, so we map the first chunk and
+ // initialize the shared pool statistics.
+ if (first_time)
+ {
+ // 1st block is used to keep shared memory statistics.
+ map_size =
+ ACE_Pagefile_Memory_Pool::round_to_chunk_size
+ (ACE_Pagefile_Memory_Pool::round_to_page_size
+ ((int) sizeof(Control_Block))
+ + append_bytes);
+
+ if (::VirtualAlloc ((void *) this->shared_cb_,
+ map_size,
+ MEM_COMMIT,
+ PAGE_READWRITE) == 0)
+ return -1;
+
+ this->shared_cb_->req_base_ = 0;
+ this->shared_cb_->mapped_base_ = 0;
+ this->local_cb_.mapped_base_ = this->shared_cb_;
+ this->local_cb_.sh_.mapped_size_ = map_size;
+ this->local_cb_.sh_.free_offset_ =
+ round_to_page_size ((int) sizeof (Control_Block));
+ this->local_cb_.sh_.free_size_ =
+ this->local_cb_.sh_.mapped_size_ -
+ this->local_cb_.sh_.free_offset_;
+ this->shared_cb_->sh_ = this->local_cb_.sh_;
+ }
+
+ // The shared memory exists, so we map the first chunk to the
+ // base address of the pool to get the shared pool statistics.
+ else
+ {
+ // 1st block is used to keep shared memory statistics.
+ map_size =
+ ACE_Pagefile_Memory_Pool::round_to_chunk_size
+ ((int) sizeof (Control_Block));
+
+ if (::VirtualAlloc ((void *) this->shared_cb_,
+ map_size,
+ MEM_COMMIT,
+ PAGE_READWRITE) == 0)
+ return -1;
+ this->local_cb_.mapped_base_ = this->shared_cb_;
+ this->local_cb_.sh_.mapped_size_ = map_size;
+ }
+ }
+
+ // If the shared memory is larger than the part we've already
+ // committed, we have to remap it.
+ if (this->shared_cb_->sh_.mapped_size_ >
+ this->local_cb_.sh_.mapped_size_
+ || append_bytes > 0)
+ {
+ map_size =
+ (this->shared_cb_->sh_.mapped_size_ -
+ this->local_cb_.sh_.mapped_size_)
+ + ACE_Pagefile_Memory_Pool::round_to_chunk_size
+ (append_bytes);
+
+ map_addr = (void *)((char *) this->shared_cb_ +
+ this->local_cb_.sh_.mapped_size_);
+
+ if (::VirtualAlloc (map_addr,
+ map_size,
+ MEM_COMMIT,
+ PAGE_READWRITE) == 0)
+ return -1;
+ else if (append_bytes > 0)
+ {
+ this->shared_cb_->sh_.mapped_size_ +=
+ round_to_chunk_size (append_bytes);
+ this->shared_cb_->sh_.free_size_ =
+ this->shared_cb_->sh_.mapped_size_ -
+ this->shared_cb_->sh_.free_offset_;
+ }
+ }
+
+ // Update local copy of the shared memory statistics.
+ this->local_cb_.sh_ =
+ this->shared_cb_->sh_;
+#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
+ ACE_BASED_POINTER_REPOSITORY::instance ()->bind
+ (this->local_cb_.mapped_base_,
+ this->local_cb_.sh_.mapped_size_);
+#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
+
+ return 0;
+}
+
+#endif /* ACE_WIN32 */
+
diff --git a/ace/Pagefile_Memory_Pool.h b/ace/Pagefile_Memory_Pool.h
new file mode 100644
index 00000000000..004582523d2
--- /dev/null
+++ b/ace/Pagefile_Memory_Pool.h
@@ -0,0 +1,192 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Memory_Pool.h
+ *
+ * $Id$
+ *
+ * @author Dougls C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Prashant Jain <pjain@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_PAGEFILE_MEMORY_POOL_H
+#define ACE_PAGEFILE_MEMORY_POOL_H
+#include /**/ "ace/pre.h"
+
+#include "ace/ACE.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if defined (ACE_WIN32)
+
+/**
+ * @class ACE_Pagefile_Memory_Pool_Options
+ *
+ * @brief Helper class for Pagefile Memory Pool constructor options.
+ *
+ * This should be a nested class, but that breaks too many
+ * compilers.
+ */
+class ACE_Export ACE_Pagefile_Memory_Pool_Options
+{
+public:
+ /// Initialization method.
+ ACE_Pagefile_Memory_Pool_Options (void *base_addr = ACE_DEFAULT_PAGEFILE_POOL_BASE,
+ size_t max_size = ACE_DEFAULT_PAGEFILE_POOL_SIZE);
+
+ /// Base address of the memory-mapped backing store.
+ void *base_addr_;
+
+ /// Maximum size the pool may grow.
+ size_t max_size_;
+};
+
+/**
+ * @class ACE_Pagefile_Memory_Pool
+ *
+ * @brief Make a memory pool that is based on "anonymous" memory
+ * regions allocated from the Win32 page file.
+ */
+class ACE_Export ACE_Pagefile_Memory_Pool
+{
+public:
+ typedef ACE_Pagefile_Memory_Pool_Options OPTIONS;
+
+ /// Initialize the pool.
+ ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
+ const OPTIONS *options = 0);
+
+ /// Ask system for initial chunk of shared memory.
+ void *init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time);
+
+ /// Acquire at least <nbytes> from the memory pool. <rounded_bytes>
+ /// is the actual number of bytes allocated.
+ void *acquire (size_t nbytes,
+ size_t &rounded_bytes);
+
+ /// Instruct the memory pool to release all of its resources.
+ int release (int destroy = 1);
+
+ /**
+ * Win32 Structural exception selector. The return value decides
+ * how to handle memory pool related structural exceptions. Returns
+ * 1, 0, or , -1.
+ */
+ virtual int seh_selector (void *);
+
+ /**
+ * Try to extend the virtual address space so that <addr> is now
+ * covered by the address mapping. The method succeeds and returns
+ * 0 if the backing store has adequate memory to cover this address.
+ * Otherwise, it returns -1. This method is typically called by an
+ * exception handler for a Win32 structured exception when another
+ * process has grown the backing store (and its mapping) and our
+ * process now incurs a fault because our mapping isn't in range
+ * (yet).
+ */
+ int remap (void *addr);
+
+ /// Round up to system page size.
+ size_t round_to_page_size (size_t nbytes);
+
+ /// Round up to the chunk size required by the operation system
+ size_t round_to_chunk_size (size_t nbytes);
+
+ // = Don't need this methods here ...
+ int sync (ssize_t = -1, int = MS_SYNC);
+ int sync (void *, size_t, int = MS_SYNC);
+ int protect (ssize_t = -1, int = PROT_RDWR);
+ int protect (void *, size_t, int = PROT_RDWR);
+
+ /// Return the base address of this memory pool, 0 if base_addr
+ /// never changes.
+ virtual void *base_addr (void) const;
+
+ void dump (void) const {}
+
+protected:
+
+ /**
+ * Map portions or the entire pool into the local virtual address
+ * space. To do this, we compute the new @c file_offset of the
+ * backing store and commit the memory.
+ */
+ int map (int &firstTime, size_t appendBytes = 0);
+
+ /// Release the mapping.
+ int unmap (void);
+
+private:
+
+ /**
+ * @class Control_Block
+ *
+ * @brief Attributes that are meaningful in local storage only.
+ */
+ class Control_Block
+ {
+ public:
+ /// Required base address
+ void *req_base_;
+
+ /// Base address returned from system call
+ void *mapped_base_;
+
+ /**
+ * @class Shared_Control_Block
+ *
+ * @brief Pool statistics
+ */
+ class Shared_Control_Block
+ {
+ public:
+ /// Maximum size the pool may grow
+ size_t max_size_;
+
+ /// Size of mapped shared memory segment
+ size_t mapped_size_;
+
+ /// Offset to mapped but not yet acquired address space
+ ptrdiff_t free_offset_;
+
+ /// Size of mapped but not yet acquired address space
+ size_t free_size_;
+ };
+
+ Shared_Control_Block sh_;
+ };
+
+ // Base of mapped region. If this has the value of 0 then the OS is
+ // free to select any address to map the file, otherwise this value
+ // is what the OS must try to use to mmap the file.
+
+ /// Description of what our process mapped.
+ Control_Block local_cb_;
+
+ /// Shared memory pool statistics.
+ Control_Block *shared_cb_;
+
+ /// File mapping handle.
+ ACE_HANDLE object_handle_;
+
+ /// System page size.
+ size_t page_size_;
+
+ /// Name of the backing store where the shared memory pool is kept.
+ ACE_TCHAR backing_store_name_[MAXPATHLEN];
+};
+
+#endif /* ACE_WIN32 */
+
+#if defined (__ACE_INLINE__)
+#include "ace/Pagefile_Memory_Pool.inl"
+#endif /* __ACE_INLINE__ */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_MEMORY_POOL_H */
diff --git a/ace/Pagefile_Memory_Pool.inl b/ace/Pagefile_Memory_Pool.inl
new file mode 100644
index 00000000000..db8d7a00aa4
--- /dev/null
+++ b/ace/Pagefile_Memory_Pool.inl
@@ -0,0 +1,48 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if defined (ACE_WIN32)
+
+ACE_INLINE size_t
+ACE_Pagefile_Memory_Pool::round_to_chunk_size (size_t nbytes)
+{
+ return (nbytes + ACE_DEFAULT_PAGEFILE_POOL_CHUNK - 1)
+ & (~(ACE_DEFAULT_PAGEFILE_POOL_CHUNK - 1));
+}
+
+ACE_INLINE size_t
+ACE_Pagefile_Memory_Pool::round_to_page_size (size_t nbytes)
+{
+ return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
+}
+
+ACE_INLINE int
+ACE_Pagefile_Memory_Pool::sync (ssize_t, int)
+{
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Pagefile_Memory_Pool::sync (void *, size_t, int)
+{
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Pagefile_Memory_Pool::protect (ssize_t, int)
+{
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Pagefile_Memory_Pool::protect (void *, size_t, int)
+{
+ return 0;
+}
+
+ACE_INLINE void *
+ACE_Pagefile_Memory_Pool::base_addr (void) const
+{
+ return 0;
+}
+#endif /* ACE_WIN32 */
diff --git a/ace/Sbrk_Memory_Pool.cpp b/ace/Sbrk_Memory_Pool.cpp
new file mode 100644
index 00000000000..70c6f7c4891
--- /dev/null
+++ b/ace/Sbrk_Memory_Pool.cpp
@@ -0,0 +1,119 @@
+// $Id$
+
+// Memory_Pool.cpp
+#include "ace/Sbrk_Memory_Pool.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID(ace, Sbrk_Memory_Pool, "$Id$")
+
+#if !defined (ACE_LACKS_SBRK)
+ACE_ALLOC_HOOK_DEFINE(ACE_Sbrk_Memory_Pool)
+
+// Ask system for more local memory via sbrk(2).
+
+void *
+ACE_Sbrk_Memory_Pool::acquire (size_t nbytes,
+ size_t &rounded_bytes)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::acquire");
+ rounded_bytes = this->round_up (nbytes);
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes));
+ void *cp = ACE_OS::sbrk (rounded_bytes);
+
+ if (cp == MAP_FAILED)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) cp = %u\n",
+ cp),
+ 0);
+ else
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d, new break = %u\n"), nbytes, rounded_bytes, cp));
+ return cp;
+}
+
+/* No-op for now... */
+
+int
+ACE_Sbrk_Memory_Pool::release (int)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::release");
+ return 0;
+}
+
+int
+ACE_Sbrk_Memory_Pool::sync (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Sbrk_Memory_Pool::sync (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Sbrk_Memory_Pool::protect (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::protect");
+ return 0;
+}
+
+int
+ACE_Sbrk_Memory_Pool::protect (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::protect");
+ return 0;
+}
+
+// Ask system for initial chunk of local memory.
+
+void *
+ACE_Sbrk_Memory_Pool::init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::init_acquire");
+ // Note that we assume that when ACE_Sbrk_Memory_Pool is used,
+ // ACE_Malloc's constructor will only get called once. If this
+ // assumption doesn't hold, we are in deep trouble!
+
+ first_time = 1;
+ return this->acquire (nbytes, rounded_bytes);
+}
+
+void
+ACE_Sbrk_Memory_Pool::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::dump");
+#endif /* ACE_HAS_DUMP */
+}
+
+ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool (const ACE_TCHAR *,
+ const OPTIONS *)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool");
+}
+
+ACE_Sbrk_Memory_Pool::~ACE_Sbrk_Memory_Pool (void)
+{
+}
+
+void *
+ACE_Sbrk_Memory_Pool::base_addr (void) const
+{
+ return 0;
+}
+
+
+// Round up the request to a multiple of the page size.
+
+size_t
+ACE_Sbrk_Memory_Pool::round_up (size_t nbytes)
+{
+ ACE_TRACE ("ACE_Sbrk_Memory_Pool::round_up");
+ return ACE::round_to_pagesize (nbytes);
+}
+#endif /* !ACE_LACKS_SBRK */
diff --git a/ace/Sbrk_Memory_Pool.h b/ace/Sbrk_Memory_Pool.h
new file mode 100644
index 00000000000..07893057659
--- /dev/null
+++ b/ace/Sbrk_Memory_Pool.h
@@ -0,0 +1,107 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Memory_Pool.h
+ *
+ * $Id$
+ *
+ * @author Dougls C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Prashant Jain <pjain@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_SBRK_MEMORY_POOL_H
+#define ACE_SBRK_MEMORY_POOL_H
+#include /**/ "ace/pre.h"
+
+#include "ace/ACE.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if !defined (ACE_LACKS_SBRK)
+/**
+ * @class ACE_Sbrk_Memory_Pool_Options
+ *
+ * @brief Helper class for Sbrk Memory Pool constructor options.
+ *
+ * This should be a nested class, but that breaks too many
+ * compilers.
+ */
+class ACE_Export ACE_Sbrk_Memory_Pool_Options
+{
+};
+
+/**
+ * @class ACE_Sbrk_Memory_Pool
+ *
+ * @brief Make a memory pool that is based on <sbrk(2)>.
+ */
+class ACE_Export ACE_Sbrk_Memory_Pool
+{
+public:
+ typedef ACE_Sbrk_Memory_Pool_Options OPTIONS;
+
+ /// Initialize the pool.
+ ACE_Sbrk_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
+ const OPTIONS *options = 0);
+
+ virtual ~ACE_Sbrk_Memory_Pool (void);
+
+ // = Implementor operations.
+ /// Ask system for initial chunk of local memory.
+ virtual void *init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time);
+
+ /// Acquire at least @a nbytes from the memory pool. @a rounded_bytes is
+ /// the actual number of bytes allocated.
+ virtual void *acquire (size_t nbytes,
+ size_t &rounded_bytes);
+
+ /// Instruct the memory pool to release all of its resources.
+ virtual int release (int destroy = 1);
+
+ /**
+ * 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 @a addr.
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+
+ /**
+ * Change the protection of the pages of the mapped region to <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);
+
+ /// Dump the state of an object.
+ virtual void dump (void) const;
+
+ /// Return the base address of this memory pool, 0 if base_addr
+ /// never changes.
+ virtual void *base_addr (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+protected:
+ /// Implement the algorithm for rounding up the request to an
+ /// appropriate chunksize.
+ virtual size_t round_up (size_t nbytes);
+};
+#endif /* !ACE_LACKS_SBRK */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SBRK_MEMORY_POOL_H */
diff --git a/ace/Shared_Memory_Pool.cpp b/ace/Shared_Memory_Pool.cpp
new file mode 100644
index 00000000000..34a790a6110
--- /dev/null
+++ b/ace/Shared_Memory_Pool.cpp
@@ -0,0 +1,449 @@
+// $Id$
+
+// Shared_Memory_Pool.cpp
+#include "ace/Shared_Memory_Pool.h"
+#include "ace/OS_NS_sys_shm.h"
+
+ACE_RCSID(ace, Shared_Memory_Pool, "$Id$")
+
+#if !defined (ACE_LACKS_SYSV_SHMEM)
+ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_Pool)
+
+ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options (const char *base_addr,
+ size_t max_segments,
+ size_t file_perms,
+ off_t minimum_bytes,
+ size_t segment_size)
+ : base_addr_ (base_addr),
+ max_segments_ (max_segments),
+ minimum_bytes_ (minimum_bytes),
+ file_perms_ (file_perms),
+ segment_size_ (segment_size)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool_Options::ACE_Shared_Memory_Pool_Options");
+}
+
+void
+ACE_Shared_Memory_Pool::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_Shared_Memory_Pool::dump");
+#endif /* ACE_HAS_DUMP */
+}
+
+int
+ACE_Shared_Memory_Pool::in_use (off_t &offset,
+ size_t &counter)
+{
+ offset = 0;
+ SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
+ shmid_ds buf;
+
+ for (counter = 0;
+ counter < this->max_segments_ && st[counter].used_ == 1;
+ counter++)
+ {
+ if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("shmctl")),
+ -1);
+ offset += buf.shm_segsz;
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset));
+ }
+
+ return 0;
+}
+
+int
+ACE_Shared_Memory_Pool::find_seg (const void* const searchPtr,
+ off_t &offset,
+ size_t &counter)
+{
+ offset = 0;
+ SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
+ shmid_ds buf;
+
+ for (counter = 0;
+ counter < this->max_segments_
+ && st[counter].used_ == 1;
+ counter++)
+ {
+ if (ACE_OS::shmctl (st[counter].shmid_, IPC_STAT, &buf) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("shmctl")),
+ -1);
+ offset += buf.shm_segsz;
+
+ // If segment 'counter' starts at a location greater than the
+ // place we are searching for. We then decrement the offset to
+ // the start of counter-1. (flabar@vais.net)
+ if (((ptrdiff_t) offset + (ptrdiff_t) (this->base_addr_)) > (ptrdiff_t) searchPtr)
+ {
+ --counter;
+ offset -= buf.shm_segsz;
+ return 0;
+ }
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) segment size = %d, offset = %d\n"), buf.shm_segsz, offset));
+ }
+
+ return 0;
+}
+
+int
+ACE_Shared_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
+ off_t &offset)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::commit_backing_store_name");
+
+ size_t counter;
+ SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
+
+ if (this->in_use (offset, counter) == -1)
+ return -1;
+
+ if (counter == this->max_segments_)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "exceeded max number of segments = %d, base = %u, offset = %u\n",
+ counter,
+ this->base_addr_,
+ offset),
+ -1);
+ else
+ {
+ int shmid = ACE_OS::shmget (st[counter].key_,
+ rounded_bytes,
+ this->file_perms_ | IPC_CREAT | IPC_EXCL);
+ if (shmid == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("shmget")),
+ -1);
+ st[counter].shmid_ = shmid;
+ st[counter].used_ = 1;
+
+ void *address = (void *) (((char *) this->base_addr_) + offset);
+ void *shmem = ACE_OS::shmat (st[counter].shmid_,
+ (char *) address,
+ 0);
+
+ if (shmem != address)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p, shmem = %u, address = %u\n",
+ "shmat",
+ shmem,
+ address),
+ -1);
+ }
+ return 0;
+}
+
+// Handle SIGSEGV and SIGBUS signals to remap shared memory properly.
+
+int
+ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::handle_signal");
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("signal %S occurred\n"), signum));
+
+#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
+ off_t offset;
+ // Make sure that the pointer causing the problem is within the
+ // range of the backing store.
+
+ if (siginfo != 0)
+ {
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) si_signo = %d, si_code = %d, addr = %u\n"), siginfo->si_signo, siginfo->si_code, siginfo->si_addr));
+ size_t counter;
+ if (this->in_use (offset, counter) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("in_use")));
+#if !defined(_UNICOS)
+ else if (!(siginfo->si_code == SEGV_MAPERR
+ && siginfo->si_addr < (((char *) this->base_addr_) + offset)
+ && siginfo->si_addr >= ((char *) this->base_addr_)))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) address %u out of range\n",
+ siginfo->si_addr),
+ -1);
+#else /* ! _UNICOS */
+ else if (!(siginfo->si_code == SEGV_MEMERR
+ && siginfo->si_addr < (((unsigned long) this->base_addr_) + offset)
+ && siginfo->si_addr >= ((unsigned long) this->base_addr_)))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) address %u out of range\n",
+ siginfo->si_addr),
+ -1);
+#endif /* ! _UNICOS */
+ }
+
+ // The above if case will check to see that the address is in the
+ // proper range. Therefore there is a segment out there that the
+ // pointer wants to point into. Find the segment that someone else
+ // has used and attach to it (flabar@vais.net)
+
+ size_t counter; // ret value to get shmid from the st table.
+
+#if !defined(_UNICOS)
+ if (this->find_seg (siginfo->si_addr, offset, counter) == -1)
+#else /* ! _UNICOS */
+ if (this->find_seg ((const void *)siginfo->si_addr, offset, counter) == -1)
+#endif /* ! _UNICOS */
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("in_use")),
+ -1);
+
+ void *address = (void *) (((char *) this->base_addr_) + offset);
+ SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
+
+ void *shmem = ACE_OS::shmat (st[counter].shmid_, (char *) address, 0);
+
+ if (shmem != address)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p, shmem = %u, address = %u\n",
+ "shmat",
+ shmem,
+ address),
+ -1);
+
+ // NOTE: this won't work if we dont have SIGINFO_T or SI_ADDR
+#else
+ ACE_UNUSED_ARG (siginfo);
+#endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */
+
+ return 0;
+}
+
+ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name,
+ const OPTIONS *options)
+ : base_addr_ (0),
+ file_perms_ (ACE_DEFAULT_FILE_PERMS),
+ max_segments_ (ACE_DEFAULT_MAX_SEGMENTS),
+ minimum_bytes_ (0),
+ segment_size_ (ACE_DEFAULT_SEGMENT_SIZE)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool");
+
+ // Only change the defaults if <options> != 0.
+ if (options)
+ {
+ this->base_addr_ =
+ reinterpret_cast<void *> (const_cast<char *> (options->base_addr_));
+ this->max_segments_ = options->max_segments_;
+ this->file_perms_ = options->file_perms_;
+ this->minimum_bytes_ = options->minimum_bytes_;
+ this->segment_size_ = options->segment_size_;
+ }
+
+ if (backing_store_name)
+ {
+ // Convert the string into a number that is used as the segment
+ // key.
+
+ int segment_key;
+ int result = ::sscanf (ACE_TEXT_ALWAYS_CHAR (backing_store_name),
+ "%d",
+ &segment_key);
+
+ if (result == 0 || result == EOF)
+ // The conversion to a number failed so hash with crc32
+ // ACE::crc32 is also used in <SV_Semaphore_Simple>.
+ this->base_shm_key_ =
+ (key_t) ACE::crc32 (ACE_TEXT_ALWAYS_CHAR (backing_store_name));
+ else
+ this->base_shm_key_ = segment_key;
+
+ if (this->base_shm_key_ == IPC_PRIVATE)
+ // Make sure that the segment can be shared between unrelated
+ // processes.
+ this->base_shm_key_ = ACE_DEFAULT_SHM_KEY;
+ }
+ else
+ this->base_shm_key_ = ACE_DEFAULT_SHM_KEY;
+
+ if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("%p\n"),
+ ACE_LIB_TEXT ("ACE_Sig_Handler::register_handler")));
+}
+
+ACE_Shared_Memory_Pool::~ACE_Shared_Memory_Pool (void)
+{
+}
+
+// Ask system for more shared memory.
+
+void *
+ACE_Shared_Memory_Pool::acquire (size_t nbytes,
+ size_t &rounded_bytes)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::acquire");
+
+ rounded_bytes = this->round_up (nbytes);
+
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes));
+
+ off_t offset;
+
+ if (this->commit_backing_store_name (rounded_bytes, offset) == -1)
+ return 0;
+
+ // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d\n"), nbytes, rounded_bytes));
+ return ((char *) this->base_addr_) + offset;
+}
+
+// Ask system for initial chunk of shared memory.
+
+void *
+ACE_Shared_Memory_Pool::init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire");
+
+ off_t shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE));
+ rounded_bytes = this->round_up (nbytes > (size_t) this->minimum_bytes_
+ ? nbytes
+ : (size_t) this->minimum_bytes_);
+
+ // Acquire the semaphore to serialize initialization and prevent
+ // race conditions.
+
+ int shmid = ACE_OS::shmget (this->base_shm_key_,
+ rounded_bytes + shm_table_offset,
+ this->file_perms_ | IPC_CREAT | IPC_EXCL);
+ if (shmid == -1)
+ {
+ if (errno != EEXIST)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("shmget")),
+ 0);
+ first_time = 0;
+
+ shmid = ACE_OS::shmget (this->base_shm_key_, 0, 0);
+
+ if (shmid == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_LIB_TEXT ("(%P|%t) %p\n"),
+ ACE_LIB_TEXT ("shmget")),
+ 0);
+
+ // This implementation doesn't care if we don't get the key we
+ // want...
+ this->base_addr_ =
+ ACE_OS::shmat (shmid,
+ reinterpret_cast<char *> (this->base_addr_),
+ 0);
+ if (this->base_addr_ == reinterpret_cast<void *> (-1))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p, base_addr = %u\n",
+ "shmat",
+ this->base_addr_),
+ 0);
+ }
+ else
+ {
+ first_time = 1;
+
+ // This implementation doesn't care if we don't get the key we
+ // want...
+ this->base_addr_ =
+ ACE_OS::shmat (shmid,
+ reinterpret_cast<char *> (this->base_addr_),
+ 0);
+ if (this->base_addr_ == reinterpret_cast<char *> (-1))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p, base_addr = %u\n",
+ "shmat",
+ this->base_addr_), 0);
+
+ SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
+ st[0].key_ = this->base_shm_key_;
+ st[0].shmid_ = shmid;
+
+ st[0].used_ = 1;
+
+ for (size_t counter = 1; // Skip over the first entry...
+ counter < this->max_segments_;
+ counter++)
+ {
+ st[counter].key_ = this->base_shm_key_ + counter;
+ st[counter].shmid_ = 0;
+ st[counter].used_ = 0;
+ }
+ }
+
+ return (void *) (((char *) this->base_addr_) + shm_table_offset);
+}
+
+// Instruct the memory pool to release all of its resources.
+
+int
+ACE_Shared_Memory_Pool::release (int)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::release");
+
+ int result = 0;
+ SHM_TABLE *st = reinterpret_cast<SHM_TABLE *> (this->base_addr_);
+
+ for (size_t counter = 0;
+ counter < this->max_segments_ && st[counter].used_ == 1;
+ counter++)
+ if (ACE_OS::shmctl (st[counter].shmid_, IPC_RMID, 0) == -1)
+ result = -1;
+
+ return result;
+}
+
+int
+ACE_Shared_Memory_Pool::sync (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Shared_Memory_Pool::sync (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::sync");
+ return 0;
+}
+
+int
+ACE_Shared_Memory_Pool::protect (ssize_t, int)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::protect");
+ return 0;
+}
+
+int
+ACE_Shared_Memory_Pool::protect (void *, size_t, int)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::protect");
+ return 0;
+}
+
+void *
+ACE_Shared_Memory_Pool::base_addr (void) const
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::base_addr");
+ return this->base_addr_;
+}
+
+// Implement the algorithm for rounding up the request to an
+// appropriate chunksize.
+
+size_t
+ACE_Shared_Memory_Pool::round_up (size_t nbytes)
+{
+ ACE_TRACE ("ACE_Shared_Memory_Pool::round_up");
+ if (nbytes < this->segment_size_)
+ nbytes = this->segment_size_;
+
+ return ACE::round_to_pagesize (nbytes);
+}
+#endif /* !ACE_LACKS_SYSV_SHMEM */
diff --git a/ace/Shared_Memory_Pool.h b/ace/Shared_Memory_Pool.h
new file mode 100644
index 00000000000..e252d06f4b3
--- /dev/null
+++ b/ace/Shared_Memory_Pool.h
@@ -0,0 +1,200 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Memory_Pool.h
+ *
+ * $Id$
+ *
+ * @author Dougls C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Prashant Jain <pjain@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_SHARED_MEMORY_POOL_H
+#define ACE_SHARED_MEMORY_POOL_H
+#include /**/ "ace/pre.h"
+
+#include "ace/ACE.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Event_Handler.h"
+#include "ace/Signal.h"
+
+#if !defined (ACE_LACKS_SYSV_SHMEM)
+
+/**
+ * @class ACE_Shared_Memory_Pool_Options
+ *
+ * @brief Helper class for Shared Memory Pool constructor options.
+ *
+ * This should be a nested class, but that breaks too many
+ * compilers.
+ */
+class ACE_Export ACE_Shared_Memory_Pool_Options
+{
+public:
+ /// Initialization method.
+ ACE_Shared_Memory_Pool_Options (const char *base_addr = ACE_DEFAULT_BASE_ADDR,
+ size_t max_segments = ACE_DEFAULT_MAX_SEGMENTS,
+ size_t file_perms = ACE_DEFAULT_FILE_PERMS,
+ off_t minimum_bytes = 0,
+ size_t segment_size = ACE_DEFAULT_SEGMENT_SIZE);
+
+ /// Base address of the memory-mapped backing store.
+ const char *base_addr_;
+
+ /// Number of shared memory segments to allocate.
+ size_t max_segments_;
+
+ /// What the minimum bytes of the initial segment should be.
+ off_t minimum_bytes_;
+
+ /// File permissions to use when creating/opening a segment.
+ size_t file_perms_;
+
+ /// Shared memory segment size.
+ size_t segment_size_;
+};
+
+/**
+ * @class ACE_Shared_Memory_Pool
+ *
+ * @brief Make a memory pool that is based on System V shared memory
+ * (shmget(2) etc.). This implementation allows memory to be
+ * shared between processes. If your platform doesn't support
+ * System V shared memory (e.g., Win32 and many RTOS platforms
+ * do not) then you should use ACE_MMAP_Memory_Pool instead of this
+ * class. In fact, you should probably use ACE_MMAP_Memory_Pool on
+ * platforms that *do* support System V shared memory since it
+ * provides more powerful features, such as persistent backing store
+ * and greatly scalability.
+ */
+class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler
+{
+public:
+ typedef ACE_Shared_Memory_Pool_Options OPTIONS;
+
+ /// Initialize the pool.
+ ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name = 0,
+ const OPTIONS *options = 0);
+
+ virtual ~ACE_Shared_Memory_Pool (void);
+
+ /// Ask system for initial chunk of local memory.
+ virtual void *init_acquire (size_t nbytes,
+ size_t &rounded_bytes,
+ int &first_time);
+
+ /**
+ * Acquire at least @a nbytes from the memory pool. @a rounded_byes is
+ * the actual number of bytes allocated. Also acquires an internal
+ * semaphore that ensures proper serialization of Memory_Pool
+ * initialization across processes.
+ */
+ virtual void *acquire (size_t nbytes,
+ size_t &rounded_bytes);
+
+ /// Instruct the memory pool to release all of its resources.
+ virtual int release (int destroy = 1);
+
+ /// Sync the memory region to the backing store starting at
+ /// @c this->base_addr_.
+ virtual int sync (ssize_t len = -1, int flags = MS_SYNC);
+
+ /// Sync the memory region to the backing store starting at @a addr.
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+
+ /**
+ * Change the protection of the pages of the mapped region to <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 <prot>
+ /// starting at <addr> up to <len> bytes.
+ virtual int protect (void *addr, size_t len, int prot = PROT_RDWR);
+
+ /// Return the base address of this memory pool, 0 if base_addr
+ /// never changes.
+ virtual void *base_addr (void) const;
+
+ /// Dump the state of an object.
+ virtual void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+protected:
+ /// Implement the algorithm for rounding up the request to an
+ /// appropriate chunksize.
+ virtual size_t round_up (size_t nbytes);
+
+ /**
+ * Commits a new shared memory segment if necessary after an
+ * <acquire> or a signal. <offset> is set to the new offset into
+ * the backing store.
+ */
+ virtual int commit_backing_store_name (size_t rounded_bytes,
+ off_t &offset);
+
+ /// Keeps track of all the segments being used.
+ struct SHM_TABLE
+ {
+ /// Shared memory segment key.
+ key_t key_;
+
+ /// Shared memory segment internal id.
+ int shmid_;
+
+ /// Is the segment currently used.;
+ int used_;
+ };
+
+ /**
+ * Base address of the shared memory segment. If this has the value
+ * of 0 then the OS is free to select any address, otherwise this
+ * value is what the OS must try to use to map the shared memory
+ * segment.
+ */
+ void *base_addr_;
+
+ /// File permissions to use when creating/opening a segment.
+ size_t file_perms_;
+
+ /// Number of shared memory segments in the <SHM_TABLE> table.
+ size_t max_segments_;
+
+ /// What the minimim bytes of the initial segment should be.
+ off_t minimum_bytes_;
+
+ /// Shared memory segment size.
+ size_t segment_size_;
+
+ /// Base shared memory key for the segment.
+ key_t base_shm_key_;
+
+ /// Find the segment that contains the @a searchPtr
+ virtual int find_seg (const void *const searchPtr,
+ off_t &offset,
+ size_t &counter);
+
+ /// Determine how much memory is currently in use.
+ virtual int in_use (off_t &offset,
+ size_t &counter);
+
+ /// Handles SIGSEGV.
+ ACE_Sig_Handler signal_handler_;
+
+ /// Handle SIGSEGV and SIGBUS signals to remap shared memory
+ /// properly.
+ virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
+};
+#endif /* !ACE_LACKS_SYSV_SHMEM */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_SHARED_MEMORY_POOL_H */
diff --git a/ace/ace.mpc b/ace/ace.mpc
index 427d28fe50a..1a7e8a68266 100644
--- a/ace/ace.mpc
+++ b/ace/ace.mpc
@@ -282,16 +282,20 @@ project(ACE) : acedefaults, aceversion, core, qt_reactor, other, codecs, token,
Based_Pointer_Repository.cpp
Malloc.cpp
PI_Malloc.cpp
+ Local_Memory_Pool.cpp
+ MMAP_Memory_Pool.cpp
Malloc_Allocator.cpp
Malloc_Instantiations.cpp
Mem_Map.cpp
- Memory_Pool.cpp
Obchunk.cpp
Obstack.cpp
+ Pagefile_Memory_Pool.cpp
Read_Buffer.cpp
+ Sbrk_Memory_Pool.cpp
Shared_Memory.cpp
Shared_Memory_MM.cpp
Shared_Memory_SV.cpp
+ Shared_Memory_Pool.cpp
}
Timer {
diff --git a/examples/System_V_IPC/SV_Semaphores/Semaphores_1.cpp b/examples/System_V_IPC/SV_Semaphores/Semaphores_1.cpp
index 1dba56c734c..ef88e2fa3e0 100644
--- a/examples/System_V_IPC/SV_Semaphores/Semaphores_1.cpp
+++ b/examples/System_V_IPC/SV_Semaphores/Semaphores_1.cpp
@@ -2,6 +2,7 @@
#include "ace/SV_Shared_Memory.h"
#include "ace/SV_Semaphore_Simple.h"
+#include "ace/SV_Semaphore_Complex.h"
#include "ace/Malloc.h"
#include "ace/OS_NS_unistd.h"
diff --git a/tests/SV_Shared_Memory_Test.cpp b/tests/SV_Shared_Memory_Test.cpp
index 7f22a2da468..1b5ae80060d 100644
--- a/tests/SV_Shared_Memory_Test.cpp
+++ b/tests/SV_Shared_Memory_Test.cpp
@@ -24,8 +24,11 @@
#include "test_config.h"
#include "ace/Malloc.h"
+#include "ace/SV_Semaphore_Simple.h"
+#include "ace/SV_Semaphore_Complex.h"
#include "ace/OS_NS_unistd.h"
+
ACE_RCSID(tests, SV_Shared_Memory_Test, "$Id$")
#if defined (ACE_HAS_SYSV_IPC) && !defined(ACE_LACKS_SYSV_SHMEM)