SPIPE_Connector.cpp

Go to the documentation of this file.
00001 // $Id: SPIPE_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/SPIPE_Connector.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_sys_time.h"
00006 #include "ace/OS_NS_fcntl.h"
00007 #include "ace/OS_NS_unistd.h"
00008 
00009 #if !defined (__ACE_INLINE__)
00010 #include "ace/SPIPE_Connector.inl"
00011 #endif /* __ACE_INLINE__ */
00012 
00013 ACE_RCSID(ace, SPIPE_Connector, "$Id: SPIPE_Connector.cpp 80826 2008-03-04 14:51:23Z wotte $")
00014 
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE_Connector)
00018 
00019 // Creates a Local ACE_SPIPE.
00020 
00021 ACE_SPIPE_Connector::ACE_SPIPE_Connector (ACE_SPIPE_Stream &new_io,
00022                                           const ACE_SPIPE_Addr &remote_sap,
00023                                           ACE_Time_Value *timeout,
00024                                           const ACE_Addr & local_sap,
00025                                           int reuse_addr,
00026                                           int flags,
00027                                           int perms,
00028             LPSECURITY_ATTRIBUTES sa,
00029             int pipe_mode)
00030 {
00031   ACE_TRACE ("ACE_SPIPE_Connector::ACE_SPIPE_Connector");
00032   if (this->connect (new_io, remote_sap, timeout, local_sap,
00033                      reuse_addr, flags, perms, sa, pipe_mode) == -1
00034       && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME))
00035     ACE_ERROR ((LM_ERROR, ACE_TEXT ("address %s, %p\n"),
00036                remote_sap.get_path_name (), ACE_TEXT ("ACE_SPIPE_Connector")));
00037 }
00038 
00039 void
00040 ACE_SPIPE_Connector::dump (void) const
00041 {
00042 #if defined (ACE_HAS_DUMP)
00043   ACE_TRACE ("ACE_SPIPE_Connector::dump");
00044 #endif /* ACE_HAS_DUMP */
00045 }
00046 
00047 ACE_SPIPE_Connector::ACE_SPIPE_Connector (void)
00048 {
00049   ACE_TRACE ("ACE_SPIPE_Connector::ACE_SPIPE_Connector");
00050 }
00051 
00052 int
00053 ACE_SPIPE_Connector::connect (ACE_SPIPE_Stream &new_io,
00054                               const ACE_SPIPE_Addr &remote_sap,
00055                               ACE_Time_Value *timeout,
00056                               const ACE_Addr & /* local_sap */,
00057                               int /* reuse_addr */,
00058                               int flags,
00059                               int perms,
00060                               LPSECURITY_ATTRIBUTES sa,
00061                               int pipe_mode)
00062 {
00063   ACE_TRACE ("ACE_SPIPE_Connector::connect");
00064   // Make darn sure that the O_CREAT flag is not set!
00065   ACE_CLR_BITS (flags, O_CREAT);
00066 
00067   ACE_HANDLE handle;
00068 
00069   ACE_UNUSED_ARG (pipe_mode);
00070 #if defined (ACE_WIN32) && \
00071    !defined (ACE_HAS_PHARLAP) && !defined (ACE_HAS_WINCE)
00072   // We need to allow for more than one attempt to connect,
00073   // calculate the absolute time at which we give up.
00074   ACE_Time_Value absolute_time;
00075   if (timeout != 0)
00076     absolute_time = ACE_OS::gettimeofday () + *timeout;
00077 
00078   // Loop until success or failure.
00079   for (;;)
00080     {
00081       handle = ACE_OS::open (remote_sap.get_path_name(), flags, perms, sa);
00082       if (handle != ACE_INVALID_HANDLE)
00083         // Success!
00084         break;
00085 
00086       // Check if we have a busy pipe condition.
00087       if (::GetLastError() != ERROR_PIPE_BUSY)
00088         // Nope, this is a failure condition.
00089         break;
00090 
00091       // This will hold the time out value used in the ::WaitNamedPipe
00092       // call.
00093       DWORD time_out_value;
00094 
00095       // Check if we are to block until we connect.
00096       if (timeout == 0)
00097         // Wait for as long as it takes.
00098         time_out_value = NMPWAIT_WAIT_FOREVER;
00099       else
00100         {
00101           // Calculate the amount of time left to wait.
00102           ACE_Time_Value relative_time (absolute_time - ACE_OS::gettimeofday ());
00103           // Check if we have run out of time.
00104           if (relative_time <= ACE_Time_Value::zero)
00105             {
00106               // Mimick the errno value returned by
00107               // ACE::handle_timed_open.
00108               if (*timeout == ACE_Time_Value::zero)
00109                 errno = EWOULDBLOCK;
00110               else
00111                 errno = ETIMEDOUT;
00112               // Exit the connect loop with the failure.
00113               break;
00114             }
00115           // Get the amount of time remaining for ::WaitNamedPipe.
00116           time_out_value = relative_time.msec ();
00117 
00118         }
00119 
00120       // Wait for the named pipe to become available.
00121       ACE_TEXT_WaitNamedPipe (remote_sap.get_path_name (),
00122                               time_out_value);
00123 
00124       // Regardless of the return value, we'll do one more attempt to
00125       // connect to see if it is now available and to return
00126       // consistent error values.
00127     }
00128 
00129   // Set named pipe mode if we have a valid handle.
00130   if (handle != ACE_INVALID_HANDLE)
00131     {
00132       // Check if we are changing the pipe mode from the default.
00133       if (pipe_mode != (PIPE_READMODE_BYTE | PIPE_WAIT))
00134         {
00135           DWORD dword_pipe_mode = pipe_mode;
00136           if (!::SetNamedPipeHandleState (handle,
00137                                           &dword_pipe_mode,
00138                                           0,
00139                                           0))
00140             {
00141               // We were not able to put the pipe into the requested
00142               // mode.
00143               ACE_OS::close (handle);
00144               handle = ACE_INVALID_HANDLE;
00145             }
00146         }
00147     }
00148 #else /* ACE_WIN32 && !ACE_HAS_PHARLAP */
00149   handle = ACE::handle_timed_open (timeout,
00150                                               remote_sap.get_path_name (),
00151                                               flags, perms, sa);
00152 #endif /* !ACE_WIN32 || ACE_HAS_PHARLAP || ACE_HAS_WINCE */
00153 
00154   new_io.set_handle (handle);
00155   new_io.remote_addr_ = remote_sap; // class copy.
00156 
00157   return handle == ACE_INVALID_HANDLE ? -1 : 0;
00158 }
00159 
00160 ACE_END_VERSIONED_NAMESPACE_DECL

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