MEM_Acceptor.cpp

Go to the documentation of this file.
00001 // MEM_Acceptor.cpp,v 4.30 2006/03/14 21:15:49 sjiang Exp
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, "MEM_Acceptor.cpp,v 4.30 2006/03/14 21:15:49 sjiang Exp")
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_LIB_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 (reinterpret_cast<sockaddr_in *> (addr),
00123                               len);
00124           remote_sap->set_port_number(temp.get_port_number ());
00125         }
00126     }
00127 
00128   if (this->shared_accept_finish (new_stream,
00129                                   in_blocking_mode,
00130                                   reset_new_handle) == -1)
00131     return -1;
00132 
00133   // Allocate 2 * MAXPATHLEN so we can accomodate the unique
00134   // name that gets appended later
00135   ACE_TCHAR buf [2 * MAXPATHLEN + 1];
00136 
00137   ACE_INET_Addr local_addr;
00138   if (new_stream.get_local_addr (local_addr) == -1)
00139     return -1;
00140 
00141   if (this->mmap_prefix_ != 0)
00142     {
00143       ACE_OS::sprintf (buf,
00144                        ACE_LIB_TEXT ("%s_%d_"),
00145                        this->mmap_prefix_,
00146                        local_addr.get_port_number ());
00147     }
00148   else
00149     {
00150       ACE_TCHAR name[25];
00151       // - 24 is so we can append name to the end.
00152       if (ACE::get_temp_dir (buf, MAXPATHLEN - 24) == -1)
00153         {
00154           ACE_ERROR ((LM_ERROR,
00155                       ACE_LIB_TEXT ("Temporary path too long, ")
00156                       ACE_LIB_TEXT ("defaulting to current directory\n")));
00157           buf[0] = 0;
00158         }
00159 
00160       ACE_OS::sprintf (name,
00161                        ACE_LIB_TEXT ("MEM_Acceptor_%d_"),
00162                        local_addr.get_port_number ());
00163       ACE_OS::strcat (buf, name);
00164     }
00165   ACE_TCHAR unique [MAXPATHLEN];
00166   ACE_OS::unique_name (&new_stream, unique, MAXPATHLEN);
00167 
00168   ACE_OS::strcat (buf, unique);
00169 
00170   // Make sure we have a fresh start.
00171   ACE_OS::unlink (buf);
00172 
00173   new_stream.disable (ACE_NONBLOCK);
00174   ACE_HANDLE new_handle = new_stream.get_handle ();
00175 
00176   // Protocol negociation:
00177   //   Tell the client side what level of signaling strategy
00178   //   we support.
00179   ACE_MEM_IO::Signal_Strategy client_signaling =
00180 #if defined (ACE_WIN32) || !defined (_ACE_USE_SV_SEM)
00181     this->preferred_strategy_;
00182 #else
00183     // We don't support MT.
00184     ACE_MEM_IO::Reactive;
00185 #endif /* ACE_WIN32 || !_ACE_USE_SV_SEM */
00186   if (ACE::send (new_handle, &client_signaling,
00187                  sizeof (ACE_INT16)) == -1)
00188     ACE_ERROR_RETURN ((LM_DEBUG,
00189                        ACE_LIB_TEXT ("ACE_MEM_Acceptor::accept error sending strategy\n")),
00190                       -1);
00191 
00192   //   Now we get the signaling strategy the client support.
00193   if (ACE::recv (new_handle, &client_signaling,
00194                  sizeof (ACE_INT16)) == -1)
00195     ACE_ERROR_RETURN ((LM_DEBUG,
00196                        ACE_LIB_TEXT ("ACE_MEM_Acceptor::%p error receiving strategy\n"), ACE_LIB_TEXT ("accept")),
00197                       -1);
00198 
00199   // Ensure minimum buffer size
00200   if (this->malloc_options_.minimum_bytes_ < ACE_MEM_STREAM_MIN_BUFFER)
00201     this->malloc_options_.minimum_bytes_ = ACE_MEM_STREAM_MIN_BUFFER;
00202 
00203   // Client will decide what signaling strategy to use.
00204 
00205   // Now set up the shared memory malloc pool.
00206   if (new_stream.init (buf,
00207                        static_cast<ACE_MEM_IO::Signal_Strategy> (client_signaling),
00208                        &this->malloc_options_) == -1)
00209     return -1;
00210 
00211   // @@ Need to handle timeout here.
00212   ACE_UINT16 buf_len = static_cast<ACE_UINT16> ((ACE_OS::strlen (buf) + 1) *
00213                                                 sizeof (ACE_TCHAR));
00214 
00215   // No need to worry about byte-order because both parties should always
00216   // be on the same machine.
00217   if (ACE::send (new_handle, &buf_len, sizeof (ACE_UINT16)) == -1)
00218     return -1;
00219 
00220   // Now send the pathname of the mmap file.
00221   if (ACE::send (new_handle, buf, buf_len) == -1)
00222     return -1;
00223   return 0;
00224 }
00225 
00226 int
00227 ACE_MEM_Acceptor::shared_accept_finish (ACE_MEM_Stream new_stream,
00228                                         int in_blocking_mode,
00229                                         int reset_new_handle) const
00230 {
00231   ACE_TRACE ("ACE_MEM_Acceptor::shared_accept_finish ()");
00232 
00233   ACE_HANDLE new_handle = new_stream.get_handle ();
00234 
00235   // Check to see if we were originally in blocking mode, and if so,
00236   // set the <new_stream>'s handle and <this> handle to be in blocking
00237   // mode.
00238   if (in_blocking_mode)
00239     {
00240       // Save/restore errno.
00241       ACE_Errno_Guard error (errno);
00242 
00243       // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
00244       // originally.
00245       ACE::clr_flags (this->get_handle (),
00246                                  ACE_NONBLOCK);
00247       ACE::clr_flags (new_handle,
00248                                  ACE_NONBLOCK);
00249     }
00250 
00251 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00252   if (reset_new_handle)
00253     // Reset the event association inherited by the new handle.
00254     ::WSAEventSelect ((SOCKET) new_handle, 0, 0);
00255 #else
00256   ACE_UNUSED_ARG (reset_new_handle);
00257 #endif /* ACE_WIN32 */
00258   if (new_handle == ACE_INVALID_HANDLE)
00259     return -1;
00260 
00261   return 0;
00262 }
00263 
00264 ACE_END_VERSIONED_NAMESPACE_DECL
00265 
00266 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */

Generated on Thu Nov 9 09:41:55 2006 for ACE by doxygen 1.3.6