diff options
author | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-02-10 19:58:09 +0000 |
---|---|---|
committer | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-02-10 19:58:09 +0000 |
commit | 7ad4f697cf767302feafe6a648498e57e3e960d0 (patch) | |
tree | b71587497c9c68d639be74d8dce2021af96d25f8 | |
parent | 53ae527d407ebcf4cc9efb3bff2527a817da1c70 (diff) | |
download | ATCD-7ad4f697cf767302feafe6a648498e57e3e960d0.tar.gz |
ChangeLogTag:Thu Feb 10 13:49:34 2000 Nanbor Wang <nanbor@cs.wustl.edu>
30 files changed, 2599 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog index ed93ab22f2c..21bf0149ec6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +Thu Feb 10 13:49:34 2000 Nanbor Wang <nanbor@cs.wustl.edu> + + * ace/MEM_SAP.h: + * ace/MEM_SAP.i: + * ace/MEM_SAP.cpp: Implemented the adaptation layer for managing + shared memory in shared memory transport. + + * ace/MEM_Addr.h: + * ace/MEM_Addr.i: + * ace/MEM_Addr.cpp: Implemented the "endpoint" addressing + mechanism for shared memory transport. The ACE_MEM_Addr make + sure the "endpoint" is not on an interface that is accessable + outside of the running host. It also serves as endpoint + identification and provides the <same_host> checking method. + + * ace/MEM_IO.h: + * ace/MEM_IO.i: + * ace/MEM_IO.cpp: Implemented the IO routines for shared memory + transport. Currently, these IO routines treat shared memory + transport as a streaming devide and copy the data into its own + buffer before sending the data over. We'll add method for + acquiring and sending the internal buffer later. + + * ace/MEM_Acceptor.h: + * ace/MEM_Acceptor.i: + * ace/MEM_Acceptor.cpp: + * ace/MEM_Connector.h: + * ace/MEM_Connector.i: + * ace/MEM_Connector.cpp: + * ace/MEM_Stream.h: + * ace/MEM_Stream.i: + * ace/MEM_Stream.cpp: These classes emulate SOCK_* classes but use + shared memory as their transport mechanism. + + * ace/Malloc_T.cpp: Fixed a mis-matched ACE_TRACE message. + + * ace/OS.h: Added definitions of ACE_MEM_ACCEPTOR, + ACE_MEM_CONNECTOR and, ACE_MEM_STREAM. + + * ace/Makefile: Aded MEM_* files and updated dependencies. + + * tests/Malloc_Test.cpp: Removed explicit template instantiations + for ACE_Malloc[_T] as they are taken care of in MEM_SAP.cpp + now. + + * examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP_memclient.dsp: + * examples/IPC_SAP/SOCK_SAP/CPP_memserver.dsp: + * examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw: Added a simple example + on how to use the shared-memory transport. + Thu Feb 10 10:18:00 2000 Ossama Othman <ossama@uci.edu> * THANKS: diff --git a/ChangeLogs/ChangeLog-02a b/ChangeLogs/ChangeLog-02a index ed93ab22f2c..21bf0149ec6 100644 --- a/ChangeLogs/ChangeLog-02a +++ b/ChangeLogs/ChangeLog-02a @@ -1,3 +1,55 @@ +Thu Feb 10 13:49:34 2000 Nanbor Wang <nanbor@cs.wustl.edu> + + * ace/MEM_SAP.h: + * ace/MEM_SAP.i: + * ace/MEM_SAP.cpp: Implemented the adaptation layer for managing + shared memory in shared memory transport. + + * ace/MEM_Addr.h: + * ace/MEM_Addr.i: + * ace/MEM_Addr.cpp: Implemented the "endpoint" addressing + mechanism for shared memory transport. The ACE_MEM_Addr make + sure the "endpoint" is not on an interface that is accessable + outside of the running host. It also serves as endpoint + identification and provides the <same_host> checking method. + + * ace/MEM_IO.h: + * ace/MEM_IO.i: + * ace/MEM_IO.cpp: Implemented the IO routines for shared memory + transport. Currently, these IO routines treat shared memory + transport as a streaming devide and copy the data into its own + buffer before sending the data over. We'll add method for + acquiring and sending the internal buffer later. + + * ace/MEM_Acceptor.h: + * ace/MEM_Acceptor.i: + * ace/MEM_Acceptor.cpp: + * ace/MEM_Connector.h: + * ace/MEM_Connector.i: + * ace/MEM_Connector.cpp: + * ace/MEM_Stream.h: + * ace/MEM_Stream.i: + * ace/MEM_Stream.cpp: These classes emulate SOCK_* classes but use + shared memory as their transport mechanism. + + * ace/Malloc_T.cpp: Fixed a mis-matched ACE_TRACE message. + + * ace/OS.h: Added definitions of ACE_MEM_ACCEPTOR, + ACE_MEM_CONNECTOR and, ACE_MEM_STREAM. + + * ace/Makefile: Aded MEM_* files and updated dependencies. + + * tests/Malloc_Test.cpp: Removed explicit template instantiations + for ACE_Malloc[_T] as they are taken care of in MEM_SAP.cpp + now. + + * examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP_memclient.dsp: + * examples/IPC_SAP/SOCK_SAP/CPP_memserver.dsp: + * examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw: Added a simple example + on how to use the shared-memory transport. + Thu Feb 10 10:18:00 2000 Ossama Othman <ossama@uci.edu> * THANKS: diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index ed93ab22f2c..21bf0149ec6 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,55 @@ +Thu Feb 10 13:49:34 2000 Nanbor Wang <nanbor@cs.wustl.edu> + + * ace/MEM_SAP.h: + * ace/MEM_SAP.i: + * ace/MEM_SAP.cpp: Implemented the adaptation layer for managing + shared memory in shared memory transport. + + * ace/MEM_Addr.h: + * ace/MEM_Addr.i: + * ace/MEM_Addr.cpp: Implemented the "endpoint" addressing + mechanism for shared memory transport. The ACE_MEM_Addr make + sure the "endpoint" is not on an interface that is accessable + outside of the running host. It also serves as endpoint + identification and provides the <same_host> checking method. + + * ace/MEM_IO.h: + * ace/MEM_IO.i: + * ace/MEM_IO.cpp: Implemented the IO routines for shared memory + transport. Currently, these IO routines treat shared memory + transport as a streaming devide and copy the data into its own + buffer before sending the data over. We'll add method for + acquiring and sending the internal buffer later. + + * ace/MEM_Acceptor.h: + * ace/MEM_Acceptor.i: + * ace/MEM_Acceptor.cpp: + * ace/MEM_Connector.h: + * ace/MEM_Connector.i: + * ace/MEM_Connector.cpp: + * ace/MEM_Stream.h: + * ace/MEM_Stream.i: + * ace/MEM_Stream.cpp: These classes emulate SOCK_* classes but use + shared memory as their transport mechanism. + + * ace/Malloc_T.cpp: Fixed a mis-matched ACE_TRACE message. + + * ace/OS.h: Added definitions of ACE_MEM_ACCEPTOR, + ACE_MEM_CONNECTOR and, ACE_MEM_STREAM. + + * ace/Makefile: Aded MEM_* files and updated dependencies. + + * tests/Malloc_Test.cpp: Removed explicit template instantiations + for ACE_Malloc[_T] as they are taken care of in MEM_SAP.cpp + now. + + * examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp: + * examples/IPC_SAP/SOCK_SAP/CPP_memclient.dsp: + * examples/IPC_SAP/SOCK_SAP/CPP_memserver.dsp: + * examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw: Added a simple example + on how to use the shared-memory transport. + Thu Feb 10 10:18:00 2000 Ossama Othman <ossama@uci.edu> * THANKS: diff --git a/ace/MEM_Acceptor.cpp b/ace/MEM_Acceptor.cpp new file mode 100644 index 00000000000..d0071f5b4bc --- /dev/null +++ b/ace/MEM_Acceptor.cpp @@ -0,0 +1,196 @@ +// MEM_Acceptor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/MEM_Acceptor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/MEM_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, MEM_Acceptor, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_MEM_Acceptor) + +void +ACE_MEM_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_MEM_Acceptor::dump"); +} + +// Do nothing routine for constructor. + +ACE_MEM_Acceptor::ACE_MEM_Acceptor (void) + : mmap_prefix_ (0) +{ + ACE_TRACE ("ACE_MEM_Acceptor::ACE_MEM_Acceptor"); +} + +ACE_MEM_Acceptor::~ACE_MEM_Acceptor (void) +{ + ACE_TRACE ("ACE_MEM_Acceptor::~ACE_MEM_Acceptor"); + delete[] this->mmap_prefix_; +} + +// General purpose routine for performing server ACE_SOCK creation. + +ACE_MEM_Acceptor::ACE_MEM_Acceptor (const ACE_MEM_Addr &remote_sap, + int reuse_addr, + int backlog, + int protocol) + : mmap_prefix_ (0) +{ + ACE_TRACE ("ACE_MEM_Acceptor::ACE_MEM_Acceptor"); + if (this->open (remote_sap, + reuse_addr, + backlog, + protocol) == -1) + ACE_ERROR ((LM_ERROR, + "ACE_MEM_Acceptor::ACE_MEM_Acceptor")); +} + +int +ACE_MEM_Acceptor::open (const ACE_MEM_Addr &remote_sap, + int reuse_addr, + int back_log, + int protocol) +{ + ACE_TRACE ("ACE_MEM_Acceptor::open"); + return this->ACE_SOCK_Acceptor::open (remote_sap.get_local_addr (), + reuse_addr, + PF_INET, + back_log, + protocol); +} + +// General purpose routine for accepting new connections. + +int +ACE_MEM_Acceptor::accept (ACE_MEM_Stream &new_stream, + ACE_MEM_Addr *remote_sap, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle) +{ + ACE_TRACE ("ACE_MEM_Acceptor::accept"); + + int *len_ptr = 0; + sockaddr *addr = 0; + + int in_blocking_mode = 0; + if (this->shared_accept_start (timeout, + restart, + in_blocking_mode) == -1) + return -1; + else + { + do + new_stream.set_handle (ACE_OS::accept (this->get_handle (), + addr, + len_ptr)); + while (new_stream.get_handle () == ACE_INVALID_HANDLE + && restart != 0 + && errno == EINTR + && timeout == 0); + + if (remote_sap != 0) + { + ACE_INET_Addr temp ((sockaddr_in *) addr, *len_ptr); + remote_sap->set_port_number(temp.get_port_number ()); + } + } + + if (this->shared_accept_finish (new_stream, + in_blocking_mode, + reset_new_handle) == -1) + return -1; + + ASYS_TCHAR buf [MAXPATHLEN]; + ACE_INET_Addr local_addr; + if (new_stream.get_local_addr (local_addr) == -1) + return -1; + + if (this->mmap_prefix_ != 0) + { + ACE_OS::sprintf (buf, + ASYS_TEXT ("%s_%d_"), + this->mmap_prefix_, + local_addr.get_port_number ()); + } + else + { + const ASYS_TCHAR* temp_dir = + ACE_OS::getenv (ASYS_TEXT (ACE_DEFAULT_TEMP_DIR_ENV)); + + if (temp_dir == 0) + temp_dir = ASYS_TEXT ("/tmp"); + + ACE_OS::sprintf (buf, + ASYS_TEXT ("%s%cMEM_Acceptor_%d_"), + temp_dir, + ACE_DIRECTORY_SEPARATOR_CHAR, + local_addr.get_port_number ()); + } + ASYS_TCHAR unique [MAXPATHLEN]; + ACE_OS::unique_name (&new_stream, unique, MAXPATHLEN); + ACE_OS::strcat (buf, unique); + + // Make sure we have a fresh start. + ACE_OS::unlink (buf); + + // Now set up the shared memory malloc pool. + if (new_stream.create_shm_malloc (buf, &this->malloc_options_) == -1) + return -1; + + // @@ Need to handle timeout here. + ACE_UINT16 buf_len = ACE_OS::strlen (buf) + 1; + ACE_HANDLE new_handle = new_stream.get_handle (); + + // No need to worry about byte-order because both parties should always + // be on the same machine. + if (ACE::send (new_handle, &buf_len, sizeof (ACE_UINT16)) == -1) + return -1; + + // Now send the pathname of the mmap file. + if (ACE::send (new_handle, buf, buf_len) == -1) + return -1; + return 0; +} + +int +ACE_MEM_Acceptor::shared_accept_finish (ACE_MEM_Stream new_stream, + int in_blocking_mode, + int reset_new_handle) const +{ + ACE_TRACE ("ACE_MEM_Acceptor::shared_accept_finish ()"); + + ACE_HANDLE new_handle = new_stream.get_handle (); + + // Check to see if we were originally in blocking mode, and if so, + // set the <new_stream>'s handle and <this> handle to be in blocking + // mode. + if (in_blocking_mode) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + + // Only disable ACE_NONBLOCK if we weren't in non-blocking mode + // originally. + ACE::clr_flags (this->get_handle (), + ACE_NONBLOCK); + ACE::clr_flags (new_handle, + ACE_NONBLOCK); + } + +#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) + if (reset_new_handle) + // Reset the event association inherited by the new handle. + ::WSAEventSelect ((SOCKET) new_handle, 0, 0); +#else + ACE_UNUSED_ARG (reset_new_handle); +#endif /* ACE_WIN32 */ + if (new_handle == ACE_INVALID_HANDLE) + return -1; + + return 0; +} diff --git a/ace/MEM_Acceptor.h b/ace/MEM_Acceptor.h new file mode 100644 index 00000000000..4d8e07cc5cb --- /dev/null +++ b/ace/MEM_Acceptor.h @@ -0,0 +1,148 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// MEM_Aceeptor.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_MEM_ACCEPTOR_H +#define ACE_MEM_ACCEPTOR_H + +#include "ace/SOCK_Acceptor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/MEM_Stream.h" +#include "ace/MEM_Addr.h" + +// Forward decl. +class ACE_Reactor; + +class ACE_Export ACE_MEM_Acceptor : public ACE_SOCK_Acceptor +{ + // = TITLE + // Defines the format and interface for the acceptor side of the + // local mmap stream. I should probably designed the class + // to prevent user passing a non-localhost endpoint as the acceptor + // listen point because it doesn't make any sense at all to make + // the listening endpoint visible (or connectable) anywhere outside + // of this machine. However, I decided to leave the type of endpoint + // as <ACE_Addr> so we can later changed to use UNIX sockets with + // mmap stream if so desired. (Currently, using UNIX socket with + // this class will not work.) +public: + // = Initialization methods. + ACE_MEM_Acceptor (void); + // Default constructor. + + ~ACE_MEM_Acceptor (void); + // destructor. + + ACE_MEM_Acceptor (const ACE_MEM_Addr &remote_sap, + int reuse_addr = 0, + int backlog = ACE_DEFAULT_BACKLOG, + int protocol = 0); + // Initiate a passive mode socket. + + int open (const ACE_MEM_Addr &local_sap, + int reuse_addr = 0, + int backlog = ACE_DEFAULT_BACKLOG, + int protocol = 0); + // Initialize a passive-mode BSD-style acceptor socket (no QoS). + // <local_sap> is the address that we're going to listen for + // connections on. If <reuse_addr> is 1 then we'll use the + // <SO_REUSEADDR> to reuse this address. Returns 0 on success and + // -1 on failure. + + int accept (ACE_MEM_Stream &new_ipc_sap, + ACE_MEM_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int reset_new_handle = 0); + // Accept a new data transfer connection. + + int shared_accept_finish (ACE_MEM_Stream new_stream, + int in_blocking_mode, + int reset_new_handle) const; + // Perform operations that must occur after <ACE_OS::accept> is + // called. + + const ASYS_TCHAR *mmap_prefix (void) const; + void mmap_prefix (ASYS_TCHAR *prefix); + // Accessor/mutator of mmap filename prefix. By default, the + // <mmap_prefix_> is not set and the mmap filename is + // ${(TMP|TEMP)}//ACE_MEM_Acceptor_(port-number)_(&stream), + // otherwise, it is <mmap_prefix_>_(port-number)_(&stream), + // <mmap_prefix_> should include _absolute_ path so the connector + // within the same host can located the mmap file. + // Example: /tmp/mmapfile + + int get_local_addr (ACE_MEM_Addr &) const; + // Return the local endpoint address in the referenced <ACE_Addr>. + // Returns 0 if successful, else -1. + + ACE_MEM_SAP::MALLOC_OPTIONS& malloc_options (void); + // Accessor to the mmap options. + + // = Meta-type info + typedef ACE_MEM_Addr PEER_ADDR; + typedef ACE_MEM_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = The following methods should not be accessable externally. + int open (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = PF_INET, + int backlog = ACE_DEFAULT_BACKLOG, + int protocol = 0); + + int open (const ACE_Addr &local_sap, + ACE_Protocol_Info *protocolinfo, + ACE_SOCK_GROUP g, + u_long flags, + int reuse_addr, + int protocol_family, + int backlog = ACE_DEFAULT_BACKLOG, + int protocol = 0); + + int accept (ACE_SOCK_Stream &new_stream, + ACE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int reset_new_handle = 0) const; + + int accept (ACE_SOCK_Stream &new_stream, + ACE_Accept_QoS_Params qos_params, + ACE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int reset_new_handle = 0) const; + +private: + ASYS_TCHAR *mmap_prefix_; + + ACE_MEM_SAP::MALLOC_OPTIONS malloc_options_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/MEM_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MEM_ACCEPTOR_H */ diff --git a/ace/MEM_Acceptor.i b/ace/MEM_Acceptor.i new file mode 100644 index 00000000000..bdc1c1af7ef --- /dev/null +++ b/ace/MEM_Acceptor.i @@ -0,0 +1,70 @@ +/* -*- C++ -*- */ +// $Id$ + +// MEM_Acceptor.i + +ASYS_INLINE int +ACE_MEM_Acceptor::open (const ACE_Addr &local_sap, + ACE_Protocol_Info *protocolinfo, + ACE_SOCK_GROUP g, + u_long flags, + int reuse_addr, + int protocol_family, + int backlog, + int protocol) +{ + return this->ACE_SOCK_Acceptor::open + (local_sap, protocolinfo, g, flags, reuse_addr, protocol_family, + backlog, protocol); +} + +ASYS_INLINE int +ACE_MEM_Acceptor::accept (ACE_SOCK_Stream &new_stream, + ACE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle) const +{ + return this->ACE_SOCK_Acceptor::accept + (new_stream, remote_addr, timeout, restart, reset_new_handle); +} + +ASYS_INLINE int +ACE_MEM_Acceptor::accept (ACE_SOCK_Stream &new_stream, + ACE_Accept_QoS_Params qos_params, + ACE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart, + int reset_new_handle) const +{ + return this->ACE_SOCK_Acceptor::accept + (new_stream, qos_params, remote_addr, timeout, restart, reset_new_handle); +} + +ASYS_INLINE int +ACE_MEM_Acceptor::get_local_addr (ACE_MEM_Addr &sap) const +{ + ACE_INET_Addr temp; + + this->ACE_SOCK_Acceptor::get_local_addr (temp); + sap.set_port_number (temp.get_port_number ()); + return 0; +} + +ASYS_INLINE const ASYS_TCHAR * +ACE_MEM_Acceptor::mmap_prefix (void) const +{ + return this->mmap_prefix_; +} + +ASYS_INLINE void +ACE_MEM_Acceptor::mmap_prefix (ASYS_TCHAR *prefix) +{ + this->mmap_prefix_ = ACE::strnew (prefix); +} + +ASYS_INLINE ACE_MEM_SAP::MALLOC_OPTIONS & +ACE_MEM_Acceptor::malloc_options (void) +{ + return this->malloc_options_; +} diff --git a/ace/MEM_Addr.cpp b/ace/MEM_Addr.cpp new file mode 100644 index 00000000000..2962dfad268 --- /dev/null +++ b/ace/MEM_Addr.cpp @@ -0,0 +1,143 @@ +// $Id$ + +// Defines the Internet domain address family address format. + +#define ACE_BUILD_DLL +#include "ace/MEM_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/MEM_Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, MEM_Addr, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_MEM_Addr) + +// Transform the current address into string format. + +ACE_MEM_Addr::ACE_MEM_Addr (void) + : ACE_Addr (AF_INET, sizeof (ACE_MEM_Addr)) +{ + // ACE_TRACE ("ACE_MEM_Addr::ACE_MEM_Addr"); + this->initialize_local (0); +} + +ACE_MEM_Addr::ACE_MEM_Addr (const ACE_MEM_Addr &sa) + : ACE_Addr (AF_INET, sizeof (ACE_MEM_Addr)) +{ + ACE_TRACE ("ACE_MEM_Addr::ACE_MEM_Addr"); + this->external_.set (sa.external_); + this->internal_.set (sa.internal_); +} + +ACE_MEM_Addr::ACE_MEM_Addr (const ASYS_TCHAR port_number[]) + : ACE_Addr (AF_INET, sizeof (ACE_MEM_Addr)) +{ + ACE_TRACE ("ACE_MEM_Addr::ACE_MEM_Addr"); + u_short pn + = ACE_static_cast (u_short, + ACE_OS::strtoul (port_number, + NULL, + 10)); + this->initialize_local (pn); +} + +ACE_MEM_Addr::ACE_MEM_Addr (u_short port_number) + : ACE_Addr (AF_INET, sizeof (ACE_MEM_Addr)) +{ + ACE_TRACE ("ACE_MEM_Addr::ACE_MEM_Addr"); + this->initialize_local (port_number); +} + +int +ACE_MEM_Addr::initialize_local (u_short port_number) +{ + ASYS_TCHAR name[MAXHOSTNAMELEN + 1]; + if (ACE_OS::hostname (name, MAXHOSTNAMELEN+1) == -1) + return -1; + + this->external_.set (port_number, name); + this->internal_.set (port_number, ASYS_TEXT ("localhost")); + return 0; +} + +int +ACE_MEM_Addr::same_host (const ACE_INET_Addr &sap) +{ + ACE_TRACE ("ACE_MEM_Addr::same_host"); + + return this->external_.get_ip_address () == + sap.get_ip_address (); +} + +int +ACE_MEM_Addr::addr_to_string (ASYS_TCHAR s[], + size_t size, + int ipaddr_format) const +{ + ACE_TRACE ("ACE_MEM_Addr::addr_to_string"); + + return this->external_.addr_to_string (s, size, ipaddr_format); +} + +// Transform the string into the current addressing format. + +int +ACE_MEM_Addr::string_to_addr (const ASYS_TCHAR s[]) +{ + ACE_TRACE ("ACE_MEM_Addr::string_to_addr"); + + u_short pn + = ACE_static_cast (u_short, + ACE_OS::strtoul (s, + NULL, + 10)); + return this->set (pn); +} + +// Return the address. + +void * +ACE_MEM_Addr::get_addr (void) const +{ + ACE_TRACE ("ACE_MEM_Addr::get_addr"); + return this->external_.get_addr (); +} + +// Set a pointer to the address. +void +ACE_MEM_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_MEM_Addr::set_addr"); + + this->external_.set_addr (addr, len); + this->internal_.set_port_number (this->external_.get_port_number ()); +} + +int +ACE_MEM_Addr::get_host_name (ASYS_TCHAR hostname[], + size_t len) const +{ + ACE_TRACE ("ACE_MEM_Addr::get_host_name"); + return this->external_.get_host_name (hostname, len); +} + +// Return the character representation of the hostname. + +const ASYS_TCHAR * +ACE_MEM_Addr::get_host_name (void) const +{ + ACE_TRACE ("ACE_MEM_Addr::get_host_name"); + return this->external_.get_host_name (); +} + +void +ACE_MEM_Addr::dump (void) const +{ + ACE_TRACE ("ACE_MEM_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->external_.dump (); + this->internal_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} diff --git a/ace/MEM_Addr.h b/ace/MEM_Addr.h new file mode 100644 index 00000000000..8d683f7d4b6 --- /dev/null +++ b/ace/MEM_Addr.h @@ -0,0 +1,143 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// MEM_Addr.h +// +// = AUTHOR +// Nanbor Wang <nanbor@cs.wustl.edu> +// +// ============================================================================ + +#ifndef ACE_MEM_ADDR_H +#define ACE_MEM_ADDR_H + +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/INET_Addr.h" + +class ACE_Export ACE_MEM_Addr : public ACE_Addr +{ + // = TITLE + // Defines a C++ wrapper facade for the shared memory transport + // address family format. +public: + // = Initialization methods. + ACE_MEM_Addr (void); + // Default constructor. + + ACE_MEM_Addr (const ACE_MEM_Addr &); + // Copy constructor. + + ACE_MEM_Addr (u_short port_number); + // Creates an <ACE_INET_Addr> from a <port_number> and the remote + // <host_name>. + + ACE_MEM_Addr (const ASYS_TCHAR port_name[]); + // Creates an <ACE_INET_Addr> from a <port_name>. + + ~ACE_MEM_Addr (void); + // Default dtor. + + // = Direct initialization methods. + + int initialize_local (u_short port); + // default initialization routine. + + int same_host (const ACE_INET_Addr& sap); + // Check if <sap> designate an enpoint withing the same host. + + // These methods are useful after the object has been constructed. + + int set (u_short port_number, + int encode = 1); + // Initializes an <ACE_INET_Addr> from a <port_number> and the + // remote <host_name>. If <encode> is enabled then <port_number> is + // converted into network byte order, otherwise it is assumed to be + // in network byte order already and are passed straight through. + + int set (const ASYS_TCHAR port_name[]); + // Uses <getservbyname> to initialize an <ACE_INET_Addr> from a + // <port_name>, the remote <host_name>, and the <protocol>. + + virtual void *get_addr (void) const; + // Return a pointer to the underlying network address. + + virtual void set_addr (void *, int len); + // Set a pointer to the address. + + virtual int addr_to_string (ASYS_TCHAR buffer[], + size_t size, + int ipaddr_format = 1) const; + // Transform the external <ACE_INET_Addr> address into string + // format. + + virtual int string_to_addr (const ASYS_TCHAR address[]); + // Initializes the external <ACE_INET_Addr> from the <address>. + + void set_port_number (u_short, + int encode = 1); + // Sets the port number. + + u_short get_port_number (void) const; + // Return the port number, converting it into host byte order. + + int get_host_name (ASYS_TCHAR hostname[], + size_t hostnamelen) const; + // Return the character representation of the hostname. + + const ASYS_TCHAR *get_host_name (void) const; + // Return the character representation of the hostname (this version + // is non-reentrant since it returns a pointer to a static data + // area). + + const char *get_host_addr (void) const; + // Return the "dotted decimal" external address. + + ACE_UINT32 get_ip_address (void) const; + // Return the 4-byte external IP address, converting it into host byte + // order. + + const ACE_INET_Addr &get_remote_addr (void) const; + const ACE_INET_Addr &get_local_addr (void) const; + + int operator == (const ACE_MEM_Addr &SAP) const; + int operator == (const ACE_INET_Addr &SAP) const; + // Compare two addresses for equality. The addresses are considered + // equal if they contain the same IP address and port number. + + int operator != (const ACE_MEM_Addr &SAP) const; + int operator != (const ACE_INET_Addr &SAP) const; + // Compare two addresses for inequality. + + virtual u_long hash (void) const; + // Computes and returns hash value. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_INET_Addr external_; + // External INET addr used for identifying host. + + ACE_INET_Addr internal_; + // Internal INET addr for accepting/connecting. +}; + +#if defined (__ACE_INLINE__) +#include "ace/MEM_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MEM_ADDR_H */ diff --git a/ace/MEM_Addr.i b/ace/MEM_Addr.i new file mode 100644 index 00000000000..2dd130fca7b --- /dev/null +++ b/ace/MEM_Addr.i @@ -0,0 +1,117 @@ +/* -*- C++ -*- */ +// $Id$ + +// MEM_Addr.i + +// Default dtor. +ACE_INLINE +ACE_MEM_Addr::~ACE_MEM_Addr (void) +{ +} + +// Set the port number. + +ACE_INLINE void +ACE_MEM_Addr::set_port_number (u_short port_number, + int encode) +{ + ACE_TRACE ("ACE_MEM_Addr::set_port_number"); + + this->external_.set_port_number (port_number, encode); + this->internal_.set_port_number (port_number, encode); +} + +ACE_INLINE int +ACE_MEM_Addr::set (u_short port_number, int encode) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + this->set_port_number (port_number, encode); + return 0; +} + +ACE_INLINE int +ACE_MEM_Addr::set (const ASYS_TCHAR port_number[]) +{ + ACE_TRACE ("ACE_MEM_Addr::set"); + return this->string_to_addr (port_number); +} + +// Return the port number. + +ACE_INLINE u_short +ACE_MEM_Addr::get_port_number (void) const +{ + ACE_TRACE ("ACE_MEM_Addr::get_port_number"); + return this->internal_.get_port_number (); +} + +// Return the dotted Internet address. + +ACE_INLINE const char * +ACE_MEM_Addr::get_host_addr (void) const +{ + ACE_TRACE ("ACE_MEM_Addr::get_host_addr"); + return this->internal_.get_host_addr (); +} + +// Return the 4-byte IP address, converting it into host byte order. + +ACE_INLINE ACE_UINT32 +ACE_MEM_Addr::get_ip_address (void) const +{ + ACE_TRACE ("ACE_MEM_Addr::get_ip_address"); + return this->external_.get_ip_address (); +} + +ACE_INLINE const ACE_INET_Addr & +ACE_MEM_Addr::get_local_addr (void) const +{ + return this->internal_; +} + +ACE_INLINE const ACE_INET_Addr & +ACE_MEM_Addr::get_remote_addr (void) const +{ + return this->external_; +} + +// Compare two addresses for equality. + +ACE_INLINE int +ACE_MEM_Addr::operator == (const ACE_MEM_Addr &sap) const +{ + ACE_TRACE ("ACE_MEM_Addr::operator =="); + + return this->external_ == sap.external_ && + this->internal_ == sap.internal_; +} + +ACE_INLINE int +ACE_MEM_Addr::operator == (const ACE_INET_Addr &sap) const +{ + ACE_TRACE ("ACE_MEM_Addr::operator =="); + + return this->external_ == sap; +} + +// Compare two addresses for inequality. + +ACE_INLINE int +ACE_MEM_Addr::operator != (const ACE_MEM_Addr &sap) const +{ + ACE_TRACE ("ACE_MEM_Addr::operator !="); + return !((*this) == sap); +} + +ACE_INLINE int +ACE_MEM_Addr::operator != (const ACE_INET_Addr &sap) const +{ + ACE_TRACE ("ACE_MEM_Addr::operator !="); + return !((*this) == sap); +} + +ACE_INLINE u_long +ACE_MEM_Addr::hash (void) const +{ + return this->external_.hash (); +} diff --git a/ace/MEM_Connector.cpp b/ace/MEM_Connector.cpp new file mode 100644 index 00000000000..090e2cf2e9d --- /dev/null +++ b/ace/MEM_Connector.cpp @@ -0,0 +1,105 @@ +// MEM_Connector.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/MEM_Connector.h" + +ACE_RCSID(ace, MEM_Connector, "$Id$") + +#if defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_Connector.i" +#endif + +ACE_ALLOC_HOOK_DEFINE(ACE_MEM_Connector) + +void +ACE_MEM_Connector::dump (void) const +{ + ACE_TRACE ("ACE_MEM_Connector::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_MEM_Connector::ACE_MEM_Connector (void) +{ + ACE_TRACE ("ACE_MEM_Connector::ACE_MEM_Connector"); +} + +// Establish a connection. +ACE_MEM_Connector::ACE_MEM_Connector (ACE_MEM_Stream &new_stream, + const ACE_INET_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol) +{ + ACE_TRACE ("ACE_MEM_Connector::ACE_MEM_Connector"); + // This is necessary due to the weird inheritance relationships of + // ACE_MEM_Stream. + this->connect (new_stream, + remote_sap, + timeout, + local_sap, + reuse_addr, + flags, + perms, + protocol); +} + +int +ACE_MEM_Connector::connect (ACE_MEM_Stream &new_stream, + const ACE_INET_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol) +{ + ACE_TRACE ("ACE_MEM_Connector::connect"); + + if (!this->address_.same_host (remote_sap)) + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%P|%t) MEM_Connector can't connect ") + ASYS_TEXT ("to %s:%d which is not a local endpoint"), + remote_sap.get_host_name (), + remote_sap.get_port_number ()), + -1); + else + this->address_.set_port_number (remote_sap.get_port_number ()); + + + ACE_SOCK_Stream temp_stream; + + if (ACE_SOCK_Connector::connect (temp_stream, + this->address_.get_local_addr (), + timeout, local_sap, + reuse_addr, flags, perms, + PF_INET, protocol) == -1) + return -1; + + ACE_HANDLE new_handle = temp_stream.get_handle (); + new_stream.set_handle (new_handle); + // Do not close the handle. + + // now we should setup the mmap malloc. + char buf[MAXPATHLEN]; + + // @@ Need to handle timeout here. + ACE_INT16 buf_len; + // Byte-order is not a problem for this read. + if (ACE::recv (new_handle, &buf_len, sizeof (buf_len)) == -1) + return -1; + + if (ACE::recv (new_handle, buf, buf_len) == -1) + return -1; + + if (new_stream.create_shm_malloc (buf, &this->malloc_options_) == -1) + return -1; + + return 0; +} diff --git a/ace/MEM_Connector.h b/ace/MEM_Connector.h new file mode 100644 index 00000000000..4879708efb4 --- /dev/null +++ b/ace/MEM_Connector.h @@ -0,0 +1,106 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// MEM_Connector.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_MEM_CONNECTOR_H +#define ACE_MEM_CONNECTOR_H + +#include "ace/SOCK_Connector.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/MEM_Stream.h" +#include "ace/MEM_Addr.h" + +class ACE_Export ACE_MEM_Connector : public ACE_SOCK_Connector +{ + // = TITLE + // Defines the format and interface for the connector side of + // the <ACE_MEM_Stream>. +public: + // = Initialization methods. + ACE_MEM_Connector (void); + // Default constructor. + + ACE_MEM_Connector (ACE_MEM_Stream &new_stream, + const ACE_INET_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol = 0); + // Actively connect and produce a <new_stream> if things go well. + // The <remote_sap> is the address that we are trying to connect + // with. The <timeout> is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with <errno == EWOULDBLOCK>. If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made <errno == ETIME>. The + // <local_sap> is the value of local address to bind to. If it's + // the default value of <0> then the user is letting + // the OS do the binding. If <reuse_addr> == 1 then the + // <local_addr> is reused, even if it hasn't been cleanedup yet. + + int connect (ACE_MEM_Stream &new_stream, + const ACE_INET_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol = 0); + // Actively connect and produce a <new_stream> if things go well. + // The <remote_sap> is the address that we are trying to connect + // with. The <timeout> is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with <errno == EWOULDBLOCK>. If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made <errno == ETIME>. The + // <local_sap> is the value of local address to bind to. If it's + // the default value of <0> then the user is letting + // the OS do the binding. If <reuse_addr> == 1 then the + // <local_addr> is reused, even if it hasn't been cleanedup yet. + + ACE_MEM_SAP::MALLOC_OPTIONS &malloc_options (void); + // Accessor to underlying malloc options. + + // = Meta-type info + typedef ACE_INET_Addr PEER_ADDR; + typedef ACE_MEM_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_MEM_Addr address_; + + ACE_MEM_SAP::MALLOC_OPTIONS malloc_options_; +}; + +#if !defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_Connector.i" +#endif + +#endif /* ACE_MEM_CONNECTOR_H */ diff --git a/ace/MEM_Connector.i b/ace/MEM_Connector.i new file mode 100644 index 00000000000..3fdf59e19e0 --- /dev/null +++ b/ace/MEM_Connector.i @@ -0,0 +1,12 @@ +/* -*- C++ -*- */ +// $Id$ + +// MEM_Connector.i + +// Establish a connection. + +ASYS_INLINE ACE_MEM_SAP::MALLOC_OPTIONS & +ACE_MEM_Connector::malloc_options (void) +{ + return this->malloc_options_; +} diff --git a/ace/MEM_IO.cpp b/ace/MEM_IO.cpp new file mode 100644 index 00000000000..3b0b8867043 --- /dev/null +++ b/ace/MEM_IO.cpp @@ -0,0 +1,160 @@ +// MEM_IO.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/MEM_IO.h" +#include "ace/Handle_Set.h" + +#if defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_IO.i" +#endif /* ACE_LACKS_INLINE_FUNCTIONS */ + +ACE_RCSID(ace, MEM_IO, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_MEM_IO) + +void +ACE_MEM_IO::dump (void) const +{ + ACE_TRACE ("ACE_MEM_IO::dump"); +} + +// Allows a client to read from a socket without having to provide +// a buffer to read. This method determines how much data is in the +// socket, allocates a buffer of this size, reads in the data, and +// returns the number of bytes read. + +#if 0 +ssize_t +ACE_MEM_IO::recvv (iovec *io_vec, + const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_MEM_IO::recvv"); +#if defined (FIONREAD) + ACE_Handle_Set handle_set; + handle_set.reset (); + handle_set.set_bit (this->get_handle ()); + + io_vec->iov_base = 0; + + // Check the status of the current socket. + switch (ACE_OS::select (int (this->get_handle ()) + 1, + handle_set, + 0, 0, + timeout)) + { + case -1: + return -1; + /* NOTREACHED */ + case 0: + errno = ETIME; + return -1; + /* NOTREACHED */ + default: + // Goes fine, fallthrough to get data + break; + } + + u_long inlen; + + if (ACE_OS::ioctl (this->get_handle (), + FIONREAD, + (u_long *) &inlen) == -1) + return -1; + else if (inlen > 0) + { + ACE_NEW_RETURN (io_vec->iov_base, + char[inlen], + -1); + io_vec->iov_len = this->recv (io_vec->iov_base, + inlen); + return io_vec->iov_len; + } + else + return 0; +#else + ACE_UNUSED_ARG (io_vec); + ACE_UNUSED_ARG (timeout); + ACE_NOTSUP_RETURN (-1); +#endif /* FIONREAD */ +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_MEM_IO::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_MEM_IO::send"); + + va_list argp; + size_t total_tuples = n / 2; + iovec *iovp; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, ssize_t); + } + + ssize_t result = ACE_OS::sendv (this->get_handle (), + iovp, + total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use +// the struct iovec_Base explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_MEM_IO::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_MEM_IO::recv"); + + va_list argp; + size_t total_tuples = n / 2; + iovec *iovp; +#if defined (ACE_HAS_ALLOCA) + iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + ACE_NEW_RETURN (iovp, + iovec[total_tuples], + -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, ssize_t); + } + + ssize_t result = ACE_OS::recvv (this->get_handle (), + iovp, + total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} +#endif /* 0 */ diff --git a/ace/MEM_IO.h b/ace/MEM_IO.h new file mode 100644 index 00000000000..9780f2c4701 --- /dev/null +++ b/ace/MEM_IO.h @@ -0,0 +1,128 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// MEM_IO.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_MEM_IO_H +#define ACE_MEM_IO_H + +#include "ace/SOCK.h" +#include "ace/MEM_SAP.h" +#include "ace/Memory_Pool.h" +#include "ace/Malloc_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class ACE_Export ACE_MEM_IO : public ACE_SOCK, public ACE_MEM_SAP +{ + // = TITLE + // Defines the methods for the ACE shared memeory wrapper I/O routines + // (e.g., send/recv). +public: + // = Initialization and termination methods. + ACE_MEM_IO (); + // Constructor. + + ~ACE_MEM_IO (void); + // Destructor. + + ssize_t send (const void *buf, + size_t n, + int flags) ; + // Send an <n> byte buffer to the other process using shm_malloc_ + // connected thru the socket. + + ssize_t recv (void *buf, + size_t n, + int flags) ; + // Recv an <n> byte buffer from the shm_malloc_ thru connected socket. + + ssize_t send (const void *buf, + size_t n) ; + // Send an <n> byte buffer to the other process using shm_malloc_ + // connected thru the socket. + + ssize_t recv (void *buf, + size_t n) ; + // Recv an <n> byte buffer from the shm_malloc_ thru connected socket. + + ssize_t fetch_recv_buf (int flags, const ACE_Time_Value *timeout = 0); + // @@ Please fill in here. + + ssize_t send (const void *buf, + size_t n, + int flags, + const ACE_Time_Value *timeout); + // Wait to to <timeout> amount of time to send up to <n> bytes into + // <buf> from <handle> (uses the <send> call). If <send> times out + // a -1 is returned with <errno == ETIME>. If it succeeds the + // number of bytes sent is returned. + + ssize_t recv (void *buf, + size_t n, + int flags, + const ACE_Time_Value *timeout); + // Wait up to <timeout> amount of time to receive up to <n> bytes + // into <buf> from <handle> (uses the <recv> call). If <recv> times + // out a -1 is returned with <errno == ETIME>. If it succeeds the + // number of bytes received is returned. + + ssize_t send (const void *buf, + size_t n, + const ACE_Time_Value *timeout); + // Wait to to <timeout> amount of time to send up to <n> bytes into + // <buf> from <handle> (uses the <send> call). If <send> times out + // a -1 is returned with <errno == ETIME>. If it succeeds the + // number of bytes sent is returned. + + ssize_t recv (void *buf, + size_t n, + const ACE_Time_Value *timeout); + // Wait up to <timeout> amount of time to receive up to <n> bytes + // into <buf> from <handle> (uses the <recv> call). If <recv> times + // out a -1 is returned with <errno == ETIME>. If it succeeds the + // number of bytes received is returned. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + /* int get_local_port (u_short &) const; + // Return the local endpoint port number. Returns 0 if successful, + // else -1. + + int get_remote_port (u_short &) const; + // Return the port number of the remotely connected peer (if there + // is one). Returns 0 if successful, else -1. + */ +private: + void *recv_buffer_; + // Internal pointer for support recv/send. + + ssize_t buf_size_; + // total buffer size. + + ssize_t cur_offset_; + // current read pointer location. +}; + +#if !defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_IO.i" +#endif + +#endif /* ACE_SOCK_IO_H */ diff --git a/ace/MEM_IO.i b/ace/MEM_IO.i new file mode 100644 index 00000000000..aa2cadb1a18 --- /dev/null +++ b/ace/MEM_IO.i @@ -0,0 +1,168 @@ +/* -*- C++ -*- */ +// $Id$ + +// MEM_IO.i + +// Send an n byte message to the connected socket. +ASYS_INLINE +ACE_MEM_IO::ACE_MEM_IO (void) + : recv_buffer_ (0), + buf_size_ (0), + cur_offset_ (0) +{ + // ACE_TRACE ("ACE_MEM_IO::ACE_MEM_IO"); +} + +ASYS_INLINE ssize_t +ACE_MEM_IO::fetch_recv_buf (int flag, const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_MEM_IO::fetch_recv_buf"); + + // This method can only be called when <buf_size_> == <cur_offset_>. + ACE_ASSERT (this->buf_size_ == this->cur_offset_); + + // We have done using the previous buffer, return it to malloc. + if (this->recv_buffer_ != 0) + this->release_buffer (this->recv_buffer_); + + this->cur_offset_ = 0; + off_t new_offset = 0; + int retv = ACE::recv (this->get_handle (), + (char *) &new_offset, + sizeof (off_t), + flag, + timeout); + + if (retv != sizeof (off_t)) + { + // Nothing available or we are really screwed. + this->buf_size_ = 0; + this->recv_buffer_ = 0; + return -1; + } + else + this->buf_size_ = this->get_buf_len (new_offset, + this->recv_buffer_); + return this->buf_size_; +} + +ASYS_INLINE +ACE_MEM_IO::~ACE_MEM_IO (void) +{ + // ACE_TRACE ("ACE_MEM_IO::~ACE_MEM_IO"); +} + +ASYS_INLINE ssize_t +ACE_MEM_IO::send (const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_MEM_IO::send"); + void *sbuf = this->acquire_buffer (len); + if (sbuf == 0) + return -1; // Memory buffer not initialized. + ACE_OS::memcpy (sbuf, buf, len); + off_t offset = this->set_buf_len (sbuf, len); // <set_buf_len> also calculate + // the offset. + + // Send the offset value over the socket. + if (ACE::send (this->get_handle (), + (const char *) &offset, + sizeof (offset), + flags, + timeout) != sizeof (offset)) + { + // unsucessful send, release the memory in the shared-memory. + this->release_buffer (sbuf); + + return -1; + } + return len; +} + +ASYS_INLINE ssize_t +ACE_MEM_IO::recv (void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_MEM_IO::recv"); + + size_t count = 0; + +// while (len > 0) +// { + size_t buf_len = this->buf_size_ - this->cur_offset_; + if (buf_len == 0) + { + if (this->fetch_recv_buf (flags, timeout) == -1) + return -1; + buf_len = this->buf_size_; + } + + size_t length = (len > buf_len ? buf_len : len); + + ACE_OS::memcpy ((char *) buf + count, + (char *) this->recv_buffer_ + this->cur_offset_, + length); + this->cur_offset_ += length; +// len -= length; + count += length; +// } + + return count; +} + +ASYS_INLINE ssize_t +ACE_MEM_IO::send (const void *buf, size_t n, int flags) +{ + ACE_TRACE ("ACE_MEM_IO::send"); + return this->send (buf, n, flags, 0); +} + +// Recv an n byte message from the connected socket. + +ASYS_INLINE ssize_t +ACE_MEM_IO::recv (void *buf, size_t n, int flags) +{ + ACE_TRACE ("ACE_MEM_IO::recv"); + return this->recv (buf, n, flags, 0); +} + +// Send an n byte message to the connected socket. + +ASYS_INLINE ssize_t +ACE_MEM_IO::send (const void *buf, size_t n) +{ + ACE_TRACE ("ACE_MEM_IO::send"); + return this->send (buf, n, 0); +} + +// Recv an n byte message from the connected socket. + +ASYS_INLINE ssize_t +ACE_MEM_IO::recv (void *buf, size_t n) +{ + ACE_TRACE ("ACE_MEM_IO::recv"); + + return this->recv (buf, n, 0); +} + +ASYS_INLINE ssize_t +ACE_MEM_IO::recv (void *buf, + size_t len, + const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_MEM_IO::recv"); + return this->recv (buf, len, 0, timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_IO::send (const void *buf, + size_t len, + const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_MEM_IO::send"); + return this->send (buf, len, 0, timeout); +} diff --git a/ace/MEM_SAP.cpp b/ace/MEM_SAP.cpp new file mode 100644 index 00000000000..6bd8dc184ee --- /dev/null +++ b/ace/MEM_SAP.cpp @@ -0,0 +1,80 @@ +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/MEM_SAP.h" + +#if defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_SAP.i" +#endif + +ACE_RCSID(ace, IPC_SAP, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_IPC_SAP) + +void +ACE_MEM_SAP::dump (void) const +{ + ACE_TRACE ("ACE_MEM_SAP::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + if (this->shm_malloc_ != 0) + this->shm_malloc_->dump (); + else + ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("ACE_MEM_SAP uninitialized.\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_MEM_SAP::ACE_MEM_SAP (void) + : shm_malloc_ (0) +{ + // ACE_TRACE ("ACE_MEM_SAP::ACE_MEM_SAP"); +} + +int +ACE_MEM_SAP::create_shm_malloc (const char *name, + MALLOC_OPTIONS *options) +{ + ACE_TRACE ("ACE_MEM_SAP::create_shm_malloc"); + + if (this->shm_malloc_ != 0) + return -1; // already initialized. + + ACE_NEW_RETURN (this->shm_malloc_, + MALLOC (name, + 0, + options), + -1); + + return 0; +} + +int +ACE_MEM_SAP::close_shm_malloc (const int remove) +{ + if (this->shm_malloc_ != 0 && remove != 0) + { + this->shm_malloc_->remove (); + return 0; + } + return -1; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Write_Guard<ACE_Process_Mutex>; +template class ACE_Read_Guard<ACE_Process_Mutex>; +#if defined (ACE_HAS_POSITION_INDEPENDENT_MALLOC) +template class ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block>; +#else +template class ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex>; +template class ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_Control_Block>; +#endif /* ACE_HAS_POSITION_INDEPENDENT_MALLOC */ +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Write_Guard<ACE_Process_Mutex> +#pragma instantiate ACE_Read_Guard<ACE_Process_Mutex> +#if defined (ACE_HAS_POSITION_INDEPENDENT_MALLOC) +#pragma instantiate ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> +#else +#pragma instantiate ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> +#pragma instantiate ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_Control_Block> +#endif /* ACE_HAS_POSITION_INDEPENDENT_MALLOC */ +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/ace/MEM_SAP.h b/ace/MEM_SAP.h new file mode 100644 index 00000000000..9cdba3e5a75 --- /dev/null +++ b/ace/MEM_SAP.h @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// MEM_SAP.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_MEM_SAP_H +#define ACE_MEM_SAP_H + +#include "ace/Malloc.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class ACE_Export ACE_MEM_SAP +{ + // = TITLE + // Defines the methods of shared memory management for + // shared memory transport. +public: + // = Initialization and termination methods. + +#if defined (ACE_HAS_POSITION_INDEPENDENT_MALLOC) + typedef ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> MALLOC; +#else + typedef ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_Control_Block> MALLOC; +#endif /* ACE_HAS_POSITION_INDEPENDENT_MALLOC */ + typedef ACE_MMAP_Memory_Pool_Options MALLOC_OPTIONS; + // I'll just hardcode this for mmap for now. + + ~ACE_MEM_SAP (void); + // Destructor. + + void * acquire_buffer (const ssize_t size); + // request a buffer of size <size>. Return 0 if the <shm_malloc_> is + // not initialized. + + int release_buffer (void *buf); + // release a buffer pointed by <buf>. Return -1 if the <shm_malloc_> + // is not initialized. + + off_t set_buf_len (const void *buf, + size_t n); + // Set the length of buf (containing information) to <n> bytes. + // Return the offset of the <buf> relative to the base address. + // <buf> must be acquired by <get_buffer> method. Return -1 if the + // <shm_malloc_> is not initialized. + + ssize_t get_buf_len (const off_t off, void *&buf); + // Convert the buffer offset <off> to absolute address to <buf>. + // Return the size of valid information containing in the <buf>, + // -1 if <shm_malloc_> is not initialized. + + int remove (void); + // Remove the shared resouce (mmap file) used by us. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + + // = Class initializing methods to create/connect to a shared memory pool. + + int create_shm_malloc (const char *name, + MALLOC_OPTIONS *options = 0); + // Create a new shm_malloc object. Return 0 if succeed and -1 otherwise. + // This method should only be called from an acceptor class that wants to + // create a new memory pool for inter process communication. + + int close_shm_malloc (const int remove = 0); + // Close down the share memory pool. If <remove> != 0, then the mmap file + // will also get removed. + + MALLOC *shm_malloc_; + // Data exchange channel. + + ACE_MEM_SAP (void); + // Constructor. Prevent this class from being instantiated. +}; + +#if !defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_SAP.i" +#endif + +#endif /* ACE_SOCK_IO_H */ diff --git a/ace/MEM_SAP.i b/ace/MEM_SAP.i new file mode 100644 index 00000000000..92506fe203e --- /dev/null +++ b/ace/MEM_SAP.i @@ -0,0 +1,89 @@ +/* -*- C++ -*- */ +// $Id$ + +// MEM_SAP.i + +ASYS_INLINE +ACE_MEM_SAP::~ACE_MEM_SAP (void) +{ + // ACE_TRACE ("ACE_MEM_SAP::~ACE_MEM_SAP"); + delete this->shm_malloc_; +} + + +ASYS_INLINE void * +ACE_MEM_SAP::acquire_buffer (const ssize_t size) +{ + ACE_TRACE ("ACE_MEM_SAP::acquire_buffer"); + if (this->shm_malloc_ == 0) + return 0; // not initialized. + + size_t *lptr = ACE_static_cast (size_t *, + this->shm_malloc_->malloc (sizeof (size_t) + size)); + + *lptr = size; + ++lptr; + + return lptr; +} + +ASYS_INLINE int +ACE_MEM_SAP::release_buffer (void *buf) +{ + ACE_TRACE ("ACE_MEM_SAP::release_buffer"); + if (this->shm_malloc_ == 0) + return -1; // not initialized. + + size_t *lptr = ACE_static_cast (size_t *, buf); + + --lptr; + this->shm_malloc_->free (lptr); + return 0; +} + +ASYS_INLINE off_t +ACE_MEM_SAP::set_buf_len (const void *buf, size_t n) +{ + ACE_TRACE ("ACE_MEM_SAP::set_buf_len"); + if (this->shm_malloc_ == 0) + return -1; + + size_t *lptr = ACE_static_cast (size_t *, buf); + --lptr; + + if (*lptr >= n) + *lptr = n; + + return ((char *) lptr - (char *) this->shm_malloc_->memory_pool ().base_addr ()); +} + +ASYS_INLINE ssize_t +ACE_MEM_SAP::get_buf_len (const off_t off, void *&buf) +{ + ACE_TRACE ("ACE_MEM_SAP::get_buf_len"); + + if (this->shm_malloc_ == 0) + return -1; + + ssize_t retv = 0; + + ACE_SEH_TRY + { + size_t *lptr = (size_t*) ((char *) this->shm_malloc_->memory_pool ().base_addr () + off); + buf = lptr + 1; + retv = *lptr; + } + ACE_SEH_EXCEPT (this->shm_malloc_->memory_pool ().seh_selector (GetExceptionInformation ())) + { + } + + return retv; +} + +ASYS_INLINE int +ACE_MEM_SAP::remove (void) +{ + ACE_TRACE ("ACE_MEM_SAP::remove"); + + return close_shm_malloc (1); +} diff --git a/ace/MEM_Stream.cpp b/ace/MEM_Stream.cpp new file mode 100644 index 00000000000..de870c1c66b --- /dev/null +++ b/ace/MEM_Stream.cpp @@ -0,0 +1,35 @@ +// MEM_Stream.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/MEM_Stream.h" + +#if defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_Stream.i" +#endif + +ACE_RCSID(ace, MEM_Stream, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_MEM_Stream) + +void +ACE_MEM_Stream::dump (void) const +{ + ACE_TRACE ("ACE_MEM_Stream::dump"); +} + +int +ACE_MEM_Stream::close (void) +{ +#if defined (ACE_WIN32) + // We need the following call to make things work correctly on + // Win32, which requires use to do a <close_writer> before doing the + // close in order to avoid losing data. Note that we don't need to + // do this on UNIX since it doesn't have this "feature". Moreover, + // this will cause subtle problems on UNIX due to the way that + // fork() works. + this->close_writer (); +#endif /* ACE_WIN32 */ + // Close down the socket. + return ACE_SOCK::close (); +} diff --git a/ace/MEM_Stream.h b/ace/MEM_Stream.h new file mode 100644 index 00000000000..f31b6cbec2c --- /dev/null +++ b/ace/MEM_Stream.h @@ -0,0 +1,126 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// MEM_Stream.h +// +// = AUTHOR +// Nanbor Wang +// +// ============================================================================ + +#ifndef ACE_MEM_STREAM_H +#define ACE_MEM_STREAM_H + +#include "ace/MEM_IO.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/INET_Addr.h" + +class ACE_MEM_Acceptor; +class ACE_MEM_Connector; + +class ACE_Export ACE_MEM_Stream : public ACE_MEM_IO +{ + // = TITLE + // Defines the methods in the <ACE_MEM_Stream> abstraction. + // + // = DESCRIPTION + // This adds additional wrapper methods atop the <ACE_MEM_IO> + // class. +public: + + friend class ACE_MEM_Acceptor; + friend class ACE_MEM_Connector; + + // Initialization and termination methods. + ACE_MEM_Stream (void); + // Constructor. + + ACE_MEM_Stream (ACE_HANDLE h); + // Constructor (sets the underlying <ACE_HANDLE> with <h>). + + ~ACE_MEM_Stream (void); + // Destructor. + + //= The following two methods use write and read system calls. + ssize_t send_n (const void *buf, int n); + // Send n bytes, keep trying until n are sent. + ssize_t recv_n (void *buf, int n); + // Recv n bytes, keep trying until n are received. + + // = The following two methods use the send and recv system calls. + ssize_t send_n (const void *buf, int n, int flags); + // Send n bytes, keep trying until n are sent. + ssize_t recv_n (void *buf, int n, int flags); + // Recv n bytes, keep trying until n are received. + +/* + ssize_t send_n (const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout); + // Try to send exactly <len> bytes into <buf> from <handle> (uses + // the <send> call). If <send> blocks for longer than <timeout> the + // number of bytes actually sent is returned with <errno == ETIME>. + // If a timeout does not occur, <send_n> return <len> (i.e., the + // number of bytes requested to be sent). + + ssize_t recv_n (void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout); + // Try to recv exactly <len> bytes into <buf> from <handle> (uses + // the <ACE::recv_n> call). The <ACE_Time_Value> indicates how long + // to blocking trying to receive. If <timeout> == 0, the caller + // will block until action is possible, else will wait until the + // relative time specified in *<timeout> elapses). If <recv> blocks + // for longer than <timeout> the number of bytes actually read is + // returned with <errno == ETIME>. If a timeout does not occur, + // <recv_n> return <len> (i.e., the number of bytes requested to be + // read). + + ssize_t sendv_n (const iovec iov[], + size_t n) const; + // Send an <iovec> of size <n> to the connected socket (uses + // <ACE::sendv_n>). Will block until all bytes are sent or an error + // occurs. + + ssize_t recvv_n (iovec iov[], + size_t n) const; + // Receive an <iovec> of size <n> to the connected socket. +*/ + // = Selectively close endpoints. + int close_reader (void); + // Close down the reader. + int close_writer (void); + // Close down the writer. + + int close (void); + // Close down the socket (we need this to make things work correctly + // on Win32, which requires use to do a <close_writer> before doing + // the close to avoid losing data). + + // = Meta-type info + typedef ACE_Addr PEER_ADDR; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if !defined (ACE_LACKS_INLINE_FUNCTIONS) +#include "ace/MEM_Stream.i" +#endif + +#endif /* ACE_MEM_STREAM_H */ diff --git a/ace/MEM_Stream.i b/ace/MEM_Stream.i new file mode 100644 index 00000000000..7aa77710e49 --- /dev/null +++ b/ace/MEM_Stream.i @@ -0,0 +1,176 @@ +/* -*- C++ -*- */ +// $Id$ + +// MEM_Stream.i + +#include "ace/MEM_Stream.h" + +ASYS_INLINE +ACE_MEM_Stream::ACE_MEM_Stream (void) +{ + // ACE_TRACE ("ACE_MEM_Stream::ACE_MEM_Stream"); +} + +ASYS_INLINE +ACE_MEM_Stream::ACE_MEM_Stream (ACE_HANDLE h) +{ + // ACE_TRACE ("ACE_MEM_Stream::ACE_MEM_Stream"); + this->set_handle (h); +} + +ASYS_INLINE +ACE_MEM_Stream::~ACE_MEM_Stream (void) +{ + // ACE_TRACE ("ACE_MEM_Stream::~ACE_MEM_Stream"); +} + +ASYS_INLINE int +ACE_MEM_Stream::close_reader (void) +{ + ACE_TRACE ("ACE_MEM_Stream::close_reader"); + if (this->get_handle () != ACE_INVALID_HANDLE) + return ACE_OS::shutdown (this->get_handle (), 0); + else + return 0; +} + +// Shut down just the writing end of a ACE_SOCK. + +ASYS_INLINE int +ACE_MEM_Stream::close_writer (void) +{ + ACE_TRACE ("ACE_MEM_Stream::close_writer"); + if (this->get_handle () != ACE_INVALID_HANDLE) + return ACE_OS::shutdown (this->get_handle (), 1); + else + return 0; +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::send_n (const void *buf, int n) +{ + return this->send (buf, n); +} + + +ASYS_INLINE ssize_t +ACE_MEM_Stream::recv_n (void *buf, int n) +{ + return this->recv (buf, n); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::send_n (const void *buf, int n, int flags) +{ + return this->send (buf, n, flags); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::recv_n (void *buf, int n, int flags) +{ + return this->recv (buf, n, flags); +} + +#if 0 +ASYS_INLINE ssize_t +ACE_MEM_Stream::recv_n (void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::recv_n"); + return ACE::recv_n (this->get_handle (), + buf, + len, + flags, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::recv_n (void *buf, + size_t len, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::recv_n"); + return ACE::recv_n (this->get_handle (), + buf, + len, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::recvv_n (iovec iov[], + size_t n, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::recvv_n"); + return ACE::recvv_n (this->get_handle (), + iov, + n, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::send_n (const void *buf, + size_t len, + int flags, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::send_n"); + return ACE::send_n (this->get_handle (), + buf, + len, + flags, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::send_n (const void *buf, + size_t len, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::send_n"); + return ACE::send_n (this->get_handle (), + buf, + len, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::sendv_n (iovec iov[], + size_t n, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::sendv_n"); + return ACE::sendv_n (this->get_handle (), + iov, + n, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::send_urg (const void *ptr, + size_t len, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::send_urg"); + return ACE::send (this->get_handle (), + ptr, + len, + MSG_OOB, + timeout); +} + +ASYS_INLINE ssize_t +ACE_MEM_Stream::recv_urg (void *ptr, + size_t len, + const ACE_Time_Value *timeout) const +{ + ACE_TRACE ("ACE_MEM_Stream::recv_urg"); + return ACE::recv (this->get_handle (), + ptr, + len, + MSG_OOB, + timeout); +} +#endif /* 0 */ diff --git a/ace/Makefile b/ace/Makefile index ddbb7c4477d..54a25bf28fc 100644 --- a/ace/Makefile +++ b/ace/Makefile @@ -138,7 +138,13 @@ IPC_FILES = \ UNIX_Addr \ UPIPE_Acceptor \ UPIPE_Connector \ - UPIPE_Stream + UPIPE_Stream \ + MEM_Acceptor \ + MEM_Addr \ + MEM_Connector \ + MEM_IO \ + MEM_SAP \ + MEM_Stream SVCCONF_FILES = \ DLL \ Parse_Node \ diff --git a/ace/Malloc_T.cpp b/ace/Malloc_T.cpp index b96087af560..1665f630257 100644 --- a/ace/Malloc_T.cpp +++ b/ace/Malloc_T.cpp @@ -61,7 +61,7 @@ ACE_Allocator_Adapter<MALLOC>::~ACE_Allocator_Adapter (void) template <class MALLOC> void ACE_Allocator_Adapter<MALLOC>::print_stats (void) const { - ACE_TRACE ("ACE_Malloc_T<MALLOC>::print_stats"); + ACE_TRACE ("ACE_Allocator_Adaptor<MALLOC>::print_stats"); this->allocator_.print_stats (); } #endif /* ACE_HAS_MALLOC_STATS */ @@ -666,7 +666,7 @@ ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>::unbind (const char *name, void * if (curr->next_) curr->next_->prev_ = prev; - + // This will free up both the node and the name due to our // clever trick in <bind>! this->shared_free (curr); @@ -1637,6 +1637,11 @@ private: ACE_Time_Value *max_wait_time_; # define ACE_SOCK_CONNECTOR ACE_SOCK_Connector # define ACE_SOCK_STREAM ACE_SOCK_Stream +// Handle ACE_MEM_* +# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor +# define ACE_MEM_CONNECTOR ACE_MEM_Connector +# define ACE_MEM_STREAM ACE_MEM_Stream + // Handle ACE_LSOCK_* # define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor # define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector @@ -1713,6 +1718,11 @@ private: ACE_Time_Value *max_wait_time_; # define ACE_SOCK_CONNECTOR ACE_SOCK_Connector, ACE_INET_Addr # define ACE_SOCK_STREAM ACE_SOCK_Stream, ACE_INET_Addr +// Handle ACE_MEM_* +# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor, ACE_MEM_Addr +# define ACE_MEM_CONNECTOR ACE_MEM_Connector, ACE_INET_Addr +# define ACE_MEM_STREAM ACE_MEM_Stream, ACE_INET_Addr + // Handle ACE_LSOCK_* # define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor, ACE_UNIX_Addr # define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector, ACE_UNIX_Addr diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp new file mode 100644 index 00000000000..37182fd2c38 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp @@ -0,0 +1,56 @@ +// $Id$ + +// This tests the features of the <ACE_MEM_Connector> and +// <ACE_MEM_Stream> classes. In addition, it can be used to test the +// oneway and twoway latency and throughput at the socket-level. This +// is useful as a baseline to compare against ORB-level performance +// for the same types of data. + +#include "ace/MEM_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Thread_Manager.h" +#include "ace/Singleton.h" +#include "ace/Get_Opt.h" +#include "ace/High_Res_Timer.h" +#include "ace/Synch.h" + +ACE_RCSID(SOCK_SAP, CPP_inclient, "$Id$") + +static int +run_client (void) +{ + ACE_MEM_Connector connector; + ACE_MEM_Stream stream; + ACE_INET_Addr server_addr (ACE_DEFAULT_SERVER_PORT, "COYOTE"); + + if (connector.connect (stream, server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + char buf [MAXPATHLEN]; + while (gets (buf) >0) + { + stream.send (buf, ACE_OS::strlen (buf)+1); + stream.recv (buf, MAXPATHLEN); + ACE_DEBUG ((LM_DEBUG, "Echo: %s\n", buf)); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + // Initialize the logger. + ACE_LOG_MSG->open (argv[0]); + + // Run the client + run_client (); + + return 0; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp new file mode 100644 index 00000000000..0dcf1c29cbc --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp @@ -0,0 +1,70 @@ +// $Id$ + +// This example tests the features of the <ACE_MEM_Acceptor>, +// <ACE_MEM_Stream>, and <ACE_Svc_Handler> classes. If the platform +// supports threads it uses a thread-per-connection concurrency model. +// Otherwise, it uses a single-threaded iterative server model. + +#include "ace/MEM_Acceptor.h" +#include "ace/Thread_Manager.h" +#include "ace/Handle_Set.h" +#include "ace/Profile_Timer.h" + +ACE_RCSID(SOCK_SAP, CPP_inserver, "$Id$") + +static int +run_event_loop (u_short port) +{ + // Create the acceptors. + ACE_MEM_Acceptor acceptor; + + ACE_MEM_Addr server_addr (port); + + // Create acceptors, reuse the address. + if (acceptor.open (server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + 1); + else if (acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_local_addr"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting server at port %d\n", + server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor + // calls within the loop. + ACE_MEM_Stream new_stream; + + // blocking wait on accept. + if (acceptor.accept (new_stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "accept"), + -1); + + char buf[MAXPATHLEN]; + int len = 0; + while ((len = new_stream.recv (buf, MAXPATHLEN)) != -1) + { + ACE_DEBUG ((LM_DEBUG, "%s\n", buf)); + new_stream.send (buf, len); + } + + return new_stream.remove (); +} + +int +main (int argc, char *argv[]) +{ + u_short port = ACE_DEFAULT_SERVER_PORT; + + if (argc > 1) + port = ACE_OS::atoi (argv[1]); + + return run_event_loop (port); +} diff --git a/examples/IPC_SAP/SOCK_SAP/CPP_memclient.dsp b/examples/IPC_SAP/SOCK_SAP/CPP_memclient.dsp new file mode 100644 index 00000000000..1bb3dd35869 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP_memclient.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="CPP_memclient" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=CPP_memclient - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CPP_memclient.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CPP_memclient.mak" CFG="CPP_memclient - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CPP_memclient - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "CPP_memclient - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "CPP_memclient - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "CPP_memclient - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CPP_memclient___Win32_Debug"
+# PROP BASE Intermediate_Dir "CPP_memclient___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
+
+!ENDIF
+
+# Begin Target
+
+# Name "CPP_memclient - Win32 Release"
+# Name "CPP_memclient - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=".\CPP-memclient.cpp"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=".\CPP-memclient.h"
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/examples/IPC_SAP/SOCK_SAP/CPP_memserver.dsp b/examples/IPC_SAP/SOCK_SAP/CPP_memserver.dsp new file mode 100644 index 00000000000..9fa6802ae4d --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP_memserver.dsp @@ -0,0 +1,69 @@ +# Microsoft Developer Studio Project File - Name="CPP_memserver" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=CPP_memserver - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CPP_memserver.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CPP_memserver.mak" CFG="CPP_memserver - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CPP_memserver - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CPP_memserver___Win32_Debug"
+# PROP BASE Intermediate_Dir "CPP_memserver___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
+# Begin Target
+
+# Name "CPP_memserver - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=".\CPP-memserver.cpp"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw b/examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw index ecfbf538184..36a90951e36 100644 --- a/examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw +++ b/examples/IPC_SAP/SOCK_SAP/SOCK_SAP.dsw @@ -27,6 +27,30 @@ Package=<4> ###############################################################################
+Project: "CPP_memclient"=.\CPP_memclient.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "CPP_memserver"=.\CPP_memserver.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "C_inclient"=.\SOCK_SAP.dsp - Package Owner=<4>
Package=<5>
diff --git a/tests/Malloc_Test.cpp b/tests/Malloc_Test.cpp index d974ef23ebd..c523f28c0d8 100644 --- a/tests/Malloc_Test.cpp +++ b/tests/Malloc_Test.cpp @@ -345,17 +345,12 @@ main (int argc, ASYS_TCHAR *[]) #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) #if defined (ACE_HAS_POSITION_INDEPENDENT_MALLOC) -template class ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block>; template class auto_ptr< ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> >; template class ACE_Auto_Basic_Ptr< ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> >; #else -template class ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex>; -template class ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_Control_Block>; template class auto_ptr< ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> >; template class ACE_Auto_Basic_Ptr< ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> >; #endif /* ACE_HAS_POSITION_INDEPENDENT_MALLOC */ -template class ACE_Write_Guard<ACE_Process_Mutex>; -template class ACE_Read_Guard<ACE_Process_Mutex>; template class ACE_Based_Pointer<Test_Data>; template class ACE_Based_Pointer_Basic<Test_Data>; template class ACE_Based_Pointer_Basic<long>; @@ -363,17 +358,12 @@ template class ACE_Based_Pointer_Basic<Long_Test>; template class ACE_Based_Pointer<Long_Test>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #if defined (ACE_HAS_POSITION_INDEPENDENT_MALLOC) -#pragma instantiate ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> #pragma instantiate auto_ptr< ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> > #pragma instantiate ACE_Auto_Basic_Ptr< ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_PI_Control_Block> >; #else -#pragma instantiate ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> -#pragma instantiate ACE_Malloc_T<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex, ACE_Control_Block> #pragma instantiate auto_ptr< ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> > #pragma instantiate ACE_Auto_Basic_Ptr< ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_Process_Mutex> >; #endif /* ACE_HAS_POSITION_INDEPENDENT_MALLOC */ -#pragma instantiate ACE_Write_Guard<ACE_Process_Mutex> -#pragma instantiate ACE_Read_Guard<ACE_Process_Mutex> #pragma instantiate ACE_Based_Pointer<Test_Data> #pragma instantiate ACE_Based_Pointer_Basic<Test_Data> #pragma instantiate ACE_Based_Pointer_Basic<long> |