summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2014-10-19 20:22:58 (GMT)
committerTobias Markmann <tm@ayena.de>2014-10-20 13:49:33 (GMT)
commit6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch)
tree2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
parent38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff)
downloadswift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.zip
swift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.tar.bz2
Update Boost in 3rdParty to version 1.56.0.
This updates Boost in our 3rdParty directory to version 1.56.0. Updated our update.sh script to stop on error. Changed error reporting in SwiftTools/CrashReporter.cpp to SWIFT_LOG due to missing include of <iostream> with newer Boost. Change-Id: I4b35c77de951333979a524097f35f5f83d325edc
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp')
-rw-r--r--3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp85
1 files changed, 79 insertions, 6 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
index 0466e33..40231b9 100644
--- a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
+++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_iocp_socket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -32,6 +32,7 @@ win_iocp_socket_service_base::win_iocp_socket_service_base(
: io_service_(io_service),
iocp_service_(use_service<win_iocp_io_service>(io_service)),
reactor_(0),
+ connect_ex_(0),
mutex_(),
impl_list_(0)
{
@@ -534,19 +535,62 @@ void win_iocp_socket_service_base::start_reactor_op(
if (is_open(impl))
{
- r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false);
+ r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false, false);
return;
}
else
op->ec_ = boost::asio::error::bad_descriptor;
- iocp_service_.post_immediate_completion(op);
+ iocp_service_.post_immediate_completion(op, false);
}
void win_iocp_socket_service_base::start_connect_op(
win_iocp_socket_service_base::base_implementation_type& impl,
- reactor_op* op, const socket_addr_type* addr, std::size_t addrlen)
+ int family, int type, const socket_addr_type* addr,
+ std::size_t addrlen, win_iocp_socket_connect_op_base* op)
{
+ // If ConnectEx is available, use that.
+ if (family == BOOST_ASIO_OS_DEF(AF_INET)
+ || family == BOOST_ASIO_OS_DEF(AF_INET6))
+ {
+ if (connect_ex_fn connect_ex = get_connect_ex(impl, type))
+ {
+ union address_union
+ {
+ socket_addr_type base;
+ sockaddr_in4_type v4;
+ sockaddr_in6_type v6;
+ } a;
+
+ using namespace std; // For memset.
+ memset(&a, 0, sizeof(a));
+ a.base.sa_family = family;
+
+ socket_ops::bind(impl.socket_, &a.base,
+ family == BOOST_ASIO_OS_DEF(AF_INET)
+ ? sizeof(a.v4) : sizeof(a.v6), op->ec_);
+ if (op->ec_ && op->ec_ != boost::asio::error::invalid_argument)
+ {
+ iocp_service_.post_immediate_completion(op, false);
+ return;
+ }
+
+ op->connect_ex_ = true;
+ update_cancellation_thread_id(impl);
+ iocp_service_.work_started();
+
+ BOOL result = connect_ex(impl.socket_,
+ addr, static_cast<int>(addrlen), 0, 0, 0, op);
+ DWORD last_error = ::WSAGetLastError();
+ if (!result && last_error != WSA_IO_PENDING)
+ iocp_service_.on_completion(op, last_error);
+ else
+ iocp_service_.on_pending(op);
+ return;
+ }
+ }
+
+ // Otherwise, fall back to a reactor-based implementation.
reactor& r = get_reactor();
update_cancellation_thread_id(impl);
@@ -561,13 +605,13 @@ void win_iocp_socket_service_base::start_connect_op(
{
op->ec_ = boost::system::error_code();
r.start_op(reactor::connect_op, impl.socket_,
- impl.reactor_data_, op, false);
+ impl.reactor_data_, op, false, false);
return;
}
}
}
- r.post_immediate_completion(op);
+ r.post_immediate_completion(op, false);
}
void win_iocp_socket_service_base::close_for_destruction(
@@ -623,6 +667,35 @@ reactor& win_iocp_socket_service_base::get_reactor()
return *r;
}
+win_iocp_socket_service_base::connect_ex_fn
+win_iocp_socket_service_base::get_connect_ex(
+ win_iocp_socket_service_base::base_implementation_type& impl, int type)
+{
+ if (type != BOOST_ASIO_OS_DEF(SOCK_STREAM)
+ && type != BOOST_ASIO_OS_DEF(SOCK_SEQPACKET))
+ return 0;
+
+ void* ptr = interlocked_compare_exchange_pointer(&connect_ex_, 0, 0);
+ if (!ptr)
+ {
+ GUID guid = { 0x25a207b9, 0xddf3, 0x4660,
+ { 0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e } };
+
+ DWORD bytes = 0;
+ if (::WSAIoctl(impl.socket_, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guid, sizeof(guid), &ptr, sizeof(ptr), &bytes, 0, 0) != 0)
+ {
+ // Set connect_ex_ to a special value to indicate that ConnectEx is
+ // unavailable. That way we won't bother trying to look it up again.
+ ptr = this;
+ }
+
+ interlocked_exchange_pointer(&connect_ex_, ptr);
+ }
+
+ return reinterpret_cast<connect_ex_fn>(ptr == this ? 0 : ptr);
+}
+
void* win_iocp_socket_service_base::interlocked_compare_exchange_pointer(
void** dest, void* exch, void* cmp)
{