MEM_Acceptor.cpp

Go to the documentation of this file.
00001 // $Id: MEM_Acceptor.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/MEM_Acceptor.h"
00004 
00005 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00006 
00007 #include "ace/OS_NS_stdio.h"
00008 #include "ace/OS_NS_string.h"
00009 #include "ace/OS_NS_sys_socket.h"
00010 #include "ace/OS_NS_unistd.h"
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/MEM_Acceptor.inl"
00014 #endif /* __ACE_INLINE__ */
00015 
00016 ACE_RCSID(ace, MEM_Acceptor, "$Id: MEM_Acceptor.cpp 80826 2008-03-04 14:51:23Z wotte $")
00017 
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 ACE_ALLOC_HOOK_DEFINE(ACE_MEM_Acceptor)
00021 
00022 void
00023 ACE_MEM_Acceptor::dump (void) const
00024 {
00025 #if defined (ACE_HAS_DUMP)
00026   ACE_TRACE ("ACE_MEM_Acceptor::dump");
00027 #endif /* ACE_HAS_DUMP */
00028 }
00029 
00030 // Do nothing routine for constructor.
00031 
00032 ACE_MEM_Acceptor::ACE_MEM_Acceptor (void)
00033   : mmap_prefix_ (0),
00034     malloc_options_ (ACE_DEFAULT_BASE_ADDR, 0),
00035     preferred_strategy_ (ACE_MEM_IO::Reactive)
00036 {
00037   ACE_TRACE ("ACE_MEM_Acceptor::ACE_MEM_Acceptor");
00038 }
00039 
00040 ACE_MEM_Acceptor::~ACE_MEM_Acceptor (void)
00041 {
00042   ACE_TRACE ("ACE_MEM_Acceptor::~ACE_MEM_Acceptor");
00043   delete[] this->mmap_prefix_;
00044 }
00045 
00046 // General purpose routine for performing server ACE_SOCK creation.
00047 
00048 ACE_MEM_Acceptor::ACE_MEM_Acceptor (const ACE_MEM_Addr &remote_sap,
00049                                     int reuse_addr,
00050                                     int backlog,
00051                                     int protocol)
00052   : mmap_prefix_ (0),
00053     malloc_options_ (ACE_DEFAULT_BASE_ADDR, 0),
00054     preferred_strategy_ (ACE_MEM_IO::Reactive)
00055 {
00056   ACE_TRACE ("ACE_MEM_Acceptor::ACE_MEM_Acceptor");
00057   if (this->open (remote_sap,
00058                   reuse_addr,
00059                   backlog,
00060                   protocol) == -1)
00061     ACE_ERROR ((LM_ERROR,
00062                 ACE_TEXT ("ACE_MEM_Acceptor::ACE_MEM_Acceptor")));
00063 }
00064 
00065 int
00066 ACE_MEM_Acceptor::open (const ACE_MEM_Addr &remote_sap,
00067                         int reuse_addr,
00068                         int back_log,
00069                         int protocol)
00070 {
00071   ACE_TRACE ("ACE_MEM_Acceptor::open");
00072   return this->ACE_SOCK_Acceptor::open (remote_sap.get_local_addr (),
00073                                         reuse_addr,
00074                                         PF_INET,
00075                                         back_log,
00076                                         protocol);
00077 }
00078 
00079 // General purpose routine for accepting new connections.
00080 
00081 int
00082 ACE_MEM_Acceptor::accept (ACE_MEM_Stream &new_stream,
00083                           ACE_MEM_Addr *remote_sap,
00084                           ACE_Time_Value *timeout,
00085                           int restart,
00086                           int reset_new_handle)
00087 {
00088   ACE_TRACE ("ACE_MEM_Acceptor::accept");
00089 
00090   int in_blocking_mode = 1;
00091   if (this->shared_accept_start (timeout,
00092                                  restart,
00093                                  in_blocking_mode) == -1)
00094     return -1;
00095   else
00096     {
00097       sockaddr *addr = 0;
00098       struct sockaddr_in inet_addr;
00099       int *len_ptr = 0;
00100       int len = 0;
00101 
00102       if (remote_sap != 0)
00103         {
00104           addr = reinterpret_cast<sockaddr *> (&inet_addr);
00105           len = sizeof (inet_addr);
00106           len_ptr = &len;
00107         }
00108 
00109       do
00110         // On Win32 the third parameter to <accept> must be a NULL
00111         // pointer if to ignore the client's address.
00112         new_stream.set_handle (ACE_OS::accept (this->get_handle (),
00113                                                addr,
00114                                                len_ptr));
00115       while (new_stream.get_handle () == ACE_INVALID_HANDLE
00116              && restart != 0
00117              && errno == EINTR
00118              && timeout == 0);
00119 
00120       if (remote_sap != 0)
00121         {
00122           ACE_INET_Addr temp (&inet_addr, len);
00123           remote_sap->set_port_number (temp.get_port_number ());
00124         }
00125     }
00126 
00127   if (this->shared_accept_finish (new_stream,
00128                                   in_blocking_mode,
00129                                   reset_new_handle) == -1)
00130     return -1;
00131 
00132   // Allocate 2 * MAXPATHLEN so we can accomodate the unique
00133   // name that gets appended later
00134   ACE_TCHAR buf [2 * MAXPATHLEN + 1];
00135 
00136   ACE_INET_Addr local_addr;
00137   if (new_stream.get_local_addr (local_addr) == -1)
00138     return -1;
00139 
00140   if (this->mmap_prefix_ != 0)
00141     {
00142       ACE_OS::sprintf (buf,
00143                        ACE_TEXT ("%s_%d_"),
00144                        this->mmap_prefix_,
00145                        local_addr.get_port_number ());
00146     }
00147   else
00148     {
00149       ACE_TCHAR name[25];
00150       // - 24 is so we can append name to the end.
00151       if (ACE::get_temp_dir (buf, MAXPATHLEN - 24) == -1)
00152         {
00153           ACE_ERROR ((LM_ERROR,
00154                       ACE_TEXT ("Temporary path too long, ")
00155                       ACE_TEXT ("defaulting to current directory\n")));
00156           buf[0] = 0;
00157         }
00158 
00159       ACE_OS::sprintf (name,
00160                        ACE_TEXT ("MEM_Acceptor_%d_"),
00161                        local_addr.get_port_number ());
00162       ACE_OS::strcat (buf, name);
00163     }
00164   ACE_TCHAR unique [MAXPATHLEN];
00165   ACE_OS::unique_name (&new_stream, unique, MAXPATHLEN);
00166 
00167   ACE_OS::strcat (buf, unique);
00168 
00169   // Make sure we have a fresh start.
00170   ACE_OS::unlink (buf);
00171 
00172   new_stream.disable (ACE_NONBLOCK);
00173   ACE_HANDLE new_handle = new_stream.get_handle ();
00174 
00175   // Protocol negociation:
00176   //   Tell the client side what level of signaling strategy
00177   //   we support.
00178   ACE_MEM_IO::Signal_Strategy client_signaling =
00179 #if defined (ACE_WIN32) || !defined (_ACE_USE_SV_SEM)
00180     this->preferred_strategy_;
00181 #else
00182     // We don't support MT.
00183     ACE_MEM_IO::Reactive;
00184 #endif /* ACE_WIN32 || !_ACE_USE_SV_SEM */
00185   if (ACE::send (new_handle, &client_signaling,
00186                  sizeof (ACE_INT16)) == -1)
00187     ACE_ERROR_RETURN ((LM_DEBUG,
00188                        ACE_TEXT ("ACE_MEM_Acceptor::accept error sending strategy\n")),
00189                       -1);
00190 
00191   //   Now we get the signaling strategy the client support.
00192   if (ACE::recv (new_handle, &client_signaling,
00193                  sizeof (ACE_INT16)) == -1)
00194     ACE_ERROR_RETURN ((LM_DEBUG,
00195                        ACE_TEXT ("ACE_MEM_Acceptor::%p error receiving strategy\n"), ACE_TEXT ("accept")),
00196                       -1);
00197 
00198   // Ensure minimum buffer size
00199   if (this->malloc_options_.minimum_bytes_ < ACE_MEM_STREAM_MIN_BUFFER)
00200     this->malloc_options_.minimum_bytes_ = ACE_MEM_STREAM_MIN_BUFFER;
00201 
00202   // Client will decide what signaling strategy to use.
00203 
00204   // Now set up the shared memory malloc pool.
00205   if (new_stream.init (buf,
00206                        static_cast<ACE_MEM_IO::Signal_Strategy> (client_signaling),
00207                        &this->malloc_options_) == -1)
00208     return -1;
00209 
00210   // @@ Need to handle timeout here.
00211   ACE_UINT16 buf_len = static_cast<ACE_UINT16> ((ACE_OS::strlen (buf) + 1) *
00212                                                 sizeof (ACE_TCHAR));
00213 
00214   // No need to worry about byte-order because both parties should always
00215   // be on the same machine.
00216   if (ACE::send (new_handle, &buf_len, sizeof (ACE_UINT16)) == -1)
00217     return -1;
00218 
00219   // Now send the pathname of the mmap file.
00220   if (ACE::send (new_handle, buf, buf_len) == -1)
00221     return -1;
00222   return 0;
00223 }
00224 
00225 int
00226 ACE_MEM_Acceptor::shared_accept_finish (ACE_MEM_Stream new_stream,
00227                                         int in_blocking_mode,
00228                                         int reset_new_handle) const
00229 {
00230   ACE_TRACE ("ACE_MEM_Acceptor::shared_accept_finish ()");
00231 
00232   ACE_HANDLE new_handle = new_stream.get_handle ();
00233 
00234   // Check to see if we were originally in blocking mode, and if so,
00235   // set the <new_stream>'s handle and <this> handle to be in blocking
00236   // mode.
00237   if (in_blocking_mode)
00238     {
00239       // Save/restore errno.
00240       ACE_Errno_Guard error (errno);
00241 
00242       // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
00243       // originally.
00244       ACE::clr_flags (this->get_handle (),
00245                                  ACE_NONBLOCK);
00246       ACE::clr_flags (new_handle,
00247                                  ACE_NONBLOCK);
00248     }
00249 
00250 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00251   if (reset_new_handle)
00252     // Reset the event association inherited by the new handle.
00253     ::WSAEventSelect ((SOCKET) new_handle, 0, 0);
00254 #else
00255   ACE_UNUSED_ARG (reset_new_handle);
00256 #endif /* ACE_WIN32 */
00257   if (new_handle == ACE_INVALID_HANDLE)
00258     return -1;
00259 
00260   return 0;
00261 }
00262 
00263 ACE_END_VERSIONED_NAMESPACE_DECL
00264 
00265 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */

Generated on Tue Feb 2 17:18:40 2010 for ACE by  doxygen 1.4.7