summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1999-06-14 02:17:02 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1999-06-14 02:17:02 +0000
commitb4a501994dd71bacf8c727a8a11e8c57a023e1fc (patch)
treecd090e6574f0f1d2f35adc0dd6d719c5c0d9b90e /ace
parenta43d81d54a95a6fd5359d4733b7e3c1e4f02bd6b (diff)
downloadATCD-b4a501994dd71bacf8c727a8a11e8c57a023e1fc.tar.gz
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r--ace/OS.h267
-rw-r--r--ace/OS.i506
-rw-r--r--ace/SOCK_Acceptor.cpp260
-rw-r--r--ace/SOCK_Acceptor.h34
-rw-r--r--ace/SOCK_Connector.cpp255
-rw-r--r--ace/SOCK_Connector.h68
-rw-r--r--ace/SOCK_Connector.i18
7 files changed, 1167 insertions, 241 deletions
diff --git a/ace/OS.h b/ace/OS.h
index af5cea580fa..b9403efb2cb 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -3126,6 +3126,8 @@ struct iovec
{
size_t iov_len; // byte count to read/write
char *iov_base; // data to be read/written
+
+ operator WSABUF &(void) { return *((WSABUF *) this); }
};
struct msghdr
@@ -4692,7 +4694,7 @@ extern "C" {
typedef int (*ACE_COMPARE_FUNC)(const void *, const void *);
}
-class ACE_Errno_Guard
+class ACE_Export ACE_Errno_Guard
{
// = TITLE
// Provides a wrapper to improve performance when thread-specific
@@ -4716,39 +4718,224 @@ class ACE_Errno_Guard
// avoids an unnecessary second access to thread-specific storage
// by caching a pointer to the value of errno in TSS.
public:
- ACE_Errno_Guard (int &e, int error):
-#if defined (ACE_MT_SAFE)
- ep_ (&e),
-#endif /* ACE_MT_SAFE */
- error_ (error) { }
+ // = Initialization and termination methods.
+ ACE_Errno_Guard (int &errno_ref,
+ int error);
+ // Stash the value of <error> into <error_> and initialize the
+ // <errno_ptr_> to the address of <errno_ref>.
- ACE_Errno_Guard (int &e):
-#if defined (ACE_MT_SAFE)
- ep_ (&e),
-#endif /* ACE_MT_SAFE */
- error_ (e) { }
+ ACE_Errno_Guard (int &errno_ref);
+ // Stash the value of <errno> into <error_> and initialize the
+ // <errno_ptr_> to the address of <errno_ref>.
+
+ ~ACE_Errno_Guard (void);
+ // Reset the value of <errno> to <error>.
- ~ACE_Errno_Guard (void)
- {
-#if defined (ACE_MT_SAFE)
- *ep_ = error_;
-#else
- errno = error_;
-#endif /* ACE_MT_SAFE */
- }
+ int operator= (int error);
+ // Assign <error> to <error_>.
- int operator= (int error)
- {
- return this->error_ = error;
- }
+ int operator== (int error);
+ // Compare <error> with <error_> for equality.
+
+ int operator!= (int error);
+ // Compare <error> with <error_> for inequality.
private:
#if defined (ACE_MT_SAFE)
- int *ep_;
+ int *errno_ptr_;
#endif /* ACE_MT_SAFE */
int error_;
};
+// @@ We might want a smarter way to do this...
+#if !defined (SERVICETYPE)
+typedef u_long ACE_SERVICE_TYPE;
+#else
+typedef SERVICETYPE ACE_SERVICE_TYPE;
+#endif /* SERVICETYPE */
+
+class ACE_Export ACE_Flow_Spec
+#if defined (ACE_HAS_WINSOCK2)
+ : public FLOWSPEC
+#endif /* ACE_HAS_WINSOCK2 */
+{
+ // = TITLE
+ // Wrapper class that defines the flow spec QoS information, which
+ // is used by RSVP.
+public:
+ // = Get/set the token rate in bytes/sec.
+ u_long token_rate (void);
+ void token_rate (u_long tr);
+
+ // = Get/set the token bucket size in bytes.
+ u_long token_bucket_size (void);
+ void token_bucket_size (u_long tbs);
+
+ // = Get/set the PeakBandwidth in bytes/sec.
+ u_long peak_bandwidth (void);
+ void peak_bandwidth (u_long pb);
+
+ // = Get/set the latency in microseconds.
+ u_long latency (void);
+ void latency (u_long l);
+
+ // = Get/set the delay variation in microseconds.
+ u_long delay_variation (void);
+ void delay_variation (u_long dv);
+
+ // = Get/set the service type.
+ ACE_SERVICE_TYPE service_type (void);
+ void service_type (ACE_SERVICE_TYPE st);
+
+ // = Get/set the maximum SDU size in bytes.
+ u_long max_sdu_size (void);
+ void max_sdu_size (u_long mss);
+
+ // = Get/set the minimum policed size in bytes.
+ u_long minimum_policed_size (void);
+ void minimum_policed_size (u_long mps);
+};
+
+class ACE_Export ACE_QoS
+#if defined (ACE_HAS_WINSOCK2)
+ : public QOS
+#endif /* ACE_HAS_WINSOCK2 */
+{
+ // = TITLE
+ // Wrapper class that holds the sender and receiver flow spec
+ // information, which is used by RSVP.
+public:
+ // = Get/set the flow spec for data sending.
+ ACE_Flow_Spec sending_flowspec (void);
+ void sending_flowspec (const ACE_Flow_Spec &fs);
+
+ // = Get/set the flow spec for data receiving.
+ ACE_Flow_Spec receiving_flowspec (void);
+ void receiving_flowspec (const ACE_Flow_Spec &fs);
+
+ // = Get/set the provider specific information.
+ iovec provider_specific (void);
+ void provider_specific (const iovec &ps);
+};
+
+class ACE_Export ACE_Connect_QoS_Params
+{
+ // = TITLE
+ // Wrapper class that simplifies the information passed to the QoS
+ // enabled <ACE_OS::connect> and <ACE_OS::join_leaf> methods.
+public:
+ ACE_Connect_QoS_Params (iovec *caller_data = 0,
+ iovec *callee_data = 0,
+ ACE_QoS *socket_qos = 0,
+ ACE_QoS *group_socket_qos = 0,
+ u_long flags = 0);
+ // Initialize the data members. The <caller_data> is a pointer to
+ // the user data that is to be transferred to the peer during
+ // connection establishment. The <callee_data> is a pointer to the
+ // user data that is to be transferred back from the peer during
+ // connection establishment. The_<socket_qos> is a pointer to the
+ // flow speicfications for the socket, one for each direction. The
+ // <group_socket_qos> is a pointer to the flow speicfications for
+ // the socket group, if applicable. The_<flags> indicate if we're a
+ // sender, receiver, or both.
+
+ // = Get/set caller data.
+ iovec *caller_data (void);
+ void caller_data (iovec *);
+
+ // = Get/set callee data.
+ iovec *callee_data (void);
+ void callee_data (iovec *);
+
+ // = Get/set socket qos.
+ ACE_QoS *socket_qos (void);
+ void socket_qos (ACE_QoS *);
+
+ // = Get/set group socket qos.
+ ACE_QoS *group_socket_qos (void);
+ void group_socket_qos (ACE_QoS *);
+
+ // = Get/set flags.
+ u_long flags (void);
+ void flags (u_long);
+
+private:
+ iovec *caller_data_;
+ // A pointer to the user data that is to be transferred to the peer
+ // during connection establishment.
+
+ iovec *callee_data_;
+ // A pointer to the user data that is to be transferred back from
+ // the peer during connection establishment.
+
+ ACE_QoS *socket_qos_;
+ // A pointer to the flow speicfications for the socket, one for each
+ // direction.
+
+ ACE_QoS *group_socket_qos_;
+ // A pointer to the flow speicfications for the socket group, if
+ // applicable.
+
+ u_long flags_;
+ // Flags that indicate if we're a sender, receiver, or both.
+};
+
+// Callback function that's used by the QoS-enabled <ACE_OS::accept>
+// method.
+typedef int (*ACE_QOS_CONDITION_FUNC) (iovec *caller_id,
+ iovec *caller_data,
+ ACE_QoS *socket_qos,
+ ACE_QoS *group_socket_qos,
+ iovec *callee_id,
+ iovec *callee_data,
+ u_long *g, /* unused */
+ u_long callbackdata);
+
+// Callback function that's used by the QoS-enabled <ACE_OS::ioctl>
+// method.
+typedef void (*ACE_OVERLAPPED_COMPLETION_FUNC) (u_long error,
+ u_long bytes_transferred,
+ ACE_OVERLAPPED *overlapped,
+ u_long flags);
+class ACE_Export ACE_Accept_QoS_Params
+{
+ // = TITLE
+ // Wrapper class that simplifies the information passed to the QoS
+ // enabled <ACE_OS::accept> method.
+public:
+ ACE_Accept_QoS_Params (ACE_QOS_CONDITION_FUNC qos_condition_callback = 0,
+ u_long callback_data = 0);
+ // Initialize the data members. The <qos_condition_callback> is the
+ // address of an optional, application-supplied condition function
+ // that will make an accept/reject decision based on the caller
+ // information pass in as parameters, and optionally create or join
+ // a socket group by assinging an appropriate value to the result
+ // parameter <g> of this function. The <callback_data> data is
+ // passed back to the application as a condition function parameter,
+ // i.e., it is an Asynchronous Completion Token (ACT).
+
+ // = Get/set QoS condition callback.
+ ACE_QOS_CONDITION_FUNC qos_condition_callback (void);
+ void qos_condition_callback (ACE_QOS_CONDITION_FUNC qcc);
+
+ // = Get/Set callback data.
+ u_long callback_data (void);
+ void callback_data (u_long cd);
+
+private:
+ ACE_QOS_CONDITION_FUNC qos_condition_callback_;
+ // This is the address of an optional, application-supplied
+ // condition function that will make an accept/reject decision based
+ // on the caller information pass in as parameters, and optionally
+ // create or join a socket group by assinging an appropriate value
+ // to the result parameter <g> of this function.
+
+ u_long callback_data_;
+ // This data is passed back to the application as a condition
+ // function parameter, i.e., it is an Asynchronous Completion Token
+ // (ACT).
+};
+
class ACE_Export ACE_OS
{
// = TITLE
@@ -5260,6 +5447,16 @@ public:
static int ioctl (ACE_HANDLE handle,
int cmd,
void * = 0);
+ static int ioctl (ACE_HANDLE socket,
+ u_long io_control_code,
+ void *in_buffer_p,
+ u_long in_buffer,
+ void *out_buffer_p,
+ u_long out_buffer,
+ u_long *bytes_returned,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func);
+ // QoS-enabled <ioctl>.
static int isastream (ACE_HANDLE handle);
static int isatty (ACE_HANDLE handle);
static off_t lseek (ACE_HANDLE handle,
@@ -5488,12 +5685,25 @@ public:
static ACE_HANDLE accept (ACE_HANDLE handle,
struct sockaddr *addr,
int *addrlen);
+ // BSD-style <accept> (no QoS).
+ static ACE_HANDLE accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen,
+ ACE_Accept_QoS_Params qos_params);
+ // QoS-enabled <accept>.
static int bind (ACE_HANDLE s,
struct sockaddr *name,
int namelen);
static int connect (ACE_HANDLE handle,
struct sockaddr *addr,
int addrlen);
+ // BSD-style <connect> (no QoS).
+ static int connect (ACE_HANDLE handle,
+ const sockaddr *addr,
+ int addrlen,
+ ACE_Connect_QoS_Params qos_params);
+ // QoS-enabled <connect>.
+
static int closesocket (ACE_HANDLE s);
static struct hostent *gethostbyaddr (const char *addr,
int length,
@@ -5539,7 +5749,6 @@ public:
static char *inet_ntoa (const struct in_addr addr);
static int inet_aton (const char *strptr,
struct in_addr *addr);
-
static const char *inet_ntop (int family,
const void *addrptr,
char *strptr,
@@ -5547,8 +5756,11 @@ public:
static int inet_pton (int family,
const char *strptr,
void *addrptr);
-
-
+ static ACE_HANDLE join_leaf (ACE_HANDLE socket,
+ const sockaddr *name,
+ int namelen,
+ ACE_Connect_QoS_Params qos_params);
+ // Joins a leaf node into a QoS-enabled multi-point session.
static int listen (ACE_HANDLE handle,
int backlog);
static int recv (ACE_HANDLE handle,
@@ -5579,6 +5791,7 @@ public:
int optname,
const char *optval,
int optlen);
+ // QoS-enabled <ioctl> wrapper.
static int shutdown (ACE_HANDLE handle,
int how);
static ACE_HANDLE socket (int domain,
diff --git a/ace/OS.i b/ace/OS.i
index 8beda1dbfdf..70e59c87906 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -697,8 +697,6 @@ ACE_OS::umask (mode_t cmask)
#else /* ACE_WIN32 */
-// This is for Win32 exclusively!
-
// Adapt the Win32 System Calls (which return BOOLEAN values of TRUE
// and FALSE) into int values expected by the ACE_OSCALL macros.
# define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) == FALSE ? -1 : 0)
@@ -4141,48 +4139,430 @@ ACE_OS::event_reset (ACE_event_t *event)
# endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
#endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+ACE_INLINE u_long
+ACE_Flow_Spec::token_rate (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->TokenRate;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::token_rate (u_long tr)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->TokenRate = tr;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE u_long
+ACE_Flow_Spec::token_bucket_size (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->TokenBucketSize;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::token_bucket_size (u_long tbs)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->TokenBucketSize = tbs;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE u_long
+ACE_Flow_Spec::peak_bandwidth (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->PeakBandwidth;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::peak_bandwidth (u_long pb)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->PeakBandwidth = pb;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE u_long
+ACE_Flow_Spec::latency (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->Latency;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::latency (u_long l)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->Latency = l;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE u_long
+ACE_Flow_Spec::delay_variation (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->DelayVariation;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+ACE_INLINE void
+ACE_Flow_Spec::delay_variation (u_long dv)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->DelayVariation = dv;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE ACE_SERVICE_TYPE
+ACE_Flow_Spec::service_type (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->ServiceType;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::service_type (ACE_SERVICE_TYPE st)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->ServiceType = st;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE u_long
+ACE_Flow_Spec::max_sdu_size (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->MaxSduSize;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::max_sdu_size (u_long mss)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->MaxSduSize = mss;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE u_long
+ACE_Flow_Spec::minimum_policed_size (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return this->MinimumPolicedSize;
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_Flow_Spec::minimum_policed_size (u_long mps)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->MinimumPolicedSize = mps;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE ACE_Flow_Spec
+ACE_QoS::sending_flowspec (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return (ACE_Flow_Spec &) this->SendingFlowspec;
+#else
+ ACE_NOTSUP_RETURN (ACE_Flow_Spec ());
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_QoS::sending_flowspec (const ACE_Flow_Spec &fs)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->SendingFlowspec = (FLOWSPEC) fs;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE ACE_Flow_Spec
+ACE_QoS::receiving_flowspec (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return (ACE_Flow_Spec &) this->ReceivingFlowspec;
+#else
+ ACE_NOTSUP_RETURN (ACE_Flow_Spec ());
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_QoS::receiving_flowspec (const ACE_Flow_Spec &fs)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->ReceivingFlowspec = (FLOWSPEC) fs;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE iovec
+ACE_QoS::provider_specific (void)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ return (iovec &) this->ProviderSpecific;
+#else
+ ACE_NOTSUP_RETURN (iovec ());
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE void
+ACE_QoS::provider_specific (const iovec &ps)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ this->ProviderSpecific = (WSABUF) ((iovec &) ps);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE
+ACE_Connect_QoS_Params::ACE_Connect_QoS_Params (iovec *caller_data,
+ iovec *callee_data,
+ ACE_QoS *socket_qos,
+ ACE_QoS *group_socket_qos,
+ u_long flags)
+ : caller_data_ (caller_data),
+ callee_data_ (callee_data),
+ socket_qos_ (socket_qos),
+ group_socket_qos_ (group_socket_qos),
+ flags_ (flags)
+{
+}
+
+ACE_INLINE iovec *
+ACE_Connect_QoS_Params::caller_data (void)
+{
+ return this->caller_data_;
+}
+
+ACE_INLINE void
+ACE_Connect_QoS_Params::caller_data (iovec *cd)
+{
+ this->caller_data_ = cd;
+}
+
+ACE_INLINE iovec *
+ACE_Connect_QoS_Params::callee_data (void)
+{
+ return this->callee_data_;
+}
+
+ACE_INLINE void
+ACE_Connect_QoS_Params::callee_data (iovec *cd)
+{
+ this->callee_data_ = cd;
+}
+
+ACE_INLINE ACE_QoS *
+ACE_Connect_QoS_Params::socket_qos (void)
+{
+ return this->socket_qos_;
+}
+
+ACE_INLINE void
+ACE_Connect_QoS_Params::socket_qos (ACE_QoS *sq)
+{
+ this->socket_qos_ = sq;
+}
+
+ACE_INLINE ACE_QoS *
+ACE_Connect_QoS_Params::group_socket_qos (void)
+{
+ return this->group_socket_qos_;
+}
+
+ACE_INLINE void
+ACE_Connect_QoS_Params::group_socket_qos (ACE_QoS *gsq)
+{
+ this->group_socket_qos_ = gsq;
+}
+
+ACE_INLINE u_long
+ACE_Connect_QoS_Params::flags (void)
+{
+ return this->flags_;
+}
+
+ACE_INLINE void
+ACE_Connect_QoS_Params::flags (u_long f)
+{
+ this->flags_ = f;
+}
+
+ACE_INLINE
+ACE_Accept_QoS_Params::ACE_Accept_QoS_Params (ACE_QOS_CONDITION_FUNC qos_condition_callback,
+ u_long callback_data)
+ : qos_condition_callback_ (qos_condition_callback),
+ callback_data_ (callback_data)
+{
+}
+
+ACE_INLINE ACE_QOS_CONDITION_FUNC
+ACE_Accept_QoS_Params::qos_condition_callback (void)
+{
+ return this->qos_condition_callback_;
+}
+
+ACE_INLINE void
+ACE_Accept_QoS_Params::qos_condition_callback (ACE_QOS_CONDITION_FUNC qcc)
+{
+ this->qos_condition_callback_ = qcc;
+}
+
+ACE_INLINE u_long
+ACE_Accept_QoS_Params::callback_data (void)
+{
+ return this->callback_data_;
+}
+
+ACE_INLINE void
+ACE_Accept_QoS_Params::callback_data (u_long cd)
+{
+ this->callback_data_ = cd;
+}
ACE_INLINE ACE_HANDLE
-ACE_OS::accept (ACE_HANDLE handle, struct sockaddr *addr,
+ACE_OS::accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
int *addrlen)
{
ACE_TRACE ("ACE_OS::accept");
#if defined (ACE_PSOS)
# if !defined (ACE_PSOS_DIAB_PPC)
-ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle, (struct sockaddr_in *) addr,
- (ACE_SOCKET_LEN *) addrlen),
- ACE_HANDLE, ACE_INVALID_HANDLE);
+ ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
+ (struct sockaddr_in *) addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
# else
-ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle, (struct sockaddr *) addr,
- (ACE_SOCKET_LEN *) addrlen),
- ACE_HANDLE, ACE_INVALID_HANDLE);
+ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
+ (struct sockaddr *) addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
# endif /* defined ACE_PSOS_DIAB_PPC */
#else
- // On a non-blocking socket with no connections to accept, this system
- // call will return EWOULDBLOCK or EAGAIN, depending on the platform.
- // UNIX 98 allows either errno, and they may be the same numeric value.
- // So to make life easier for upper ACE layers as well as application
- // programmers, always change EAGAIN to EWOULDBLOCK. Rather than hack the
- // ACE_OSCALL_RETURN macro, it's handled explicitly here. If the ACE_OSCALL
- // macro ever changes, this function needs to be reviewed.
- // On Win32, the regular macros can be used, as this is not an issue.
+ // On a non-blocking socket with no connections to accept, this
+ // system call will return EWOULDBLOCK or EAGAIN, depending on the
+ // platform. UNIX 98 allows either errno, and they may be the same
+ // numeric value. So to make life easier for upper ACE layers as
+ // well as application programmers, always change EAGAIN to
+ // EWOULDBLOCK. Rather than hack the ACE_OSCALL_RETURN macro, it's
+ // handled explicitly here. If the ACE_OSCALL macro ever changes,
+ // this function needs to be reviewed. On Win32, the regular macros
+ // can be used, as this is not an issue.
# if defined (ACE_WIN32)
- ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle, addr, (ACE_SOCKET_LEN *) addrlen),
- ACE_HANDLE, ACE_INVALID_HANDLE);
+ ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
# else
-
- ACE_HANDLE ace_result_;
- ace_result_ = ::accept ((ACE_SOCKET) handle, addr,
- (ACE_SOCKET_LEN *) addrlen) ;
+ ACE_HANDLE ace_result = ::accept ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen) ;
if (ace_result_ == ACE_INVALID_HANDLE && errno == EAGAIN)
errno = EWOULDBLOCK;
- return ace_result_;
+ return ace_result;
# endif /* defined (ACE_WIN32) */
#endif /* defined (ACE_PSOS) */
}
+ACE_INLINE ACE_HANDLE
+ACE_OS::accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen,
+ ACE_Accept_QoS_Params qos_params)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ ACE_SOCKCALL_RETURN (::WSAAccept ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen,
+ (LPCONDITIONPROC) qos_params.qos_condition_callback (),
+ qos_params.callback_data ()),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+#else
+ ACE_UNUSED_ARG (qos_params);
+ return ACE_OS::accept (handle,
+ addr,
+ addrlen);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::join_leaf (ACE_HANDLE socket,
+ const sockaddr *name,
+ int namelen,
+ ACE_Connect_QoS_Params qos_params)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ ACE_SOCKCALL_RETURN (::WSAJoinLeaf ((ACE_SOCKET) socket,
+ name,
+ namelen,
+ (WSABUF *) qos_params.caller_data (),
+ (WSABUF *) qos_params.callee_data (),
+ (QOS *) qos_params.socket_qos (),
+ (QOS *) qos_params.group_socket_qos (),
+ qos_params.flags ()),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+#else
+ ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+int
+ACE_OS::ioctl (ACE_HANDLE socket,
+ u_long io_control_code,
+ void *in_buffer_p,
+ u_long in_buffer,
+ void *out_buffer_p,
+ u_long out_buffer,
+ u_long *bytes_returned,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ ACE_SOCKCALL_RETURN (::WSAIoctl ((ACE_SOCKET) socket,
+ io_control_code,
+ in_buffer_p,
+ in_buffer,
+ out_buffer_p,
+ out_buffer,
+ bytes_returned,
+ (WSAOVERLAPPED *) overlapped,
+ (LPWSAOVERLAPPED_COMPLETION_ROUTINE) func),
+ int,
+ SOCKET_ERROR);
+#else
+ ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
ACE_INLINE int
ACE_OS::bind (ACE_HANDLE handle, struct sockaddr *addr, int addrlen)
{
@@ -4197,7 +4577,9 @@ ACE_OS::bind (ACE_HANDLE handle, struct sockaddr *addr, int addrlen)
}
ACE_INLINE int
-ACE_OS::connect (ACE_HANDLE handle, struct sockaddr *addr, int addrlen)
+ACE_OS::connect (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int addrlen)
{
ACE_TRACE ("ACE_OS::connect");
#if defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC)
@@ -4209,6 +4591,30 @@ ACE_OS::connect (ACE_HANDLE handle, struct sockaddr *addr, int addrlen)
#endif /* defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC) */
}
+ACE_INLINE int
+ACE_OS::connect (ACE_HANDLE handle,
+ const sockaddr *addr,
+ int addrlen,
+ ACE_Connect_QoS_Params qos_params)
+{
+ ACE_TRACE ("ACE_OS::connect");
+#if defined (ACE_HAS_WINSOCK2)
+ ACE_SOCKCALL_RETURN (::WSAConnect ((ACE_SOCKET) handle,
+ (const sockaddr *) addr,
+ (ACE_SOCKET_LEN) addrlen,
+ (WSABUF *) qos_params.caller_data (),
+ (WSABUF *) qos_params.callee_data (),
+ (QOS *) qos_params.socket_qos (),
+ (QOS *) qos_params.group_socket_qos ()),
+ int, -1);
+#else
+ ACE_UNUSED_ARG (qos_params);
+ return ACE_OS::connect (handle,
+ addr,
+ addrlen);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
#if !defined (VXWORKS)
ACE_INLINE struct hostent *
ACE_OS::gethostbyname (const char *name)
@@ -10950,3 +11356,53 @@ ACE_OS_CString::wchar_rep (void)
{
return this->rep_;
}
+
+ACE_INLINE
+ACE_Errno_Guard::ACE_Errno_Guard (int &errno_ref,
+ int error)
+ :
+#if defined (ACE_MT_SAFE)
+ errno_ptr_ (&errno_ref),
+#endif /* ACE_MT_SAFE */
+ error_ (error)
+{
+}
+
+ACE_INLINE
+ACE_Errno_Guard::ACE_Errno_Guard (int &errno_ref)
+ :
+#if defined (ACE_MT_SAFE)
+ errno_ptr_ (&errno_ref),
+#endif /* ACE_MT_SAFE */
+ error_ (errno_ref)
+{
+}
+
+ACE_INLINE
+ACE_Errno_Guard::~ACE_Errno_Guard (void)
+{
+#if defined (ACE_MT_SAFE)
+ *errno_ptr_ = this->error_;
+#else
+ errno = this->error_;
+#endif /* ACE_MT_SAFE */
+}
+
+ACE_INLINE int
+ACE_Errno_Guard::operator= (int error)
+{
+ return this->error_ = error;
+}
+
+ACE_INLINE int
+ACE_Errno_Guard::operator== (int error)
+{
+ return this->error_ == error;
+}
+
+ACE_INLINE int
+ACE_Errno_Guard::operator!= (int error)
+{
+ return this->error_ != error;
+}
+
diff --git a/ace/SOCK_Acceptor.cpp b/ace/SOCK_Acceptor.cpp
index 62f12886438..b6c2599de7e 100644
--- a/ace/SOCK_Acceptor.cpp
+++ b/ace/SOCK_Acceptor.cpp
@@ -21,6 +21,75 @@ ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (void)
ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
}
+// Performs the timed accept operation.
+
+int
+ACE_SOCK_Acceptor::shared_accept_start (ACE_Time_Value *timeout,
+ int restart,
+ int &in_blocking_mode) const
+{
+ ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept_start");
+
+ ACE_HANDLE handle = this->get_handle ();
+
+ // Handle the case where we're doing a timed <accept>.
+ if (timeout != 0)
+ {
+ if (ACE::handle_timed_accept (handle,
+ timeout,
+ restart) == -1)
+ return -1;
+ else
+ {
+ in_blocking_mode = ACE_BIT_DISABLED (ACE::get_flags (handle),
+ ACE_NONBLOCK);
+ // Set the handle into non-blocking mode if it's not already
+ // in it.
+ if (in_blocking_mode
+ && ACE::set_flags (handle,
+ ACE_NONBLOCK) == -1)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+ACE_SOCK_Acceptor::shared_accept_finish (ACE_SOCK_Stream new_stream,
+ int in_blocking_mode,
+ int reset_new_handle) const
+{
+ ACE_TRACE ("ACE_SOCK_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 */
+
+ return new_handle == ACE_INVALID_HANDLE ? -1 : 0;
+}
+
// General purpose routine for accepting new connections.
int
@@ -32,13 +101,89 @@ ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream,
{
ACE_TRACE ("ACE_SOCK_Acceptor::accept");
- ACE_HANDLE new_handle =
- this->shared_accept (remote_addr,
- timeout,
- restart,
- reset_new_handle);
- new_stream.set_handle (new_handle);
- return new_handle == ACE_INVALID_HANDLE ? -1 : 0;
+ int in_blocking_mode = 0;
+ if (this->shared_accept_start (timeout,
+ restart,
+ in_blocking_mode) == -1)
+ return -1;
+ else
+ {
+ sockaddr *addr = 0;
+ int len = 0;
+
+ if (remote_addr != 0)
+ {
+ len = remote_addr->get_size ();
+ addr = (sockaddr *) remote_addr->get_addr ();
+ }
+
+ do
+ new_stream.set_handle (ACE_OS::accept (this->get_handle (),
+ addr,
+ &len));
+ while (new_stream.get_handle () == ACE_INVALID_HANDLE
+ && restart != 0
+ && errno == EINTR
+ && timeout == 0);
+
+ // Reset the size of the addr, which is only necessary for UNIX
+ // domain sockets.
+ if (new_stream.get_handle () != ACE_INVALID_HANDLE
+ && remote_addr != 0)
+ remote_addr->set_size (len);
+ }
+
+ return this->shared_accept_finish (new_stream,
+ in_blocking_mode,
+ reset_new_handle);
+}
+
+int
+ACE_SOCK_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
+{
+ ACE_TRACE ("ACE_SOCK_Acceptor::accept");
+
+ int in_blocking_mode = 0;
+ if (this->shared_accept_start (timeout,
+ restart,
+ in_blocking_mode) == -1)
+ return -1;
+ else
+ {
+ sockaddr *addr = 0;
+ int len = 0;
+
+ if (remote_addr != 0)
+ {
+ len = remote_addr->get_size ();
+ addr = (sockaddr *) remote_addr->get_addr ();
+ }
+
+ do
+ new_stream.set_handle (ACE_OS::accept (this->get_handle (),
+ addr,
+ &len,
+ qos_params));
+ while (new_stream.get_handle () == ACE_INVALID_HANDLE
+ && restart != 0
+ && errno == EINTR
+ && timeout == 0);
+
+ // Reset the size of the addr, which is only necessary for UNIX
+ // domain sockets.
+ if (new_stream.get_handle () != ACE_INVALID_HANDLE
+ && remote_addr != 0)
+ remote_addr->set_size (len);
+ }
+
+ return this->shared_accept_finish (new_stream,
+ in_blocking_mode,
+ reset_new_handle);
}
// General purpose routine for performing server ACE_SOCK creation.
@@ -50,9 +195,14 @@ ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
int protocol)
{
ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor");
- if (this->open (local_sap, reuse_addr, protocol_family,
- backlog, protocol) == -1)
- ACE_ERROR ((LM_ERROR, ASYS_TEXT ("%p\n"), ASYS_TEXT ("ACE_SOCK_Acceptor")));
+ if (this->open (local_sap,
+ reuse_addr,
+ protocol_family,
+ backlog,
+ protocol) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("ACE_SOCK_Acceptor")));
}
void
@@ -73,8 +223,10 @@ ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
ACE_TRACE ("ACE_SOCK_Acceptor::open");
int error = 0;
- if (ACE_SOCK::open (SOCK_STREAM, protocol_family,
- protocol, reuse_addr) == -1)
+ if (ACE_SOCK::open (SOCK_STREAM,
+ protocol_family,
+ protocol,
+ reuse_addr) == -1)
error = 1;
else if (protocol_family == PF_INET)
@@ -101,92 +253,20 @@ ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap,
else
{
if (ACE_OS::bind (this->get_handle (),
- ACE_reinterpret_cast(sockaddr *, &local_inet_addr),
+ ACE_reinterpret_cast (sockaddr *,
+ &local_inet_addr),
sizeof local_inet_addr) == -1)
error = 1;
}
}
- else if (ACE_OS::bind (this->get_handle (), (sockaddr *) local_sap.get_addr (),
+ else if (ACE_OS::bind (this->get_handle (),
+ (sockaddr *) local_sap.get_addr (),
local_sap.get_size ()) == -1)
error = 1;
- if (error || ACE_OS::listen (this->get_handle (), backlog) == -1)
+ if (error || ACE_OS::listen (this->get_handle (),
+ backlog) == -1)
this->close ();
return error ? -1 : 0;
}
-
-// Performs the timed accept operation.
-
-ACE_HANDLE
-ACE_SOCK_Acceptor::shared_accept (ACE_Addr *remote_addr,
- ACE_Time_Value *timeout,
- int restart,
- int reset_new_handle) const
-{
- ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept");
- ACE_UNUSED_ARG (reset_new_handle);
-
- sockaddr *addr = 0;
- int *len_ptr = 0;
- int len;
- ACE_HANDLE new_handle;
- ACE_HANDLE handle = this->get_handle ();
-
- if (remote_addr != 0)
- {
- len = remote_addr->get_size ();
- len_ptr = &len;
- addr = (sockaddr *) remote_addr->get_addr ();
- }
-
- // Handle the case where we're doing a timed <accept>.
- if (timeout != 0)
- {
- if (ACE::handle_timed_accept (handle, timeout, restart) == -1)
- return ACE_INVALID_HANDLE;
- else
- {
- int val = ACE::get_flags (handle);
-
- // Set the handle into non-blocking mode if it's not already
- // in it.
- if (ACE_BIT_DISABLED (val, ACE_NONBLOCK)
- && ACE::set_flags (handle, ACE_NONBLOCK) == -1)
- return ACE_INVALID_HANDLE;
-
- new_handle = ACE_OS::accept (handle, addr, len_ptr);
-
- if (ACE_BIT_DISABLED (val, ACE_NONBLOCK))
- {
- // Save/restore errno.
- ACE_Errno_Guard error (errno);
- // Only disable ACE_NONBLOCK if we weren't in
- // non-blocking mode originally.
- ACE::clr_flags (handle, ACE_NONBLOCK);
- ACE::clr_flags (new_handle, ACE_NONBLOCK);
- }
- }
- }
- else
- {
- // Perform a blocking accept.
-
- do
- new_handle = ACE_OS::accept (handle, addr, len_ptr);
- while (new_handle == ACE_INVALID_HANDLE && restart && errno == EINTR);
- }
-
-#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, NULL, 0);
-#endif /* ACE_WIN32 */
-
- // Reset the size of the addr (really only necessary for the
- // UNIX domain sockets).
- if (new_handle != ACE_INVALID_HANDLE && remote_addr != 0)
- remote_addr->set_size (*len_ptr);
-
- return new_handle;
-}
diff --git a/ace/SOCK_Acceptor.h b/ace/SOCK_Acceptor.h
index 5f68e60030f..b7aa9f0b545 100644
--- a/ace/SOCK_Acceptor.h
+++ b/ace/SOCK_Acceptor.h
@@ -28,8 +28,7 @@
class ACE_Export ACE_SOCK_Acceptor : public ACE_SOCK
{
// = TITLE
- // Defines the format and interface for an <ACE_Stream>
- // acceptor.
+ // Defines a factory that creates new <ACE_Stream>s passively.
public:
// = Initialization methods.
ACE_SOCK_Acceptor (void);
@@ -52,15 +51,26 @@ public:
int protocol = 0);
// Initiate a passive mode socket.
- // = Passive connection acceptance method.
+ // = Passive connection <accept> methods.
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;
- // Accept a new data transfer connection. A <timeout> of 0 means
- // block forever, a <timeout> of {0, 0} means poll. <restart> == 1
- // means "restart if interrupted."
+ // Accept a new <ACE_SOCK_Stream> connection. A <timeout> of 0
+ // means block forever, a <timeout> of {0, 0} means poll. <restart>
+ // == 1 means "restart if interrupted," i.e., if errno == EINTR.
+
+ 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;
+ // Accept a new <ACE_SOCK_Stream> connection using the RVSP QoS
+ // information in <qos_params>. A <timeout> of 0 means block
+ // forever, a <timeout> of {0, 0} means poll. <restart> == 1 means
+ // "restart if interrupted," i.e., if errno == EINTR.
// = Meta-type info
typedef ACE_INET_Addr PEER_ADDR;
@@ -73,6 +83,18 @@ public:
// Declare the dynamic allocation hooks.
protected:
+ int shared_accept_start (ACE_Time_Value *timeout,
+ int restart,
+ int &in_blocking_mode) const;
+ // Perform operations that must occur before <ACE_OS::accept> is
+ // called.
+
+ int shared_accept_finish (ACE_SOCK_Stream new_stream,
+ int in_blocking_mode,
+ int reset_new_handle) const;
+ // Perform operations that must occur after <ACE_OS::accept> is
+ // called.
+
ACE_HANDLE shared_accept (ACE_Addr *remote_addr,
ACE_Time_Value *,
int restart,
diff --git a/ace/SOCK_Connector.cpp b/ace/SOCK_Connector.cpp
index 6a1edc9028d..9938d839f4a 100644
--- a/ace/SOCK_Connector.cpp
+++ b/ace/SOCK_Connector.cpp
@@ -20,22 +20,15 @@ ACE_SOCK_Connector::dump (void) const
ACE_TRACE ("ACE_SOCK_Connector::dump");
}
-// Actively connect and produce a new ACE_SOCK_Stream if things go well...
-
-int
-ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
- const ACE_Addr &remote_sap,
- ACE_Time_Value *timeout,
- const ACE_Addr &local_sap,
- int reuse_addr,
- int /* flags */,
- int /* perms */,
- int protocol_family,
- int protocol)
+int
+ACE_SOCK_Connector::shared_connect_start (ACE_SOCK_Stream &new_stream,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int protocol_family,
+ int protocol)
{
- ACE_TRACE ("ACE_SOCK_Connector::connect");
- int result = 0;
-
+ ACE_TRACE ("ACE_SOCK_Connector::shared_connect_start");
// Only open a new socket if we don't already have a valid handle.
if (new_stream.get_handle () == ACE_INVALID_HANDLE
&& new_stream.open (SOCK_STREAM,
@@ -43,65 +36,126 @@ ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
protocol,
reuse_addr) == -1)
return -1;
-
- sockaddr *raddr = (sockaddr *) remote_sap.get_addr ();
- size_t rsize = remote_sap.get_size ();
-
- if (local_sap != ACE_Addr::sap_any)
+ else if (local_sap != ACE_Addr::sap_any)
{
sockaddr *laddr = (sockaddr *) local_sap.get_addr ();
size_t size = local_sap.get_size ();
- result = ACE_OS::bind (new_stream.get_handle (),
- laddr,
- size);
-
- if (result == -1)
+ if (ACE_OS::bind (new_stream.get_handle (),
+ laddr,
+ size) == -1)
{
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
new_stream.close ();
return -1;
}
}
// Enable non-blocking, if required.
- if (timeout != 0)
+ if (timeout != 0 && new_stream.enable (ACE_NONBLOCK) == -1)
+ return -1;
+ else
+ return 0;
+}
+
+int
+ACE_SOCK_Connector::shared_connect_finish (ACE_SOCK_Stream &new_stream,
+ ACE_Time_Value *timeout,
+ int result)
+{
+ ACE_TRACE ("ACE_SOCK_Connector::shared_connect_finish");
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+
+ if (result == -1 && timeout != 0)
{
- if (new_stream.enable (ACE_NONBLOCK) == -1)
- result = -1;
-
- if (ACE_OS::connect (new_stream.get_handle (), raddr, rsize) == -1)
+ // Check whether the connection is in progress.
+ if (error == EINPROGRESS || error == EWOULDBLOCK)
{
- result = -1;
-
- // Check whether the connection is in progress.
- if (errno == EINPROGRESS || errno == EWOULDBLOCK)
- {
- // This expression checks if we were polling.
- if (timeout->sec () == 0 && timeout->usec () == 0)
- errno = EWOULDBLOCK;
- // Wait synchronously
- else if (this->complete (new_stream, 0, timeout) != -1)
- return 0;
- }
+ // This expression checks if we were polling.
+ if (timeout->sec () == 0 && timeout->usec () == 0)
+ error = EWOULDBLOCK;
+ // Wait synchronously using timeout.
+ else if (this->complete (new_stream,
+ 0,
+ timeout) == -1)
+ error = errno;
+ else
+ return 0;
}
}
- // Do a blocking connect.
- else if (ACE_OS::connect (new_stream.get_handle (), raddr, rsize) == -1)
- result = -1;
// EISCONN is treated specially since this routine may be used to
// check if we are already connected.
- if (result != -1 || errno == EISCONN)
+ if (result != -1 || error == EISCONN)
// Start out with non-blocking disabled on the <new_stream>.
new_stream.disable (ACE_NONBLOCK);
- else if (!(errno == EWOULDBLOCK || errno == ETIMEDOUT))
- {
- // Save/restore errno.
- ACE_Errno_Guard error (errno);
- new_stream.close ();
- }
-
+ else if (!(error == EWOULDBLOCK || error == ETIMEDOUT))
+ new_stream.close ();
+
return result;
}
+// Actively connect and produce a new ACE_SOCK_Stream if things go well...
+
+int
+ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int /* flags */,
+ int /* perms */,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_SOCK_Connector::connect");
+ if (this->shared_connect_start (new_stream,
+ timeout,
+ local_sap,
+ reuse_addr,
+ protocol_family,
+ protocol) == -1)
+ return -1;
+
+ int result = ACE_OS::connect (new_stream.get_handle (),
+ (sockaddr *) remote_sap.get_addr (),
+ remote_sap.get_size ());
+
+ return this->shared_connect_finish (new_stream,
+ timeout,
+ result);
+}
+
+int
+ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Connect_QoS_Params qos_params,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int /* flags */,
+ int /* perms */,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_SOCK_Connector::connect");
+ if (this->shared_connect_start (new_stream,
+ timeout,
+ local_sap,
+ reuse_addr,
+ protocol_family,
+ protocol) == -1)
+ return -1;
+
+ int result = ACE_OS::connect (new_stream.get_handle (),
+ (sockaddr *) remote_sap.get_addr (),
+ remote_sap.get_size (),
+ qos_params);
+
+ return this->shared_connect_finish (new_stream,
+ timeout,
+ result);
+}
// Try to complete a non-blocking connection.
@@ -118,8 +172,9 @@ ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY);
ACE_OS::sleep (time);
#endif /* ACE_HAS_BROKEN_NON_BLOCKING_CONNECTS */
- ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (), tv);
-
+ ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (),
+ tv);
+ // We failed to get connected.
if (h == ACE_INVALID_HANDLE)
{
// Save/restore errno.
@@ -127,28 +182,82 @@ ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream,
new_stream.close ();
return -1;
}
- else // We've successfully connected!
+ else if (remote_sap != 0)
{
- if (remote_sap != 0)
+ int len = remote_sap->get_size ();
+ sockaddr *addr = (sockaddr *) remote_sap->get_addr ();
+
+ if (ACE_OS::getpeername (h,
+ addr,
+ &len) == -1)
{
- int len;
-
- len = remote_sap->get_size ();
- sockaddr *addr = (sockaddr *) remote_sap->get_addr ();
-
- if (ACE_OS::getpeername (h, addr, &len) == -1)
- {
- // Save/restore errno.
- ACE_Errno_Guard error (errno);
- new_stream.close ();
- return -1;
- }
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ new_stream.close ();
+ return -1;
}
-
- // Start out with non-blocking disabled on the <new_stream>.
- new_stream.disable (ACE_NONBLOCK);
- return 0;
}
+
+ // Start out with non-blocking disabled on the <new_stream>.
+ new_stream.disable (ACE_NONBLOCK);
+ return 0;
}
+ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int flags,
+ int perms,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
+
+ if (this->connect (new_stream,
+ remote_sap,
+ timeout,
+ local_sap,
+ reuse_addr,
+ flags,
+ perms,
+ protocol_family,
+ protocol) == -1
+ && timeout != 0
+ && !(errno == EWOULDBLOCK || errno == ETIME))
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
+}
+
+ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Connect_QoS_Params qos_params,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int flags,
+ int perms,
+ int protocol_family,
+ int protocol)
+{
+ ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
+
+ if (this->connect (new_stream,
+ remote_sap,
+ qos_params,
+ timeout,
+ local_sap,
+ reuse_addr,
+ flags,
+ perms,
+ protocol_family,
+ protocol) == -1
+ && timeout != 0
+ && !(errno == EWOULDBLOCK || errno == ETIME))
+ ACE_ERROR ((LM_ERROR,
+ ASYS_TEXT ("%p\n"),
+ ASYS_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
+}
diff --git a/ace/SOCK_Connector.h b/ace/SOCK_Connector.h
index 57d52903f52..e6abeb6a0e9 100644
--- a/ace/SOCK_Connector.h
+++ b/ace/SOCK_Connector.h
@@ -61,8 +61,30 @@ public:
// the OS do the binding. If <reuse_addr> == 1 then the
// <local_addr> is reused, even if it hasn't been cleanedup yet.
- ~ACE_SOCK_Connector (void);
- // Default dtor.
+ ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Connect_QoS_Params qos_params,
+ 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_family = PF_INET,
+ 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 <qos_params> contains QoS parameters that are passed
+ // to RSVP. 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 <ACE_Addr::sap_any> 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_SOCK_Stream &new_stream,
const ACE_Addr &remote_sap,
@@ -87,6 +109,34 @@ public:
// 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_SOCK_Stream &new_stream,
+ const ACE_Addr &remote_sap,
+ ACE_Connect_QoS_Params qos_params,
+ 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_family = PF_INET,
+ 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 <qos_params> contains QoS parameters that are passed
+ // to RSVP. 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 <ACE_Addr::sap_any> 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_SOCK_Connector (void);
+ // Default dtor.
+
// = Completion routine.
int complete (ACE_SOCK_Stream &new_stream,
ACE_Addr *remote_sap = 0,
@@ -108,6 +158,20 @@ public:
ACE_ALLOC_HOOK_DECLARE;
// Declare the dynamic allocation hooks.
+
+protected:
+ int shared_connect_start (ACE_SOCK_Stream &new_stream,
+ ACE_Time_Value *timeout,
+ const ACE_Addr &local_sap,
+ int reuse_addr,
+ int protocol_family,
+ int protocol);
+ // Perform operations that must be called before <ACE_OS::connect>.
+
+ int shared_connect_finish (ACE_SOCK_Stream &new_stream,
+ ACE_Time_Value *timeout,
+ int result);
+ // Perform operations that must be called after <ACE_OS::connect>.
};
#if !defined (ACE_LACKS_INLINE_FUNCTIONS)
diff --git a/ace/SOCK_Connector.i b/ace/SOCK_Connector.i
index ebce17c7f53..c4801c01cf0 100644
--- a/ace/SOCK_Connector.i
+++ b/ace/SOCK_Connector.i
@@ -12,24 +12,6 @@ ACE_SOCK_Connector::~ACE_SOCK_Connector (void)
ACE_TRACE ("ACE_SOCK_Connector::~ACE_SOCK_Connector");
}
-ASYS_INLINE
-ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
- const ACE_Addr &remote_sap,
- ACE_Time_Value *timeout,
- const ACE_Addr &local_sap,
- int reuse_addr,
- int flags,
- int perms,
- int protocol_family,
- int protocol)
-{
- ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector");
- if (this->connect (new_stream, remote_sap, timeout, local_sap,
- reuse_addr, flags, perms, protocol_family, protocol) == -1
- && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIME))
- ACE_ERROR ((LM_ERROR, ASYS_TEXT ("%p\n"), ASYS_TEXT ("ACE_SOCK_Connector::ACE_SOCK_Connector")));
-}
-
// Do-nothing constructor...
ASYS_INLINE