1 #include "ace/OS_NS_sys_socket.h"
3 #if !defined (ACE_HAS_INLINED_OSCALLS)
4 # include "ace/OS_NS_sys_socket.inl"
5 #endif /* ACE_HAS_INLINED_OSCALLS */
7 #include "ace/Containers_T.h"
9 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
11 #if defined (ACE_WIN32)
12 int ACE_OS::socket_initialized_
;
13 #endif /* ACE_WIN32 */
16 ACE_OS::accept (ACE_HANDLE handle
,
17 struct sockaddr
*addr
,
19 const ACE_Accept_QoS_Params
&qos_params
)
21 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
22 ACE_SOCKCALL_RETURN (::WSAAccept ((ACE_SOCKET
) handle
,
24 (ACE_SOCKET_LEN
*) addrlen
,
25 (LPCONDITIONPROC
) qos_params
.qos_condition_callback (),
26 qos_params
.callback_data ()),
30 ACE_UNUSED_ARG (qos_params
);
31 return ACE_OS::accept (handle
,
34 # endif /* ACE_HAS_WINSOCK2 */
38 ACE_OS::connect (ACE_HANDLE handle
,
41 const ACE_QoS_Params
&qos_params
)
43 ACE_OS_TRACE ("ACE_OS::connect");
44 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
45 ACE_SOCKCALL_RETURN (::WSAConnect ((ACE_SOCKET
) handle
,
46 (const sockaddr
*) addr
,
47 (ACE_SOCKET_LEN
) addrlen
,
48 (WSABUF
*) qos_params
.caller_data (),
49 (WSABUF
*) qos_params
.callee_data (),
50 (QOS
*) qos_params
.socket_qos (),
51 (QOS
*) qos_params
.group_socket_qos ()),
54 ACE_UNUSED_ARG (qos_params
);
55 return ACE_OS::connect (handle
,
56 const_cast <sockaddr
*> (addr
),
58 # endif /* ACE_HAS_WINSOCK2 */
62 ACE_OS::join_leaf (ACE_HANDLE socket
,
65 const ACE_QoS_Params
&qos_params
)
67 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
70 // Construct the WinSock2 QOS structure.
72 qos
.SendingFlowspec
= *(qos_params
.socket_qos ()->sending_flowspec ());
73 qos
.ReceivingFlowspec
= *(qos_params
.socket_qos ()->receiving_flowspec ());
74 qos
.ProviderSpecific
= (WSABUF
) qos_params
.socket_qos ()->provider_specific ();
76 ACE_SOCKCALL_RETURN (::WSAJoinLeaf ((ACE_SOCKET
) socket
,
79 (WSABUF
*) qos_params
.caller_data (),
80 (WSABUF
*) qos_params
.callee_data (),
82 (QOS
*) qos_params
.group_socket_qos (),
88 ACE_UNUSED_ARG (socket
);
89 ACE_UNUSED_ARG (name
);
90 ACE_UNUSED_ARG (namelen
);
91 ACE_UNUSED_ARG (qos_params
);
92 ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE
);
93 # endif /* ACE_HAS_WINSOCK2 */
97 ACE_OS::socket_init (int version_high
, int version_low
)
99 # if defined (ACE_WIN32) && !defined(ACE_DONT_INIT_WINSOCK)
100 if (ACE_OS::socket_initialized_
== 0)
102 WORD version_requested
= MAKEWORD (version_high
, version_low
);
104 int error
= WSAStartup (version_requested
, &wsa_data
);
108 ACE_OS::fprintf (stderr
,
109 "ACE_OS::socket_init; WSAStartup failed, "
110 "WSAGetLastError returned %d\n",
114 ACE_OS::socket_initialized_
= 1;
117 ACE_UNUSED_ARG (version_high
);
118 ACE_UNUSED_ARG (version_low
);
119 # endif /* ACE_WIN32 */
124 ACE_OS::socket_fini ()
126 # if defined (ACE_WIN32)
127 if (ACE_OS::socket_initialized_
!= 0)
129 if (WSACleanup () != 0)
131 int error
= ::WSAGetLastError ();
132 ACE_OS::fprintf (stderr
,
133 "ACE_OS::socket_fini; WSACleanup failed, "
134 "WSAGetLastError returned %d\n",
137 ACE_OS::socket_initialized_
= 0;
139 # endif /* ACE_WIN32 */
144 ACE_OS::sendv_partial_i (ACE_HANDLE handle
,
145 const iovec
*buffers
,
148 // the divide and conquer logic should remain consistent
149 // with send_partial_i
150 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
151 DWORD bytes_sent
= 0;
154 ACE_UINT64 buffer_size
= 0;
155 ACE_Array
<iovec
> iovec_array(simulated_n
);
157 for ( ; i
< simulated_n
; ++i
)
159 iovec_array
[i
].iov_base
= buffers
[i
].iov_base
;
160 iovec_array
[i
].iov_len
= buffers
[i
].iov_len
;
161 buffer_size
+= buffers
[i
].iov_len
;
163 // keep dividing the current buffer_size in half and then
164 // attempt to send the modified iovec buffer until some
165 // data is sent, or we get an errno that is not ENOBUFS
168 ACE_UINT64 remove_size
= buffer_size
/ 2;
169 buffer_size
-= remove_size
;
170 for (i
= simulated_n
- 1; (i
>= 0) && (remove_size
> 0); --i
)
172 // if the buffer division splits an iovec, we need
173 // to set its iov_len properly
174 if (iovec_array
[i
].iov_len
> remove_size
)
176 iovec_array
[i
].iov_len
-= static_cast<u_long
>(remove_size
);
179 remove_size
-= iovec_array
[i
].iov_len
;
184 result
= ::WSASend ((SOCKET
) handle
,
185 (WSABUF
*) &(iovec_array
[0]),
191 if (result
!= SOCKET_ERROR
)
194 ACE_OS::set_errno_to_wsa_last_error ();
195 // if ENOBUFS is received, we apply a divide and
196 // conquer strategy, but if bytes are sent we
197 // cannot guarantee this is the same behavior
198 if ((errno
!= ENOBUFS
) ||
205 return (ssize_t
) bytes_sent
;
207 ACE_UNUSED_ARG (handle
);
208 ACE_UNUSED_ARG (buffers
);
210 ACE_NOTSUP_RETURN (-1);
211 #endif /* ACE_HAS_WINSOCK2 */
215 ACE_OS::send_partial_i (ACE_HANDLE handle
,
220 // the divide and conquer logic should remain consistent
221 // with sendv_partial_i
222 #if !defined (ACE_LACKS_SEND) && defined (ACE_WIN32)
223 DWORD bytes_sent
= 0;
225 // keep dividing the current buffer_size in half and then
226 // attempt to send the modified buffer until some data is
227 // sent, or we get an errno that is not ENOBUFS
232 result
= (ssize_t
) ::send ((SOCKET
) handle
,
234 static_cast<int> (len
),
236 if (result
!= SOCKET_ERROR
)
239 ACE_OS::set_errno_to_wsa_last_error ();
240 // if ENOBUFS is received, we apply a divide and
241 // conquer strategy, but if bytes are sent we
242 // cannot guarantee this is the same behavior
243 if ((errno
!= ENOBUFS
) ||
252 ACE_UNUSED_ARG (handle
);
253 ACE_UNUSED_ARG (buf
);
254 ACE_UNUSED_ARG (len
);
255 ACE_UNUSED_ARG (flags
);
256 ACE_NOTSUP_RETURN (-1);
257 #endif /* ACE_LACKS_SEND && ACE_WIN32 */
260 #if !defined ACE_LACKS_RECVMSG && defined ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2
261 int ACE_OS::recvmsg_win32_i (ACE_HANDLE handle
,
264 unsigned long &bytes_received
)
266 static GUID wsaRcvMsgGuid
= WSAID_WSARECVMSG
;
267 LPFN_WSARECVMSG wsaRcvMsg
= 0;
268 unsigned long ioctlN
= 0;
269 SOCKET
const sock
= reinterpret_cast<SOCKET
> (handle
);
270 if (::WSAIoctl (sock
, SIO_GET_EXTENSION_FUNCTION_POINTER
,
271 &wsaRcvMsgGuid
, sizeof wsaRcvMsgGuid
,
272 &wsaRcvMsg
, sizeof wsaRcvMsg
,
275 ACE_OS::set_errno_to_wsa_last_error ();
280 ACE_NOTSUP_RETURN (-1);
286 reinterpret_cast<WSABUF
*> (msg
->msg_iov
),
287 static_cast<unsigned long> (msg
->msg_iovlen
),
289 static_cast<unsigned long> (msg
->msg_controllen
),
290 static_cast<char *> (msg
->msg_control
),
292 static_cast<unsigned long> (flags
),
295 if (wsaRcvMsg (sock
, &wsaMsg
, &bytes_received
, 0, 0))
297 ACE_OS::set_errno_to_wsa_last_error ();
301 msg
->msg_namelen
= wsaMsg
.namelen
;
302 msg
->msg_controllen
= static_cast<int> (wsaMsg
.Control
.len
);
306 int ACE_OS::sendmsg_win32_i (ACE_HANDLE handle
,
309 unsigned long &bytes_sent
)
311 # if _WIN32_WINNT >= 0x0600
316 reinterpret_cast<WSABUF
*> (msg
->msg_iov
),
317 static_cast<unsigned long> (msg
->msg_iovlen
),
319 static_cast<unsigned long> (msg
->msg_controllen
),
320 static_cast<char *> (msg
->msg_control
),
322 static_cast<unsigned long> (flags
),
325 SOCKET
const sock
= reinterpret_cast<SOCKET
> (handle
);
326 if (::WSASendMsg (sock
, &wsaMsg
, wsaMsg
.dwFlags
, &bytes_sent
, 0, 0))
328 ACE_OS::set_errno_to_wsa_last_error ();
334 ACE_UNUSED_ARG (handle
);
335 ACE_UNUSED_ARG (msg
);
336 ACE_UNUSED_ARG (flags
);
337 ACE_UNUSED_ARG (bytes_sent
);
338 ACE_NOTSUP_RETURN (-1);
343 ACE_END_VERSIONED_NAMESPACE_DECL