Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

SOCK_Connector.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // SOCK_Connector.cpp
00003 // $Id: SOCK_Connector.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $
00004 
00005 #include "ace/SOCK_Connector.h"
00006 #include "ace/INET_Addr.h"
00007 #include "ace/Log_Msg.h"
00008 
00009 #if !defined (ACE_HAS_WINCE)
00010 #include "ace/OS_QoS.h"
00011 #endif  // ACE_HAS_WINCE
00012 
00013 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00014 #include "ace/SOCK_Connector.i"
00015 #endif /* ACE_LACKS_INLINE_FUNCTIONS */
00016 
00017 ACE_RCSID(ace, SOCK_Connector, "$Id: SOCK_Connector.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $")
00018 
00019 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Connector)
00020 
00021 void
00022 ACE_SOCK_Connector::dump (void) const
00023 {
00024   ACE_TRACE ("ACE_SOCK_Connector::dump");
00025 }
00026 
00027 int
00028 ACE_SOCK_Connector::shared_open (ACE_SOCK_Stream &new_stream,
00029                                  int protocol_family,
00030                                  int protocol,
00031                                  int reuse_addr)
00032 {
00033   ACE_TRACE ("ACE_SOCK_Connector::shared_open");
00034 
00035   // Only open a new socket if we don't already have a valid handle.
00036   if (new_stream.get_handle () == ACE_INVALID_HANDLE
00037       && new_stream.open (SOCK_STREAM,
00038                           protocol_family,
00039                           protocol,
00040                           reuse_addr) == -1)
00041     return -1;
00042   else
00043     return 0;
00044 }
00045 
00046 int
00047 ACE_SOCK_Connector::shared_open (ACE_SOCK_Stream &new_stream,
00048                                  int protocol_family,
00049                                  int protocol,
00050                                  ACE_Protocol_Info *protocolinfo,
00051                                  ACE_SOCK_GROUP g,
00052                                  u_long flags,
00053                                  int reuse_addr)
00054 {
00055   ACE_TRACE ("ACE_SOCK_Connector::shared_open");
00056 
00057   // Only open a new socket if we don't already have a valid handle.
00058   if (new_stream.get_handle () == ACE_INVALID_HANDLE
00059       && new_stream.open (SOCK_STREAM,
00060                           protocol_family,
00061                           protocol,
00062                           protocolinfo,
00063                           g,
00064                           flags,
00065                           reuse_addr) == -1)
00066     return -1;
00067   else
00068     return 0;
00069 }
00070 
00071 int
00072 ACE_SOCK_Connector::shared_connect_start (ACE_SOCK_Stream &new_stream,
00073                                           const ACE_Time_Value *timeout,
00074                                           const ACE_Addr &local_sap)
00075 {
00076   ACE_TRACE ("ACE_SOCK_Connector::shared_connect_start");
00077 
00078   if (local_sap != ACE_Addr::sap_any)
00079     {
00080       sockaddr *laddr = ACE_reinterpret_cast (sockaddr *,
00081                                               local_sap.get_addr ());
00082       int size = local_sap.get_size ();
00083 
00084       if (ACE_OS::bind (new_stream.get_handle (),
00085                         laddr,
00086                         size) == -1)
00087         {
00088           // Save/restore errno.
00089           ACE_Errno_Guard error (errno);
00090           new_stream.close ();
00091           return -1;
00092         }
00093     }
00094 
00095   // Enable non-blocking, if required.
00096   if (timeout != 0
00097       && new_stream.enable (ACE_NONBLOCK) == -1)
00098     return -1;
00099   else
00100     return 0;
00101 }
00102 
00103 int
00104 ACE_SOCK_Connector::shared_connect_finish (ACE_SOCK_Stream &new_stream,
00105                                            const ACE_Time_Value *timeout,
00106                                            int result)
00107 {
00108   ACE_TRACE ("ACE_SOCK_Connector::shared_connect_finish");
00109   // Save/restore errno.
00110   ACE_Errno_Guard error (errno);
00111 
00112   if (result == -1 && timeout != 0)
00113     {
00114       // Check whether the connection is in progress.
00115       if (error == EINPROGRESS || error == EWOULDBLOCK)
00116         {
00117           // This expression checks if we were polling.
00118           if (timeout->sec () == 0
00119               && timeout->usec () == 0)
00120             error = EWOULDBLOCK;
00121           // Wait synchronously using timeout.
00122           else if (this->complete (new_stream,
00123                                    0,
00124                                    timeout) == -1)
00125             error = errno;
00126           else
00127             return 0;
00128         }
00129     }
00130 
00131   // EISCONN is treated specially since this routine may be used to
00132   // check if we are already connected.
00133   if (result != -1 || error == EISCONN)
00134     // Start out with non-blocking disabled on the <new_stream>.
00135     new_stream.disable (ACE_NONBLOCK);
00136   else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
00137     new_stream.close ();
00138 
00139   return result;
00140 }
00141 
00142 // Actively connect and produce a new ACE_SOCK_Stream if things go well...
00143 
00144 int
00145 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00146                              const ACE_Addr &remote_sap,
00147                              const ACE_Time_Value *timeout,
00148                              const ACE_Addr &local_sap,
00149                              int reuse_addr,
00150                              int /* flags */,
00151                              int /* perms */)
00152 {
00153   ACE_TRACE ("ACE_SOCK_Connector::connect");
00154 
00155   if (this->shared_open (new_stream,
00156                          remote_sap.get_type (),
00157                          0,
00158                          reuse_addr) == -1)
00159     return -1;
00160   else if (this->shared_connect_start (new_stream,
00161                                        timeout,
00162                                        local_sap) == -1)
00163     return -1;
00164 
00165   int result = ACE_OS::connect (new_stream.get_handle (),
00166                                 ACE_reinterpret_cast (sockaddr *,
00167                                                       remote_sap.get_addr ()),
00168                                 remote_sap.get_size ());
00169 
00170   return this->shared_connect_finish (new_stream,
00171                                       timeout,
00172                                       result);
00173 }
00174 
00175 #if !defined (ACE_HAS_WINCE)
00176 int
00177 ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
00178                              const ACE_Addr &remote_sap,
00179                              ACE_QoS_Params qos_params,
00180                              const ACE_Time_Value *timeout,
00181                              const ACE_Addr &local_sap,
00182                              ACE_Protocol_Info * protocolinfo,
00183                              ACE_SOCK_GROUP g,
00184                              u_long flags,
00185                              int reuse_addr,
00186                              int /* perms */)
00187 {
00188   ACE_TRACE ("ACE_SOCK_Connector::connect");
00189 
00190   if (this->shared_open (new_stream,
00191                          remote_sap.get_type (),
00192                          0,
00193                          protocolinfo,
00194                          g,
00195                          flags,
00196                          reuse_addr) == -1)
00197     return -1;
00198   else if (this->shared_connect_start (new_stream,
00199                                        timeout,
00200                                        local_sap) == -1)
00201     return -1;
00202 
00203   int result = ACE_OS::connect (new_stream.get_handle (),
00204                                 ACE_reinterpret_cast (sockaddr *,
00205                                                       remote_sap.get_addr ()),
00206                                 remote_sap.get_size (),
00207                                 qos_params);
00208 
00209   return this->shared_connect_finish (new_stream,
00210                                       timeout,
00211                                       result);
00212 }
00213 #endif  // ACE_HAS_WINCE
00214 
00215 // Try to complete a non-blocking connection.
00216 
00217 int
00218 ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
00219                               ACE_Addr *remote_sap,
00220                               const ACE_Time_Value *tv)
00221 {
00222   ACE_TRACE ("ACE_SOCK_Connector::complete");
00223   ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
00224                                              tv);
00225   // We failed to get connected.
00226   if (h == ACE_INVALID_HANDLE)
00227     {
00228 #if defined (ACE_WIN32)
00229       // Win32 has a timing problem - if you check to see if the
00230       // connection has completed too fast, it will fail - so wait
00231       // <ACE_NON_BLOCKING_BUG_DELAY> microseconds to let it catch up
00232       // then retry to see if it's a real failure.
00233       ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
00234       ACE_OS::sleep (time);
00235       h = ACE::handle_timed_complete (new_stream.get_handle (),
00236                                       tv);
00237       if (h == ACE_INVALID_HANDLE)
00238         {
00239 #endif /* ACE_WIN32 */
00240       // Save/restore errno.
00241       ACE_Errno_Guard error (errno);
00242       new_stream.close ();
00243       return -1;
00244 #if defined (ACE_WIN32)
00245         }
00246 #endif /* ACE_WIN32 */
00247     }
00248 
00249   if (remote_sap != 0)
00250     {
00251       int len = remote_sap->get_size ();
00252       sockaddr *addr = ACE_reinterpret_cast (sockaddr *,
00253                                              remote_sap->get_addr ());
00254       if (ACE_OS::getpeername (h,
00255                                addr,
00256                                &len) == -1)
00257         {
00258           // Save/restore errno.
00259           ACE_Errno_Guard error (errno);
00260           new_stream.close ();
00261           return -1;
00262         }
00263     }
00264 
00265   // Start out with non-blocking disabled on the <new_stream>.
00266   new_stream.disable (ACE_NONBLOCK);
00267   return 0;
00268 }
00269 
00270 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00271                                         const ACE_Addr &remote_sap,
00272                                         const ACE_Time_Value *timeout,
00273                                         const ACE_Addr &local_sap,
00274                                         int reuse_addr,
00275                                         int flags,
00276                                         int perms)
00277 {
00278   ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00279 
00280   if (this->connect (new_stream,
00281                      remote_sap,
00282                      timeout,
00283                      local_sap,
00284                      reuse_addr,
00285                      flags,
00286                      perms) == -1
00287       && timeout != 0
00288       && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00289     ACE_ERROR ((LM_ERROR,
00290                 ACE_LIB_TEXT ("%p\n"),
00291                 ACE_LIB_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00292 }
00293 
00294 #if !defined (ACE_HAS_WINCE)
00295 ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
00296                                         const ACE_Addr &remote_sap,
00297                                         ACE_QoS_Params qos_params,
00298                                         const ACE_Time_Value *timeout,
00299                                         const ACE_Addr &local_sap,
00300                                         ACE_Protocol_Info *protocolinfo,
00301                                         ACE_SOCK_GROUP g,
00302                                         u_long flags,
00303                                         int reuse_addr,
00304                                         int perms)
00305 {
00306   ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
00307 
00308   if (this->connect (new_stream,
00309                      remote_sap,
00310                      qos_params,
00311                      timeout,
00312                      local_sap,
00313                      protocolinfo,
00314                      g,
00315                      flags,
00316                      reuse_addr,
00317                      perms) == -1
00318       && timeout != 0
00319       && !(errno == EWOULDBLOCK || errno == ETIME || errno == ETIMEDOUT))
00320     ACE_ERROR ((LM_ERROR,
00321                 ACE_LIB_TEXT ("%p\n"),
00322                 ACE_LIB_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
00323 }
00324 #endif  // ACE_HAS_WINCE

Generated on Mon Jun 16 11:21:19 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002