diff options
author | Tobias Markmann <tm@ayena.de> | 2014-10-19 20:22:58 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2014-10-20 13:49:33 (GMT) |
commit | 6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch) | |
tree | 2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/boost/asio/detail/impl | |
parent | 38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff) | |
download | swift-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')
48 files changed, 2164 insertions, 772 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/buffer_sequence_adapter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/buffer_sequence_adapter.ipp new file mode 100644 index 0000000..a538134 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/buffer_sequence_adapter.ipp @@ -0,0 +1,120 @@ +// +// detail/impl/buffer_sequence_adapter.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP +#define BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include <robuffer.h> +#include <windows.storage.streams.h> +#include <wrl/implements.h> +#include <boost/asio/detail/buffer_sequence_adapter.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +class winrt_buffer_impl : + public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>, + ABI::Windows::Storage::Streams::IBuffer, + Windows::Storage::Streams::IBufferByteAccess> +{ +public: + explicit winrt_buffer_impl(const boost::asio::const_buffer& b) + { + bytes_ = const_cast<byte*>(boost::asio::buffer_cast<const byte*>(b)); + length_ = boost::asio::buffer_size(b); + capacity_ = boost::asio::buffer_size(b); + } + + explicit winrt_buffer_impl(const boost::asio::mutable_buffer& b) + { + bytes_ = const_cast<byte*>(boost::asio::buffer_cast<const byte*>(b)); + length_ = 0; + capacity_ = boost::asio::buffer_size(b); + } + + ~winrt_buffer_impl() + { + } + + STDMETHODIMP Buffer(byte** value) + { + *value = bytes_; + return S_OK; + } + + STDMETHODIMP get_Capacity(UINT32* value) + { + *value = capacity_; + return S_OK; + } + + STDMETHODIMP get_Length(UINT32 *value) + { + *value = length_; + return S_OK; + } + + STDMETHODIMP put_Length(UINT32 value) + { + if (value > capacity_) + return E_INVALIDARG; + length_ = value; + return S_OK; + } + +private: + byte* bytes_; + UINT32 length_; + UINT32 capacity_; +}; + +void buffer_sequence_adapter_base::init_native_buffer( + buffer_sequence_adapter_base::native_buffer_type& buf, + const boost::asio::mutable_buffer& buffer) +{ + std::memset(&buf, 0, sizeof(native_buffer_type)); + Microsoft::WRL::ComPtr<IInspectable> insp + = Microsoft::WRL::Make<winrt_buffer_impl>(buffer); + buf = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(insp.Get()); +} + +void buffer_sequence_adapter_base::init_native_buffer( + buffer_sequence_adapter_base::native_buffer_type& buf, + const boost::asio::const_buffer& buffer) +{ + std::memset(&buf, 0, sizeof(native_buffer_type)); + Microsoft::WRL::ComPtr<IInspectable> insp + = Microsoft::WRL::Make<winrt_buffer_impl>(buffer); + Platform::Object^ buf_obj = reinterpret_cast<Platform::Object^>(insp.Get()); + buf = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(insp.Get()); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp index 6c3528f..54b8537 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/descriptor_ops.ipp @@ -2,7 +2,7 @@ // detail/impl/descriptor_ops.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) @@ -20,7 +20,9 @@ #include <boost/asio/detail/descriptor_ops.hpp> #include <boost/asio/error.hpp> -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) #include <boost/asio/detail/push_options.hpp> @@ -183,7 +185,8 @@ std::size_t sync_read(int d, state_type state, buf* bufs, { // Try to complete the operation without blocking. errno = 0; - int bytes = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); + signed_size_type bytes = error_wrapper(::readv( + d, bufs, static_cast<int>(count)), ec); // Check if operation succeeded. if (bytes > 0) @@ -215,7 +218,8 @@ bool non_blocking_read(int d, buf* bufs, std::size_t count, { // Read some data. errno = 0; - int bytes = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec); + signed_size_type bytes = error_wrapper(::readv( + d, bufs, static_cast<int>(count)), ec); // Check for end of stream. if (bytes == 0) @@ -267,7 +271,8 @@ std::size_t sync_write(int d, state_type state, const buf* bufs, { // Try to complete the operation without blocking. errno = 0; - int bytes = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); + signed_size_type bytes = error_wrapper(::writev( + d, bufs, static_cast<int>(count)), ec); // Check if operation succeeded. if (bytes > 0) @@ -292,7 +297,8 @@ bool non_blocking_write(int d, const buf* bufs, std::size_t count, { // Write some data. errno = 0; - int bytes = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec); + signed_size_type bytes = error_wrapper(::writev( + d, bufs, static_cast<int>(count)), ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -357,7 +363,7 @@ int ioctl(int d, state_type& state, long cmd, return result; } -int fcntl(int d, long cmd, boost::system::error_code& ec) +int fcntl(int d, int cmd, boost::system::error_code& ec) { if (d == -1) { @@ -372,7 +378,7 @@ int fcntl(int d, long cmd, boost::system::error_code& ec) return result; } -int fcntl(int d, long cmd, long arg, boost::system::error_code& ec) +int fcntl(int d, int cmd, long arg, boost::system::error_code& ec) { if (d == -1) { @@ -440,6 +446,8 @@ int poll_write(int d, state_type state, boost::system::error_code& ec) #include <boost/asio/detail/pop_options.hpp> -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) #endif // BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp index 12860af..1c02ea4 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.hpp @@ -2,7 +2,7 @@ // detail/impl/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) @@ -46,7 +46,7 @@ void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue, if (shutdown_) { - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, false); return; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp index a648bf1..cc5b401 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/dev_poll_reactor.ipp @@ -2,7 +2,7 @@ // detail/impl/dev_poll_reactor.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) @@ -19,8 +19,8 @@ #if defined(BOOST_ASIO_HAS_DEV_POLL) -#include <boost/assert.hpp> #include <boost/asio/detail/dev_poll_reactor.hpp> +#include <boost/asio/detail/assert.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> @@ -122,7 +122,7 @@ void dev_poll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev) // The ops op_queue will always be empty because the fork_helper's set() // member function never returns false. - BOOST_ASSERT(ops.empty()); + BOOST_ASIO_ASSERT(ops.empty()); } } @@ -163,14 +163,14 @@ void dev_poll_reactor::move_descriptor(socket_type, } void dev_poll_reactor::start_op(int op_type, socket_type descriptor, - dev_poll_reactor::per_descriptor_data&, - reactor_op* op, bool allow_speculative) + dev_poll_reactor::per_descriptor_data&, reactor_op* op, + bool is_continuation, bool allow_speculative) { boost::asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { - post_immediate_completion(op); + post_immediate_completion(op, is_continuation); return; } @@ -183,7 +183,7 @@ void dev_poll_reactor::start_op(int op_type, socket_type descriptor, if (op->perform()) { lock.unlock(); - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, is_continuation); return; } } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp index 215f484..3a08f8e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.hpp @@ -2,7 +2,7 @@ // detail/impl/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) @@ -44,7 +44,7 @@ void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue, if (shutdown_) { - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, false); return; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp index 073bd08..27408e4 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/epoll_reactor.ipp @@ -2,7 +2,7 @@ // detail/impl/epoll_reactor.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) @@ -204,13 +204,13 @@ void epoll_reactor::move_descriptor(socket_type, } void epoll_reactor::start_op(int op_type, socket_type descriptor, - epoll_reactor::per_descriptor_data& descriptor_data, - reactor_op* op, bool allow_speculative) + epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op, + bool is_continuation, bool allow_speculative) { if (!descriptor_data) { op->ec_ = boost::asio::error::bad_descriptor; - post_immediate_completion(op); + post_immediate_completion(op, is_continuation); return; } @@ -218,7 +218,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor, if (descriptor_data->shutdown_) { - post_immediate_completion(op); + post_immediate_completion(op, is_continuation); return; } @@ -231,7 +231,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor, if (op->perform()) { descriptor_lock.unlock(); - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, is_continuation); return; } @@ -250,7 +250,7 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor, { op->ec_ = boost::system::error_code(errno, boost::asio::error::get_system_category()); - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, is_continuation); return; } } @@ -607,8 +607,9 @@ epoll_reactor::descriptor_state::descriptor_state() operation* epoll_reactor::descriptor_state::perform_io(uint32_t events) { + mutex_.lock(); perform_io_cleanup_on_block_exit io_cleanup(reactor_); - mutex::scoped_lock descriptor_lock(mutex_); + mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock); // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp index 22154bb..c5a673a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/eventfd_select_interrupter.ipp @@ -2,7 +2,7 @@ // detail/impl/eventfd_select_interrupter.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) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -28,6 +28,7 @@ #else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 # include <sys/eventfd.h> #endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8 +#include <boost/asio/detail/cstdint.hpp> #include <boost/asio/detail/eventfd_select_interrupter.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/handler_tracking.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/handler_tracking.ipp index 70342e3..2c84e5a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/handler_tracking.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/handler_tracking.ipp @@ -2,7 +2,7 @@ // detail/impl/handler_tracking.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) @@ -23,13 +23,21 @@ #include <cstdio> #include <boost/asio/detail/handler_tracking.hpp> -#include <boost/asio/detail/push_options.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <boost/asio/detail/pop_options.hpp> - -#if !defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) +# include <boost/asio/time_traits.hpp> +#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) +# if defined(BOOST_ASIO_HAS_STD_CHRONO) +# include <chrono> +# elif defined(BOOST_ASIO_HAS_BOOST_CHRONO) +# include <boost/chrono/system_clocks.hpp> +# endif +# include <boost/asio/detail/chrono_time_traits.hpp> +# include <boost/asio/wait_traits.hpp> +#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + +#if !defined(BOOST_ASIO_WINDOWS) # include <unistd.h> -#endif // !defined(BOOST_WINDOWS) +#endif // !defined(BOOST_ASIO_WINDOWS) #include <boost/asio/detail/push_options.hpp> @@ -37,10 +45,37 @@ namespace boost { namespace asio { namespace detail { +struct handler_tracking_timestamp +{ + uint64_t seconds; + uint64_t microseconds; + + handler_tracking_timestamp() + { +#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); + boost::posix_time::time_duration now = + boost::posix_time::microsec_clock::universal_time() - epoch; +#elif defined(BOOST_ASIO_HAS_STD_CHRONO) + typedef chrono_time_traits<std::chrono::system_clock, + boost::asio::wait_traits<std::chrono::system_clock> > traits_helper; + traits_helper::posix_time_duration now( + std::chrono::system_clock::now().time_since_epoch()); +#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO) + typedef chrono_time_traits<boost::chrono::system_clock, + boost::asio::wait_traits<boost::chrono::system_clock> > traits_helper; + traits_helper::posix_time_duration now( + boost::chrono::system_clock::now().time_since_epoch()); +#endif + seconds = static_cast<uint64_t>(now.total_seconds()); + microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000); + } +}; + struct handler_tracking::tracking_state { static_mutex mutex_; - boost::uint64_t next_id_; + uint64_t next_id_; tss_ptr<completion>* current_completion_; }; @@ -70,22 +105,19 @@ void handler_tracking::creation(handler_tracking::tracked_handler* h, h->id_ = state->next_id_++; lock.unlock(); - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; - boost::uint64_t current_id = 0; + uint64_t current_id = 0; if (completion* current_completion = *state->current_completion_) current_id = current_completion->id_; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|%I64u*%I64u|%.20s@%p.%.50s\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|%llu*%llu|%.20s@%p.%.50s\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, current_id, h->id_, object_type, object, op_name); } @@ -101,18 +133,15 @@ handler_tracking::completion::~completion() { if (id_) { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|%c%I64u|\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|%c%llu|\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, invoked_ ? '!' : '~', id_); } @@ -121,18 +150,15 @@ handler_tracking::completion::~completion() void handler_tracking::completion::invocation_begin() { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), id_); +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, id_); invoked_ = true; } @@ -140,18 +166,15 @@ void handler_tracking::completion::invocation_begin() void handler_tracking::completion::invocation_begin( const boost::system::error_code& ec) { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value()); invoked_ = true; @@ -160,20 +183,17 @@ void handler_tracking::completion::invocation_begin( void handler_tracking::completion::invocation_begin( const boost::system::error_code& ec, std::size_t bytes_transferred) { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,bytes_transferred=%I64u\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,bytes_transferred=%llu\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value(), - static_cast<boost::uint64_t>(bytes_transferred)); + static_cast<uint64_t>(bytes_transferred)); invoked_ = true; } @@ -181,18 +201,15 @@ void handler_tracking::completion::invocation_begin( void handler_tracking::completion::invocation_begin( const boost::system::error_code& ec, int signal_number) { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,signal_number=%d\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,signal_number=%d\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value(), signal_number); invoked_ = true; @@ -201,18 +218,15 @@ void handler_tracking::completion::invocation_begin( void handler_tracking::completion::invocation_begin( const boost::system::error_code& ec, const char* arg) { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,%.50s\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,%.50s\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, id_, ec.category().name(), ec.value(), arg); invoked_ = true; @@ -222,18 +236,15 @@ void handler_tracking::completion::invocation_end() { if (id_) { - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|<%I64u|\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|<%llu|\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), id_); +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, id_); id_ = 0; } @@ -244,22 +255,19 @@ void handler_tracking::operation(const char* object_type, { static tracking_state* state = get_state(); - boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - boost::posix_time::time_duration now = - boost::posix_time::microsec_clock::universal_time() - epoch; + handler_tracking_timestamp timestamp; unsigned long long current_id = 0; if (completion* current_completion = *state->current_completion_) current_id = current_completion->id_; write_line( -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) "@asio|%I64u.%06I64u|%I64u|%.20s@%p.%.50s\n", -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) "@asio|%llu.%06llu|%llu|%.20s@%p.%.50s\n", -#endif // defined(BOOST_WINDOWS) - static_cast<boost::uint64_t>(now.total_seconds()), - static_cast<boost::uint64_t>(now.total_microseconds() % 1000000), +#endif // defined(BOOST_ASIO_WINDOWS) + timestamp.seconds, timestamp.microseconds, current_id, object_type, object, op_name); } @@ -271,21 +279,21 @@ void handler_tracking::write_line(const char* format, ...) va_start(args, format); char line[256] = ""; -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) int length = vsprintf_s(line, sizeof(line), format, args); -#else // BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) int length = vsprintf(line, format, args); -#endif // BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) va_end(args); -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) HANDLE stderr_handle = ::GetStdHandle(STD_ERROR_HANDLE); DWORD bytes_written = 0; ::WriteFile(stderr_handle, line, length, &bytes_written, 0); -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) ::write(STDERR_FILENO, line, length); -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) } } // namespace detail diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp index d3445cd..889ae26 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.hpp @@ -2,7 +2,7 @@ // detail/impl/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -48,7 +48,7 @@ void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue, if (shutdown_) { - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, false); return; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp index a819eb9..7a026a9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/kqueue_reactor.ipp @@ -2,7 +2,7 @@ // detail/impl/kqueue_reactor.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) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -47,10 +47,15 @@ kqueue_reactor::kqueue_reactor(boost::asio::io_service& io_service) interrupter_(), shutdown_(false) { - // The interrupter is put into a permanently readable state. Whenever we want - // to interrupt the blocked kevent call we register a read operation against - // the descriptor. - interrupter_.interrupt(); + struct kevent event; + BOOST_ASIO_KQUEUE_EV_SET(&event, interrupter_.read_descriptor(), + EVFILT_READ, EV_ADD, 0, 0, &interrupter_); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code error(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(error); + } } kqueue_reactor::~kqueue_reactor() @@ -89,26 +94,27 @@ void kqueue_reactor::fork_service(boost::asio::io_service::fork_event fork_ev) interrupter_.recreate(); + struct kevent event; + BOOST_ASIO_KQUEUE_EV_SET(&event, interrupter_.read_descriptor(), + EVFILT_READ, EV_ADD, 0, 0, &interrupter_); + if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) + { + boost::system::error_code error(errno, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(error); + } + // Re-register all descriptors with kqueue. mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_); for (descriptor_state* state = registered_descriptors_.first(); state != 0; state = state->next_) { struct kevent events[2]; - int num_events = 0; - - if (!state->op_queue_[read_op].empty()) - BOOST_ASIO_KQUEUE_EV_SET(&events[num_events++], state->descriptor_, - EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, state); - else if (!state->op_queue_[except_op].empty()) - BOOST_ASIO_KQUEUE_EV_SET(&events[num_events++], state->descriptor_, - EVFILT_READ, EV_ADD | EV_CLEAR, EV_OOBAND, 0, state); - - if (!state->op_queue_[write_op].empty()) - BOOST_ASIO_KQUEUE_EV_SET(&events[num_events++], state->descriptor_, - EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, state); - - if (num_events && ::kevent(kqueue_fd_, events, num_events, 0, 0, 0) == -1) + BOOST_ASIO_KQUEUE_EV_SET(&events[0], state->descriptor_, + EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, state); + BOOST_ASIO_KQUEUE_EV_SET(&events[1], state->descriptor_, + EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, state); + if (::kevent(kqueue_fd_, events, 2, 0, 0, 0) == -1) { boost::system::error_code error(errno, boost::asio::error::get_system_category()); @@ -133,6 +139,14 @@ int kqueue_reactor::register_descriptor(socket_type descriptor, descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; + struct kevent events[2]; + BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, + EV_ADD | EV_CLEAR, 0, 0, descriptor_data); + BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, + EV_ADD | EV_CLEAR, 0, 0, descriptor_data); + if (::kevent(kqueue_fd_, events, 2, 0, 0, 0) == -1) + return errno; + return 0; } @@ -148,23 +162,13 @@ int kqueue_reactor::register_internal_descriptor( descriptor_data->shutdown_ = false; descriptor_data->op_queue_[op_type].push(op); - struct kevent event; - switch (op_type) - { - case read_op: - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_CLEAR, 0, 0, descriptor_data); - break; - case write_op: - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE, - EV_ADD | EV_CLEAR, 0, 0, descriptor_data); - break; - case except_op: - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_CLEAR, EV_OOBAND, 0, descriptor_data); - break; - } - ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); + struct kevent events[2]; + BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, + EV_ADD | EV_CLEAR, 0, 0, descriptor_data); + BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, + EV_ADD | EV_CLEAR, 0, 0, descriptor_data); + if (::kevent(kqueue_fd_, events, 2, 0, 0, 0) == -1) + return errno; return 0; } @@ -178,13 +182,13 @@ void kqueue_reactor::move_descriptor(socket_type, } void kqueue_reactor::start_op(int op_type, socket_type descriptor, - kqueue_reactor::per_descriptor_data& descriptor_data, - reactor_op* op, bool allow_speculative) + kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op, + bool is_continuation, bool allow_speculative) { if (!descriptor_data) { op->ec_ = boost::asio::error::bad_descriptor; - post_immediate_completion(op); + post_immediate_completion(op, is_continuation); return; } @@ -192,59 +196,37 @@ void kqueue_reactor::start_op(int op_type, socket_type descriptor, if (descriptor_data->shutdown_) { - post_immediate_completion(op); + post_immediate_completion(op, is_continuation); return; } bool first = descriptor_data->op_queue_[op_type].empty(); if (first) { - if (allow_speculative) + if (allow_speculative + && (op_type != read_op + || descriptor_data->op_queue_[except_op].empty())) { - if (op_type != read_op || descriptor_data->op_queue_[except_op].empty()) + if (op->perform()) { - if (op->perform()) - { - descriptor_lock.unlock(); - io_service_.post_immediate_completion(op); - return; - } + descriptor_lock.unlock(); + io_service_.post_immediate_completion(op, is_continuation); + return; } } - } - - descriptor_data->op_queue_[op_type].push(op); - io_service_.work_started(); - - if (first) - { - struct kevent event; - switch (op_type) + else { - case read_op: - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, + struct kevent events[2]; + BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); - break; - case write_op: - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE, + BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, descriptor_data); - break; - case except_op: - if (!descriptor_data->op_queue_[read_op].empty()) - return; // Already registered for read events. - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_CLEAR, EV_OOBAND, 0, descriptor_data); - break; - } - - if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) - { - op->ec_ = boost::system::error_code(errno, - boost::asio::error::get_system_category()); - descriptor_data->op_queue_[op_type].pop(); - io_service_.post_deferred_completion(op); + ::kevent(kqueue_fd_, events, 2, 0, 0, 0); } } + + descriptor_data->op_queue_[op_type].push(op); + io_service_.work_started(); } void kqueue_reactor::cancel_ops(socket_type, @@ -367,12 +349,10 @@ void kqueue_reactor::run(bool block, op_queue<operation>& ops) // Dispatch the waiting events. for (int i = 0; i < num_events; ++i) { - int descriptor = events[i].ident; void* ptr = reinterpret_cast<void*>(events[i].udata); if (ptr == &interrupter_) { - // No need to reset the interrupter since we're leaving the descriptor - // in a ready-to-read state and relying on edge-triggered notifications. + interrupter_.reset(); } else { @@ -397,7 +377,8 @@ void kqueue_reactor::run(bool block, op_queue<operation>& ops) { if (events[i].flags & EV_ERROR) { - op->ec_ = boost::system::error_code(events[i].data, + op->ec_ = boost::system::error_code( + static_cast<int>(events[i].data), boost::asio::error::get_system_category()); descriptor_data->op_queue_[j].pop(); ops.push(op); @@ -413,45 +394,6 @@ void kqueue_reactor::run(bool block, op_queue<operation>& ops) } } } - - // Renew registration for event notifications. - struct kevent event; - switch (events[i].filter) - { - case EVFILT_READ: - if (!descriptor_data->op_queue_[read_op].empty()) - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_CLEAR, 0, 0, descriptor_data); - else if (!descriptor_data->op_queue_[except_op].empty()) - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_READ, - EV_ADD | EV_CLEAR, EV_OOBAND, 0, descriptor_data); - else - continue; - break; - case EVFILT_WRITE: - if (!descriptor_data->op_queue_[write_op].empty()) - BOOST_ASIO_KQUEUE_EV_SET(&event, descriptor, EVFILT_WRITE, - EV_ADD | EV_CLEAR, 0, 0, descriptor_data); - else - continue; - break; - default: - break; - } - if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1) - { - boost::system::error_code error(errno, - boost::asio::error::get_system_category()); - for (int j = 0; j < max_ops; ++j) - { - while (reactor_op* op = descriptor_data->op_queue_[j].front()) - { - op->ec_ = error; - descriptor_data->op_queue_[j].pop(); - ops.push(op); - } - } - } } } @@ -461,10 +403,7 @@ void kqueue_reactor::run(bool block, op_queue<operation>& ops) void kqueue_reactor::interrupt() { - struct kevent event; - BOOST_ASIO_KQUEUE_EV_SET(&event, interrupter_.read_descriptor(), - EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &interrupter_); - ::kevent(kqueue_fd_, &event, 1, 0, 0, 0); + interrupter_.interrupt(); } int kqueue_reactor::do_kqueue_create() diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp index 75a8d16..556c5a2 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/pipe_select_interrupter.ipp @@ -2,7 +2,7 @@ // detail/impl/pipe_select_interrupter.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) @@ -17,7 +17,8 @@ #include <boost/asio/detail/config.hpp> -#if !defined(BOOST_WINDOWS) +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) +#if !defined(BOOST_ASIO_WINDOWS) #if !defined(__CYGWIN__) #if !defined(__SYMBIAN32__) #if !defined(BOOST_ASIO_HAS_EVENTFD) @@ -27,6 +28,7 @@ #include <sys/types.h> #include <unistd.h> #include <boost/asio/detail/pipe_select_interrupter.hpp> +#include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> @@ -90,7 +92,7 @@ void pipe_select_interrupter::recreate() void pipe_select_interrupter::interrupt() { char byte = 0; - int result = ::write(write_descriptor_, &byte, 1); + signed_size_type result = ::write(write_descriptor_, &byte, 1); (void)result; } @@ -99,7 +101,7 @@ bool pipe_select_interrupter::reset() for (;;) { char data[1024]; - int bytes_read = ::read(read_descriptor_, data, sizeof(data)); + signed_size_type bytes_read = ::read(read_descriptor_, data, sizeof(data)); if (bytes_read < 0 && errno == EINTR) continue; bool was_interrupted = (bytes_read > 0); @@ -118,6 +120,7 @@ bool pipe_select_interrupter::reset() #endif // !defined(BOOST_ASIO_HAS_EVENTFD) #endif // !defined(__SYMBIAN32__) #endif // !defined(__CYGWIN__) -#endif // !defined(BOOST_WINDOWS) +#endif // !defined(BOOST_ASIO_WINDOWS) +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) #endif // BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp index 08eae05..acb0f57 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_event.ipp @@ -2,7 +2,7 @@ // detail/impl/posix_event.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) @@ -17,10 +17,11 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) #include <boost/asio/detail/posix_event.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/error.hpp> #include <boost/asio/detail/push_options.hpp> @@ -29,7 +30,7 @@ namespace asio { namespace detail { posix_event::posix_event() - : signalled_(false) + : state_(0) { int error = ::pthread_cond_init(&cond_, 0); boost::system::error_code ec(error, @@ -43,6 +44,6 @@ posix_event::posix_event() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) #endif // BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp index 94b9bf4..d815512 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_mutex.ipp @@ -2,7 +2,7 @@ // detail/impl/posix_mutex.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) #include <boost/asio/detail/posix_mutex.hpp> #include <boost/asio/detail/throw_error.hpp> @@ -43,6 +43,6 @@ posix_mutex::posix_mutex() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) #endif // BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp index 0c52971..4b487d9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_thread.ipp @@ -2,7 +2,7 @@ // detail/impl/posix_thread.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) #include <boost/asio/detail/posix_thread.hpp> #include <boost/asio/detail/throw_error.hpp> @@ -71,6 +71,6 @@ void* boost_asio_detail_posix_thread_function(void* arg) #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) #endif // BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp index 5124c5f..65f9077 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/posix_tss_ptr.ipp @@ -2,7 +2,7 @@ // detail/impl/posix_tss_ptr.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) #include <boost/asio/detail/posix_tss_ptr.hpp> #include <boost/asio/detail/throw_error.hpp> @@ -43,6 +43,6 @@ void posix_tss_ptr_create(pthread_key_t& key) #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) #endif // BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp index dff0a82..abf4c6f 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_descriptor_service.ipp @@ -2,7 +2,7 @@ // detail/impl/reactive_descriptor_service.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) @@ -17,7 +17,9 @@ #include <boost/asio/detail/config.hpp> -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) #include <boost/asio/error.hpp> #include <boost/asio/detail/reactive_descriptor_service.hpp> @@ -177,7 +179,8 @@ boost::system::error_code reactive_descriptor_service::cancel( void reactive_descriptor_service::start_op( reactive_descriptor_service::implementation_type& impl, - int op_type, reactor_op* op, bool is_non_blocking, bool noop) + int op_type, reactor_op* op, bool is_continuation, + bool is_non_blocking, bool noop) { if (!noop) { @@ -186,12 +189,12 @@ void reactive_descriptor_service::start_op( impl.descriptor_, impl.state_, true, op->ec_)) { reactor_.start_op(op_type, impl.descriptor_, - impl.reactor_data_, op, is_non_blocking); + impl.reactor_data_, op, is_continuation, is_non_blocking); return; } } - reactor_.post_immediate_completion(op); + reactor_.post_immediate_completion(op, is_continuation); } } // namespace detail @@ -200,6 +203,8 @@ void reactive_descriptor_service::start_op( #include <boost/asio/detail/pop_options.hpp> -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) #endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp index 0f530d7..b8c2f4a 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_serial_port_service.ipp @@ -2,7 +2,7 @@ // detail/impl/reactive_serial_port_service.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) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -19,7 +19,7 @@ #include <boost/asio/detail/config.hpp> #if defined(BOOST_ASIO_HAS_SERIAL_PORT) -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) #include <cstring> #include <boost/asio/detail/reactive_serial_port_service.hpp> @@ -147,7 +147,7 @@ boost::system::error_code reactive_serial_port_service::do_get_option( #include <boost/asio/detail/pop_options.hpp> -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) #endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp index 93277e0..c72871d 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/reactive_socket_service_base.ipp @@ -2,7 +2,7 @@ // detail/reactive_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) @@ -17,7 +17,8 @@ #include <boost/asio/detail/config.hpp> -#if !defined(BOOST_ASIO_HAS_IOCP) +#if !defined(BOOST_ASIO_HAS_IOCP) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) #include <boost/asio/detail/reactive_socket_service_base.hpp> @@ -200,7 +201,8 @@ boost::system::error_code reactive_socket_service_base::do_assign( void reactive_socket_service_base::start_op( reactive_socket_service_base::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_non_blocking, bool noop) + int op_type, reactor_op* op, bool is_continuation, + bool is_non_blocking, bool noop) { if (!noop) { @@ -209,30 +211,31 @@ void reactive_socket_service_base::start_op( impl.socket_, impl.state_, true, op->ec_)) { reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_non_blocking); + impl.reactor_data_, op, is_continuation, is_non_blocking); return; } } - reactor_.post_immediate_completion(op); + reactor_.post_immediate_completion(op, is_continuation); } void reactive_socket_service_base::start_accept_op( reactive_socket_service_base::base_implementation_type& impl, - reactor_op* op, bool peer_is_open) + reactor_op* op, bool is_continuation, bool peer_is_open) { if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, false); + start_op(impl, reactor::read_op, op, true, is_continuation, false); else { op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op); + reactor_.post_immediate_completion(op, is_continuation); } } void reactive_socket_service_base::start_connect_op( reactive_socket_service_base::base_implementation_type& impl, - reactor_op* op, const socket_addr_type* addr, size_t addrlen) + reactor_op* op, bool is_continuation, + const socket_addr_type* addr, size_t addrlen) { if ((impl.state_ & socket_ops::non_blocking) || socket_ops::set_internal_non_blocking( @@ -244,14 +247,14 @@ void reactive_socket_service_base::start_connect_op( || op->ec_ == boost::asio::error::would_block) { op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, - impl.socket_, impl.reactor_data_, op, false); + reactor_.start_op(reactor::connect_op, impl.socket_, + impl.reactor_data_, op, is_continuation, false); return; } } } - reactor_.post_immediate_completion(op); + reactor_.post_immediate_completion(op, is_continuation); } } // namespace detail @@ -261,5 +264,6 @@ void reactive_socket_service_base::start_connect_op( #include <boost/asio/detail/pop_options.hpp> #endif // !defined(BOOST_ASIO_HAS_IOCP) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) #endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp index 6a384e4..77b6c27 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/resolver_service_base.ipp @@ -2,7 +2,7 @@ // detail/impl/resolver_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) @@ -110,7 +110,7 @@ void resolver_service_base::start_resolve_op(operation* op) { start_work_thread(); io_service_impl_.work_started(); - work_io_service_impl_.post_immediate_completion(op); + work_io_service_impl_.post_immediate_completion(op, false); } void resolver_service_base::start_work_thread() diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp index 0d4097e..f2b79f7 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.hpp @@ -2,7 +2,7 @@ // detail/impl/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) @@ -20,7 +20,8 @@ #if defined(BOOST_ASIO_HAS_IOCP) \ || (!defined(BOOST_ASIO_HAS_DEV_POLL) \ && !defined(BOOST_ASIO_HAS_EPOLL) \ - && !defined(BOOST_ASIO_HAS_KQUEUE)) + && !defined(BOOST_ASIO_HAS_KQUEUE) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME)) #include <boost/asio/detail/push_options.hpp> @@ -50,7 +51,7 @@ void select_reactor::schedule_timer(timer_queue<Time_Traits>& queue, if (shutdown_) { - io_service_.post_immediate_completion(op); + io_service_.post_immediate_completion(op, false); return; } @@ -82,6 +83,7 @@ std::size_t select_reactor::cancel_timer(timer_queue<Time_Traits>& queue, #endif // defined(BOOST_ASIO_HAS_IOCP) // || (!defined(BOOST_ASIO_HAS_DEV_POLL) // && !defined(BOOST_ASIO_HAS_EPOLL) - // && !defined(BOOST_ASIO_HAS_KQUEUE)) + // && !defined(BOOST_ASIO_HAS_KQUEUE) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)) #endif // BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp index d11904e..c8e04a2 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/select_reactor.ipp @@ -2,7 +2,7 @@ // detail/impl/select_reactor.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) @@ -20,7 +20,8 @@ #if defined(BOOST_ASIO_HAS_IOCP) \ || (!defined(BOOST_ASIO_HAS_DEV_POLL) \ && !defined(BOOST_ASIO_HAS_EPOLL) \ - && !defined(BOOST_ASIO_HAS_KQUEUE)) + && !defined(BOOST_ASIO_HAS_KQUEUE) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME)) #include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/fd_set_adapter.hpp> @@ -122,13 +123,14 @@ void select_reactor::move_descriptor(socket_type, } void select_reactor::start_op(int op_type, socket_type descriptor, - select_reactor::per_descriptor_data&, reactor_op* op, bool) + select_reactor::per_descriptor_data&, reactor_op* op, + bool is_continuation, bool) { boost::asio::detail::mutex::scoped_lock lock(mutex_); if (shutdown_) { - post_immediate_completion(op); + post_immediate_completion(op, is_continuation); return; } @@ -180,21 +182,21 @@ void select_reactor::run(bool block, op_queue<operation>& ops) for (int i = 0; i < max_select_ops; ++i) { have_work_to_do = have_work_to_do || !op_queue_[i].empty(); - op_queue_[i].get_descriptors(fd_sets_[i], ops); + fd_sets_[i].set(op_queue_[i], ops); if (fd_sets_[i].max_descriptor() > max_fd) max_fd = fd_sets_[i].max_descriptor(); } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Connection operations on Windows use both except and write fd_sets. have_work_to_do = have_work_to_do || !op_queue_[connect_op].empty(); - op_queue_[connect_op].get_descriptors(fd_sets_[write_op], ops); + fd_sets_[write_op].set(op_queue_[connect_op], ops); if (fd_sets_[write_op].max_descriptor() > max_fd) max_fd = fd_sets_[write_op].max_descriptor(); - op_queue_[connect_op].get_descriptors(fd_sets_[except_op], ops); + fd_sets_[except_op].set(op_queue_[connect_op], ops); if (fd_sets_[except_op].max_descriptor() > max_fd) max_fd = fd_sets_[except_op].max_descriptor(); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // We can return immediately if there's no work to do and the reactor is // not supposed to block. @@ -224,18 +226,16 @@ void select_reactor::run(bool block, op_queue<operation>& ops) // Dispatch all ready operations. if (retval > 0) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Connection operations on Windows use both except and write fd_sets. - op_queue_[connect_op].perform_operations_for_descriptors( - fd_sets_[except_op], ops); - op_queue_[connect_op].perform_operations_for_descriptors( - fd_sets_[write_op], ops); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) + fd_sets_[except_op].perform(op_queue_[connect_op], ops); + fd_sets_[write_op].perform(op_queue_[connect_op], ops); +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Exception operations must be processed first to ensure that any // out-of-band data is read before normal data. for (int i = max_select_ops - 1; i >= 0; --i) - op_queue_[i].perform_operations_for_descriptors(fd_sets_[i], ops); + fd_sets_[i].perform(op_queue_[i], ops); } timer_queues_.get_ready_timers(ops); } @@ -310,5 +310,6 @@ void select_reactor::cancel_ops_unlocked(socket_type descriptor, // || (!defined(BOOST_ASIO_HAS_DEV_POLL) // && !defined(BOOST_ASIO_HAS_EPOLL) // && !defined(BOOST_ASIO_HAS_KQUEUE)) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)) #endif // BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp index eef25ac..1f71f08 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.hpp @@ -2,7 +2,7 @@ // detail/impl/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp index 6715010..adfcaa0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/service_registry.ipp @@ -2,7 +2,7 @@ // detail/impl/service_registry.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) @@ -16,9 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> -#include <boost/throw_exception.hpp> #include <vector> #include <boost/asio/detail/service_registry.hpp> +#include <boost/asio/detail/throw_exception.hpp> #include <boost/asio/detail/push_options.hpp> @@ -146,7 +146,7 @@ void service_registry::do_add_service( boost::asio::io_service::service* new_service) { if (&owner_ != &new_service->get_io_service()) - boost::throw_exception(invalid_service_owner()); + boost::asio::detail::throw_exception(invalid_service_owner()); boost::asio::detail::mutex::scoped_lock lock(mutex_); @@ -155,7 +155,7 @@ void service_registry::do_add_service( while (service) { if (keys_match(service->key_, key)) - boost::throw_exception(service_already_exists()); + boost::asio::detail::throw_exception(service_already_exists()); service = service->next_; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/signal_set_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/signal_set_service.ipp index 0b57007..21be62f 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/signal_set_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/signal_set_service.ipp @@ -2,7 +2,7 @@ // detail/impl/signal_set_service.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) @@ -57,25 +57,33 @@ signal_state* get_signal_state() return &state; } -void asio_signal_handler(int signal_number) +void boost_asio_signal_handler(int signal_number) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) \ + || defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + || defined(__CYGWIN__) signal_set_service::deliver_signal(signal_number); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) + // || defined(BOOST_ASIO_WINDOWS_RUNTIME) + // || defined(__CYGWIN__) int saved_errno = errno; signal_state* state = get_signal_state(); - int result = ::write(state->write_descriptor_, + signed_size_type result = ::write(state->write_descriptor_, &signal_number, sizeof(signal_number)); (void)result; errno = saved_errno; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) + // || defined(BOOST_ASIO_WINDOWS_RUNTIME) + // || defined(__CYGWIN__) #if defined(BOOST_ASIO_HAS_SIGNAL) && !defined(BOOST_ASIO_HAS_SIGACTION) - ::signal(signal_number, asio_signal_handler); + ::signal(signal_number, boost_asio_signal_handler); #endif // defined(BOOST_ASIO_HAS_SIGNAL) && !defined(BOOST_ASIO_HAS_SIGACTION) } -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) class signal_set_service::pipe_read_op : public reactor_op { public: @@ -105,22 +113,32 @@ public: delete o; } }; -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) signal_set_service::signal_set_service( boost::asio::io_service& io_service) : io_service_(boost::asio::use_service<io_service_impl>(io_service)), -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) reactor_(boost::asio::use_service<reactor>(io_service)), -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) next_(0), prev_(0) { get_signal_state()->mutex_.init(); -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) reactor_.init_task(); -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) for (int i = 0; i < max_signal_number; ++i) registrations_[i] = 0; @@ -155,21 +173,31 @@ void signal_set_service::shutdown_service() void signal_set_service::fork_service( boost::asio::io_service::fork_event fork_ev) { -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); switch (fork_ev) { case boost::asio::io_service::fork_prepare: - reactor_.deregister_internal_descriptor( - state->read_descriptor_, reactor_data_); - state->fork_prepared_ = true; + { + int read_descriptor = state->read_descriptor_; + state->fork_prepared_ = true; + lock.unlock(); + reactor_.deregister_internal_descriptor(read_descriptor, reactor_data_); + } break; case boost::asio::io_service::fork_parent: - state->fork_prepared_ = false; - reactor_.register_internal_descriptor(reactor::read_op, - state->read_descriptor_, reactor_data_, new pipe_read_op); + if (state->fork_prepared_) + { + int read_descriptor = state->read_descriptor_; + state->fork_prepared_ = false; + lock.unlock(); + reactor_.register_internal_descriptor(reactor::read_op, + read_descriptor, reactor_data_, new pipe_read_op); + } break; case boost::asio::io_service::fork_child: if (state->fork_prepared_) @@ -177,17 +205,23 @@ void signal_set_service::fork_service( boost::asio::detail::signal_blocker blocker; close_descriptors(); open_descriptors(); + int read_descriptor = state->read_descriptor_; state->fork_prepared_ = false; + lock.unlock(); + reactor_.register_internal_descriptor(reactor::read_op, + read_descriptor, reactor_data_, new pipe_read_op); } - reactor_.register_internal_descriptor(reactor::read_op, - state->read_descriptor_, reactor_data_, new pipe_read_op); break; default: break; } -#else // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#else // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) (void)fork_ev; -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) } void signal_set_service::construct( @@ -209,7 +243,7 @@ boost::system::error_code signal_set_service::add( int signal_number, boost::system::error_code& ec) { // Check that the signal number is valid. - if (signal_number < 0 || signal_number > max_signal_number) + if (signal_number < 0 || signal_number >= max_signal_number) { ec = boost::asio::error::invalid_argument; return ec; @@ -240,19 +274,19 @@ boost::system::error_code signal_set_service::add( using namespace std; // For memset. struct sigaction sa; memset(&sa, 0, sizeof(sa)); - sa.sa_handler = asio_signal_handler; + sa.sa_handler = boost_asio_signal_handler; sigfillset(&sa.sa_mask); if (::sigaction(signal_number, &sa, 0) == -1) # else // defined(BOOST_ASIO_HAS_SIGACTION) - if (::signal(signal_number, asio_signal_handler) == SIG_ERR) + if (::signal(signal_number, boost_asio_signal_handler) == SIG_ERR) # endif // defined(BOOST_ASIO_HAS_SIGACTION) { -# if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::asio::error::invalid_argument; -# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::system::error_code(errno, boost::asio::error::get_system_category()); -# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) delete new_registration; return ec; } @@ -283,7 +317,7 @@ boost::system::error_code signal_set_service::remove( int signal_number, boost::system::error_code& ec) { // Check that the signal number is valid. - if (signal_number < 0 || signal_number > max_signal_number) + if (signal_number < 0 || signal_number >= max_signal_number) { ec = boost::asio::error::invalid_argument; return ec; @@ -317,12 +351,12 @@ boost::system::error_code signal_set_service::remove( if (::signal(signal_number, SIG_DFL) == SIG_ERR) # endif // defined(BOOST_ASIO_HAS_SIGACTION) { -# if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::asio::error::invalid_argument; -# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::system::error_code(errno, boost::asio::error::get_system_category()); -# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) return ec; } } @@ -371,12 +405,12 @@ boost::system::error_code signal_set_service::clear( if (::signal(reg->signal_number_, SIG_DFL) == SIG_ERR) # endif // defined(BOOST_ASIO_HAS_SIGACTION) { -# if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::asio::error::invalid_argument; -# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::system::error_code(errno, boost::asio::error::get_system_category()); -# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) return ec; } } @@ -466,11 +500,11 @@ void signal_set_service::add_service(signal_set_service* service) signal_state* state = get_signal_state(); static_mutex::scoped_lock lock(state->mutex_); -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) // If this is the first service to be created, open a new pipe. if (state->service_list_ == 0) open_descriptors(); -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) // Insert service into linked list of all services. service->next_ = state->service_list_; @@ -479,11 +513,17 @@ void signal_set_service::add_service(signal_set_service* service) state->service_list_->prev_ = service; state->service_list_ = service; -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) // Register for pipe readiness notifications. + int read_descriptor = state->read_descriptor_; + lock.unlock(); service->reactor_.register_internal_descriptor(reactor::read_op, - state->read_descriptor_, service->reactor_data_, new pipe_read_op); -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + read_descriptor, service->reactor_data_, new pipe_read_op); +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) } void signal_set_service::remove_service(signal_set_service* service) @@ -493,11 +533,18 @@ void signal_set_service::remove_service(signal_set_service* service) if (service->next_ || service->prev_ || state->service_list_ == service) { -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) // Disable the pipe readiness notifications. + int read_descriptor = state->read_descriptor_; + lock.unlock(); service->reactor_.deregister_descriptor( - state->read_descriptor_, service->reactor_data_, false); -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) + read_descriptor, service->reactor_data_, false); + lock.lock(); +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) // Remove service from linked list of all services. if (state->service_list_ == service) @@ -509,17 +556,19 @@ void signal_set_service::remove_service(signal_set_service* service) service->next_ = 0; service->prev_ = 0; -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) // If this is the last service to be removed, close the pipe. if (state->service_list_ == 0) close_descriptors(); -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) } } void signal_set_service::open_descriptors() { -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) signal_state* state = get_signal_state(); int pipe_fds[2]; @@ -542,12 +591,16 @@ void signal_set_service::open_descriptors() boost::asio::error::get_system_category()); boost::asio::detail::throw_error(ec, "signal_set_service pipe"); } -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) } void signal_set_service::close_descriptors() { -#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ + && !defined(__CYGWIN__) signal_state* state = get_signal_state(); if (state->read_descriptor_ != -1) @@ -557,7 +610,9 @@ void signal_set_service::close_descriptors() if (state->write_descriptor_ != -1) ::close(state->write_descriptor_); state->write_descriptor_ = -1; -#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) +#endif // !defined(BOOST_ASIO_WINDOWS) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + // && !defined(__CYGWIN__) } void signal_set_service::start_wait_op( @@ -574,6 +629,7 @@ void signal_set_service::start_wait_op( if (reg->undelivered_ > 0) { --reg->undelivered_; + op->signal_number_ = reg->signal_number_; io_service_.post_deferred_completion(op); return; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp index 16e9536..f2c9a11 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/socket_ops.ipp @@ -2,7 +2,7 @@ // detail/impl/socket_ops.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) @@ -16,17 +16,31 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> -#include <boost/assert.hpp> -#include <boost/detail/workaround.hpp> + #include <cctype> #include <cstdio> #include <cstdlib> #include <cstring> #include <cerrno> #include <new> +#include <boost/asio/detail/assert.hpp> #include <boost/asio/detail/socket_ops.hpp> #include <boost/asio/error.hpp> +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include <codecvt> +# include <locale> +# include <string> +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) \ + || defined(__MACH__) && defined(__APPLE__) +# if defined(BOOST_ASIO_HAS_PTHREADS) +# include <pthread.h> +# endif // defined(BOOST_ASIO_HAS_PTHREADS) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + // || defined(__MACH__) && defined(__APPLE__) + #include <boost/asio/detail/push_options.hpp> namespace boost { @@ -34,9 +48,11 @@ namespace asio { namespace detail { namespace socket_ops { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) struct msghdr { int msg_namelen; }; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) #if defined(__hpux) // HP-UX doesn't declare these functions extern "C", so they are declared again @@ -45,20 +61,24 @@ extern "C" char* if_indextoname(unsigned int, char*); extern "C" unsigned int if_nametoindex(const char*); #endif // defined(__hpux) +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + inline void clear_last_error() { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) WSASetLastError(0); #else errno = 0; #endif } +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + template <typename ReturnType> inline ReturnType error_wrapper(ReturnType return_value, boost::system::error_code& ec) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ec = boost::system::error_code(WSAGetLastError(), boost::asio::error::get_system_category()); #else @@ -293,11 +313,11 @@ int close(socket_type s, state_type& state, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::closesocket(s), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::close(s), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (result != 0 && (ec == boost::asio::error::would_block @@ -309,10 +329,10 @@ int close(socket_type s, state_type& state, // current OS where this behaviour is seen, Windows, says that the socket // remains open. Therefore we'll put the descriptor back into blocking // mode and have another attempt at closing it. -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = 0; ::ioctlsocket(s, FIONBIO, &arg); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) # if defined(__SYMBIAN32__) int flags = ::fcntl(s, F_GETFL, 0); if (flags >= 0) @@ -321,15 +341,15 @@ int close(socket_type s, state_type& state, ioctl_arg_type arg = 0; ::ioctl(s, FIONBIO, &arg); # endif // defined(__SYMBIAN32__) -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) state &= ~non_blocking; clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::closesocket(s), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) result = error_wrapper(::close(s), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } } @@ -348,7 +368,7 @@ bool set_user_non_blocking(socket_type s, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); #elif defined(__SYMBIAN32__) @@ -401,7 +421,7 @@ bool set_internal_non_blocking(socket_type s, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) ioctl_arg_type arg = (value ? 1 : 0); int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec); #elif defined(__SYMBIAN32__) @@ -501,8 +521,57 @@ void sync_connect(socket_type s, const socket_addr_type* addr, boost::asio::error::get_system_category()); } +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_connect(socket_type s, boost::system::error_code& ec) +{ + if (!ec) + { + // Need to set the SO_UPDATE_CONNECT_CONTEXT option so that getsockname + // and getpeername will work on the connected socket. + socket_ops::state_type state = 0; + const int so_update_connect_context = 0x7010; + socket_ops::setsockopt(s, state, SOL_SOCKET, + so_update_connect_context, 0, 0, ec); + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + bool non_blocking_connect(socket_type s, boost::system::error_code& ec) { + // Check if the connect operation has finished. This is required since we may + // get spurious readiness notifications from the reactor. +#if defined(BOOST_ASIO_WINDOWS) \ + || defined(__CYGWIN__) \ + || defined(__SYMBIAN32__) + fd_set write_fds; + FD_ZERO(&write_fds); + FD_SET(s, &write_fds); + fd_set except_fds; + FD_ZERO(&except_fds); + FD_SET(s, &except_fds); + timeval zero_timeout; + zero_timeout.tv_sec = 0; + zero_timeout.tv_usec = 0; + int ready = ::select(s + 1, 0, &write_fds, &except_fds, &zero_timeout); +#else // defined(BOOST_ASIO_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + pollfd fds; + fds.fd = s; + fds.events = POLLOUT; + fds.revents = 0; + int ready = ::poll(&fds, 1, 0); +#endif // defined(BOOST_ASIO_WINDOWS) + // || defined(__CYGWIN__) + // || defined(__SYMBIAN32__) + if (ready == 0) + { + // The asynchronous connect operation is still in progress. + return false; + } + // Get the error code from the connect operation. int connect_error = 0; size_t connect_error_len = sizeof(connect_error); @@ -524,7 +593,7 @@ bool non_blocking_connect(socket_type s, boost::system::error_code& ec) int socketpair(int af, int type, int protocol, socket_type sv[2], boost::system::error_code& ec) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)(af); (void)(type); (void)(protocol); @@ -550,11 +619,11 @@ bool sockatmark(socket_type s, boost::system::error_code& ec) #if defined(SIOCATMARK) ioctl_arg_type value = 0; -# if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec); -# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec); -# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (result == 0) ec = boost::system::error_code(); # if defined(ENOTTY) @@ -579,11 +648,11 @@ size_t available(socket_type s, boost::system::error_code& ec) } ioctl_arg_type value = 0; -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec); -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (result == 0) ec = boost::system::error_code(); #if defined(ENOTTY) @@ -620,32 +689,32 @@ inline void init_buf_iov_base(T& base, void* addr) base = static_cast<T>(addr); } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) typedef WSABUF buf; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) typedef iovec buf; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) void init_buf(buf& b, void* data, size_t size) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) b.buf = static_cast<char*>(data); b.len = static_cast<u_long>(size); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) init_buf_iov_base(b.iov_base, data); b.iov_len = size; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } void init_buf(buf& b, const void* data, size_t size) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) b.buf = static_cast<char*>(const_cast<void*>(data)); b.len = static_cast<u_long>(size); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) init_buf_iov_base(b.iov_base, const_cast<void*>(data)); b.iov_len = size; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr) @@ -670,11 +739,11 @@ inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr) name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr)); } -int recv(socket_type s, buf* bufs, size_t count, int flags, - boost::system::error_code& ec) +signed_size_type recv(socket_type s, buf* bufs, size_t count, + int flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast<DWORD>(count); DWORD bytes_transferred = 0; @@ -689,15 +758,15 @@ int recv(socket_type s, buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + msg.msg_iovlen = static_cast<int>(count); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recv(socket_type s, state_type state, buf* bufs, @@ -720,7 +789,7 @@ size_t sync_recv(socket_type s, state_type state, buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::recv(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec); // Check if operation succeeded. if (bytes > 0) @@ -782,7 +851,7 @@ bool non_blocking_recv(socket_type s, for (;;) { // Read some data. - int bytes = socket_ops::recv(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec); // Check for end of stream. if (is_stream && bytes == 0) @@ -815,12 +884,12 @@ bool non_blocking_recv(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int recvfrom(socket_type s, buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, +signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, + int flags, socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Receive some data. DWORD recv_buf_count = static_cast<DWORD>(count); DWORD bytes_transferred = 0; @@ -837,18 +906,18 @@ int recvfrom(socket_type s, buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = *addrlen; + msg.msg_namelen = static_cast<int>(*addrlen); msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, flags), ec); + msg.msg_iovlen = static_cast<int>(count); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); *addrlen = msg.msg_namelen; if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, @@ -865,7 +934,8 @@ size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec); // Check if operation succeeded. if (bytes >= 0) @@ -913,7 +983,8 @@ bool non_blocking_recvfrom(socket_type s, for (;;) { // Read some data. - int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -939,18 +1010,18 @@ bool non_blocking_recvfrom(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int recvmsg(socket_type s, buf* bufs, size_t count, +signed_size_type recvmsg(socket_type s, buf* bufs, size_t count, int in_flags, int& out_flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) out_flags = 0; return socket_ops::recv(s, bufs, count, in_flags, ec); -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = bufs; - msg.msg_iovlen = count; - int result = error_wrapper(::recvmsg(s, &msg, in_flags), ec); + msg.msg_iovlen = static_cast<int>(count); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec); if (result >= 0) { ec = boost::system::error_code(); @@ -959,7 +1030,7 @@ int recvmsg(socket_type s, buf* bufs, size_t count, else out_flags = 0; return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_recvmsg(socket_type s, state_type state, @@ -976,7 +1047,8 @@ size_t sync_recvmsg(socket_type s, state_type state, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::recvmsg(s, bufs, count, in_flags, out_flags, ec); + signed_size_type bytes = socket_ops::recvmsg( + s, bufs, count, in_flags, out_flags, ec); // Check if operation succeeded. if (bytes >= 0) @@ -1023,7 +1095,8 @@ bool non_blocking_recvmsg(socket_type s, for (;;) { // Read some data. - int bytes = socket_ops::recvmsg(s, bufs, count, in_flags, out_flags, ec); + signed_size_type bytes = socket_ops::recvmsg( + s, bufs, count, in_flags, out_flags, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -1049,11 +1122,11 @@ bool non_blocking_recvmsg(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int send(socket_type s, const buf* bufs, size_t count, int flags, - boost::system::error_code& ec) +signed_size_type send(socket_type s, const buf* bufs, size_t count, + int flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast<DWORD>(count); DWORD bytes_transferred = 0; @@ -1068,18 +1141,18 @@ int send(socket_type s, const buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); msg.msg_iov = const_cast<buf*>(bufs); - msg.msg_iovlen = count; + msg.msg_iovlen = static_cast<int>(count); #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_send(socket_type s, state_type state, const buf* bufs, @@ -1102,7 +1175,7 @@ size_t sync_send(socket_type s, state_type state, const buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::send(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec); // Check if operation succeeded. if (bytes >= 0) @@ -1149,7 +1222,7 @@ bool non_blocking_send(socket_type s, for (;;) { // Write some data. - int bytes = socket_ops::send(s, bufs, count, flags, ec); + signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -1175,12 +1248,12 @@ bool non_blocking_send(socket_type s, #endif // defined(BOOST_ASIO_HAS_IOCP) -int sendto(socket_type s, const buf* bufs, size_t count, int flags, - const socket_addr_type* addr, std::size_t addrlen, +signed_size_type sendto(socket_type s, const buf* bufs, size_t count, + int flags, const socket_addr_type* addr, std::size_t addrlen, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) // Send the data. DWORD send_buf_count = static_cast<DWORD>(count); DWORD bytes_transferred = 0; @@ -1195,20 +1268,20 @@ int sendto(socket_type s, const buf* bufs, size_t count, int flags, return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = addrlen; + msg.msg_namelen = static_cast<int>(addrlen); msg.msg_iov = const_cast<buf*>(bufs); - msg.msg_iovlen = count; + msg.msg_iovlen = static_cast<int>(count); #if defined(__linux__) flags |= MSG_NOSIGNAL; #endif // defined(__linux__) - int result = error_wrapper(::sendmsg(s, &msg, flags), ec); + signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } size_t sync_sendto(socket_type s, state_type state, const buf* bufs, @@ -1225,7 +1298,8 @@ size_t sync_sendto(socket_type s, state_type state, const buf* bufs, for (;;) { // Try to complete the operation without blocking. - int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::sendto( + s, bufs, count, flags, addr, addrlen, ec); // Check if operation succeeded. if (bytes >= 0) @@ -1253,7 +1327,8 @@ bool non_blocking_sendto(socket_type s, for (;;) { // Write some data. - int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec); + signed_size_type bytes = socket_ops::sendto( + s, bufs, count, flags, addr, addrlen, ec); // Retry operation if interrupted by signal. if (ec == boost::asio::error::interrupted) @@ -1283,13 +1358,13 @@ socket_type socket(int af, int type, int protocol, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0, WSA_FLAG_OVERLAPPED), ec); if (s == invalid_socket) return s; - if (af == AF_INET6) + if (af == BOOST_ASIO_OS_DEF(AF_INET6)) { // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to // false. This will only succeed on Windows Vista and later versions of @@ -1481,7 +1556,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname, } ec = boost::asio::error::fault; return socket_error_retval; -#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); @@ -1499,7 +1574,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname, if (result == 0) ec = boost::system::error_code(); return result; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen, s, level, optname, optval, optlen), ec); @@ -1518,7 +1593,7 @@ int getsockopt(socket_type s, state_type state, int level, int optname, if (result == 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } template <typename SockLenType> @@ -1540,7 +1615,7 @@ int getpeername(socket_type s, socket_addr_type* addr, return socket_error_retval; } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (cached) { // Check if socket is still connected. @@ -1561,9 +1636,9 @@ int getpeername(socket_type s, socket_addr_type* addr, ec = boost::system::error_code(); return 0; } -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)cached; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) clear_last_error(); int result = error_wrapper(call_getpeername( @@ -1610,7 +1685,7 @@ int ioctl(socket_type s, state_type& state, int cmd, } clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec); #elif defined(__MACH__) && defined(__APPLE__) \ || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) @@ -1651,7 +1726,7 @@ int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) if (!readfds && !writefds && !exceptfds && timeout) { DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; @@ -1671,7 +1746,7 @@ int select(int nfds, fd_set* readfds, fd_set* writefds, if (timeout && timeout->tv_sec == 0 && timeout->tv_usec > 0 && timeout->tv_usec < 1000) timeout->tv_usec = 1000; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) #if defined(__hpux) && defined(__SELECT) timespec ts; @@ -1696,7 +1771,7 @@ int poll_read(socket_type s, state_type state, boost::system::error_code& ec) return socket_error_retval; } -#if defined(BOOST_WINDOWS) \ +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; @@ -1707,8 +1782,8 @@ int poll_read(socket_type s, state_type state, boost::system::error_code& ec) zero_timeout.tv_usec = 0; timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0; clear_last_error(); - int result = error_wrapper(::select(s, &fds, 0, 0, timeout), ec); -#else // defined(BOOST_WINDOWS) + int result = error_wrapper(::select(s + 1, &fds, 0, 0, timeout), ec); +#else // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; @@ -1718,7 +1793,7 @@ int poll_read(socket_type s, state_type state, boost::system::error_code& ec) int timeout = (state & user_set_non_blocking) ? 0 : -1; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) @@ -1737,7 +1812,7 @@ int poll_write(socket_type s, state_type state, boost::system::error_code& ec) return socket_error_retval; } -#if defined(BOOST_WINDOWS) \ +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set fds; @@ -1748,8 +1823,8 @@ int poll_write(socket_type s, state_type state, boost::system::error_code& ec) zero_timeout.tv_usec = 0; timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0; clear_last_error(); - int result = error_wrapper(::select(s, 0, &fds, 0, timeout), ec); -#else // defined(BOOST_WINDOWS) + int result = error_wrapper(::select(s + 1, 0, &fds, 0, timeout), ec); +#else // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; @@ -1759,7 +1834,7 @@ int poll_write(socket_type s, state_type state, boost::system::error_code& ec) int timeout = (state & user_set_non_blocking) ? 0 : -1; clear_last_error(); int result = error_wrapper(::poll(&fds, 1, timeout), ec); -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) if (result == 0) @@ -1778,7 +1853,7 @@ int poll_connect(socket_type s, boost::system::error_code& ec) return socket_error_retval; } -#if defined(BOOST_WINDOWS) \ +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) fd_set write_fds; @@ -1788,11 +1863,12 @@ int poll_connect(socket_type s, boost::system::error_code& ec) FD_ZERO(&except_fds); FD_SET(s, &except_fds); clear_last_error(); - int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec); + int result = error_wrapper(::select( + s + 1, 0, &write_fds, &except_fds, 0), ec); if (result >= 0) ec = boost::system::error_code(); return result; -#else // defined(BOOST_WINDOWS) +#else // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) pollfd fds; @@ -1804,19 +1880,56 @@ int poll_connect(socket_type s, boost::system::error_code& ec) if (result >= 0) ec = boost::system::error_code(); return result; -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) } +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + const char* inet_ntop(int af, const void* src, char* dest, size_t length, unsigned long scope_id, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + using namespace std; // For sprintf. + const unsigned char* bytes = static_cast<const unsigned char*>(src); + if (af == BOOST_ASIO_OS_DEF(AF_INET)) + { + sprintf_s(dest, length, "%u.%u.%u.%u", + bytes[0], bytes[1], bytes[2], bytes[3]); + return dest; + } + else if (af == BOOST_ASIO_OS_DEF(AF_INET6)) + { + size_t n = 0, b = 0, z = 0; + while (n < length && b < 16) + { + if (bytes[b] == 0 && bytes[b + 1] == 0 && z == 0) + { + do b += 2; while (b < 16 && bytes[b] == 0 && bytes[b + 1] == 0); + n += sprintf_s(dest + n, length - n, ":%s", b < 16 ? "" : ":"), ++z; + } + else + { + n += sprintf_s(dest + n, length - n, "%s%x", b ? ":" : "", + (static_cast<u_long_type>(bytes[b]) << 8) | bytes[b + 1]); + b += 2; + } + } + if (scope_id) + n += sprintf_s(dest + n, length - n, "%%%lu", scope_id); + return dest; + } + else + { + ec = boost::asio::error::address_family_not_supported; + return 0; + } +#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy. - if (af != AF_INET && af != AF_INET6) + if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -1830,17 +1943,17 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length, sockaddr_in6_type v6; } address; DWORD address_length; - if (af == AF_INET) + if (af == BOOST_ASIO_OS_DEF(AF_INET)) { address_length = sizeof(sockaddr_in4_type); - address.v4.sin_family = AF_INET; + address.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET); address.v4.sin_port = 0; memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type)); } else // AF_INET6 { address_length = sizeof(sockaddr_in6_type); - address.v6.sin6_family = AF_INET6; + address.v6.sin6_family = BOOST_ASIO_OS_DEF(AF_INET6); address.v6.sin6_port = 0; address.v6.sin6_flowinfo = 0; address.v6.sin6_scope_id = scope_id; @@ -1848,7 +1961,7 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length, } DWORD string_length = static_cast<DWORD>(length); -#if defined(BOOST_NO_ANSI_APIS) +#if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR)); int result = error_wrapper(::WSAAddressToStringW(&address.base, address_length, 0, string_buffer, &string_length), ec); @@ -1867,33 +1980,181 @@ const char* inet_ntop(int af, const void* src, char* dest, size_t length, ec = boost::asio::error::invalid_argument; return result == socket_error_retval ? 0 : dest; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec); +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + const char* result = error_wrapper(::inet_ntop( + af, src, dest, static_cast<int>(length)), ec); if (result == 0 && !ec) ec = boost::asio::error::invalid_argument; - if (result != 0 && af == AF_INET6 && scope_id != 0) + if (result != 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id != 0) { using namespace std; // For strcat and sprintf. char if_name[IF_NAMESIZE + 1] = "%"; const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src); bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe) && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80)); - if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0) + bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff) + && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02)); + if ((!is_link_local && !is_multicast_link_local) + || if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0) sprintf(if_name + 1, "%lu", scope_id); strcat(dest, if_name); } return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } int inet_pton(int af, const char* src, void* dest, unsigned long* scope_id, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + using namespace std; // For sscanf. + unsigned char* bytes = static_cast<unsigned char*>(dest); + if (af == BOOST_ASIO_OS_DEF(AF_INET)) + { + unsigned int b0, b1, b2, b3; + if (sscanf_s(src, "%u.%u.%u.%u", &b0, &b1, &b2, &b3) != 4) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + if (b0 > 255 || b1 > 255 || b2 > 255 || b3 > 255) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + bytes[0] = static_cast<unsigned char>(b0); + bytes[1] = static_cast<unsigned char>(b1); + bytes[2] = static_cast<unsigned char>(b2); + bytes[3] = static_cast<unsigned char>(b3); + ec = boost::system::error_code(); + return 1; + } + else if (af == BOOST_ASIO_OS_DEF(AF_INET6)) + { + unsigned char* bytes = static_cast<unsigned char*>(dest); + std::memset(bytes, 0, 16); + unsigned char back_bytes[16] = { 0 }; + int num_front_bytes = 0, num_back_bytes = 0; + const char* p = src; + + enum { fword, fcolon, bword, scope, done } state = fword; + unsigned long current_word = 0; + while (state != done) + { + if (current_word > 0xFFFF) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + + switch (state) + { + case fword: + if (*p >= '0' && *p <= '9') + current_word = current_word * 16 + *p++ - '0'; + else if (*p >= 'a' && *p <= 'f') + current_word = current_word * 16 + *p++ - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + current_word = current_word * 16 + *p++ - 'A' + 10; + else + { + if (num_front_bytes == 16) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + + bytes[num_front_bytes++] = (current_word >> 8) & 0xFF; + bytes[num_front_bytes++] = current_word & 0xFF; + current_word = 0; + + if (*p == ':') + state = fcolon, ++p; + else if (*p == '%') + state = scope, ++p; + else if (*p == 0) + state = done; + else + { + ec = boost::asio::error::invalid_argument; + return -1; + } + } + break; + + case fcolon: + if (*p == ':') + state = bword, ++p; + else + state = fword; + break; + + case bword: + if (*p >= '0' && *p <= '9') + current_word = current_word * 16 + *p++ - '0'; + else if (*p >= 'a' && *p <= 'f') + current_word = current_word * 16 + *p++ - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + current_word = current_word * 16 + *p++ - 'A' + 10; + else + { + if (num_front_bytes + num_back_bytes == 16) + { + ec = boost::asio::error::invalid_argument; + return -1; + } + + back_bytes[num_back_bytes++] = (current_word >> 8) & 0xFF; + back_bytes[num_back_bytes++] = current_word & 0xFF; + current_word = 0; + + if (*p == ':') + state = bword, ++p; + else if (*p == '%') + state = scope, ++p; + else if (*p == 0) + state = done; + else + { + ec = boost::asio::error::invalid_argument; + return -1; + } + } + break; + + case scope: + if (*p >= '0' && *p <= '9') + current_word = current_word * 10 + *p++ - '0'; + else if (*p == 0) + *scope_id = current_word, state = done; + else + { + ec = boost::asio::error::invalid_argument; + return -1; + } + break; + + default: + break; + } + } + + for (int i = 0; i < num_back_bytes; ++i) + bytes[16 - num_back_bytes + i] = back_bytes[i]; + + ec = boost::system::error_code(); + return 1; + } + else + { + ec = boost::asio::error::address_family_not_supported; + return -1; + } +#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) using namespace std; // For memcpy and strcmp. - if (af != AF_INET && af != AF_INET6) + if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6)) { ec = boost::asio::error::address_family_not_supported; return -1; @@ -1907,7 +2168,7 @@ int inet_pton(int af, const char* src, void* dest, sockaddr_in6_type v6; } address; int address_length = sizeof(sockaddr_storage_type); -#if defined(BOOST_NO_ANSI_APIS) +#if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800)) int num_wide_chars = strlen(src) + 1; LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR)); ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars); @@ -1918,7 +2179,7 @@ int inet_pton(int af, const char* src, void* dest, const_cast<char*>(src), af, 0, &address.base, &address_length), ec); #endif - if (af == AF_INET) + if (af == BOOST_ASIO_OS_DEF(AF_INET)) { if (result != socket_error_retval) { @@ -1950,11 +2211,11 @@ int inet_pton(int af, const char* src, void* dest, ec = boost::system::error_code(); return result == socket_error_retval ? -1 : 1; -#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::inet_pton(af, src, dest), ec); if (result <= 0 && !ec) ec = boost::asio::error::invalid_argument; - if (result > 0 && af == AF_INET6 && scope_id) + if (result > 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id) { using namespace std; // For strchr and atoi. *scope_id = 0; @@ -1963,29 +2224,63 @@ int inet_pton(int af, const char* src, void* dest, in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest); bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe) && ((ipv6_address->s6_addr[1] & 0xc0) == 0x80)); - if (is_link_local) + bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff) + && ((ipv6_address->s6_addr[1] & 0x0f) == 0x02)); + if (is_link_local || is_multicast_link_local) *scope_id = if_nametoindex(if_name + 1); if (*scope_id == 0) *scope_id = atoi(if_name + 1); } } return result; -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } int gethostname(char* name, int namelen, boost::system::error_code& ec) { clear_last_error(); +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + try + { + using namespace Windows::Foundation::Collections; + using namespace Windows::Networking; + using namespace Windows::Networking::Connectivity; + IVectorView<HostName^>^ hostnames = NetworkInformation::GetHostNames(); + for (unsigned i = 0; i < hostnames->Size; ++i) + { + HostName^ hostname = hostnames->GetAt(i); + if (hostname->Type == HostNameType::DomainName) + { + std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; + std::string raw_name = converter.to_bytes(hostname->RawName->Data()); + if (namelen > 0 && raw_name.size() < static_cast<std::size_t>(namelen)) + { + strcpy_s(name, namelen, raw_name.c_str()); + return 0; + } + } + } + return -1; + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + return -1; + } +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) int result = error_wrapper(::gethostname(name, namelen), ec); -#if defined(BOOST_WINDOWS) +# if defined(BOOST_ASIO_WINDOWS) if (result == 0) ec = boost::system::error_code(); -#endif +# endif // defined(BOOST_ASIO_WINDOWS) return result; +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \ - || defined(__MACH__) && defined(__APPLE__) +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if !defined(BOOST_ASIO_HAS_GETADDRINFO) // The following functions are only needed for emulation of getaddrinfo and // getnameinfo. @@ -2005,7 +2300,7 @@ inline boost::system::error_code translate_netdb_error(int error) case NO_DATA: return boost::asio::error::no_data; default: - BOOST_ASSERT(false); + BOOST_ASIO_ASSERT(false); return boost::asio::error::invalid_argument; } } @@ -2014,7 +2309,7 @@ inline hostent* gethostbyaddr(const char* addr, int length, int af, hostent* result, char* buffer, int buflength, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec); @@ -2057,11 +2352,11 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, char* buffer, int buflength, int ai_flags, boost::system::error_code& ec) { clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) (void)(buffer); (void)(buflength); (void)(ai_flags); - if (af != AF_INET) + if (af != BOOST_ASIO_OS_DEF(AF_INET)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -2074,7 +2369,7 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, return result; #elif defined(__sun) || defined(__QNX__) (void)(ai_flags); - if (af != AF_INET) + if (af != BOOST_ASIO_OS_DEF(AF_INET)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -2099,7 +2394,7 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result, return retval; #else (void)(ai_flags); - if (af != AF_INET) + if (af != BOOST_ASIO_OS_DEF(AF_INET)) { ec = boost::asio::error::address_family_not_supported; return 0; @@ -2144,22 +2439,22 @@ inline int gai_nsearch(const char* host, // No host and AI_PASSIVE implies wildcard bind. switch (hints->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): search[search_count].host = "0.0.0.0"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): search[search_count].host = "0::0"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; break; - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = "0::0"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = "0.0.0.0"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; default: @@ -2171,22 +2466,22 @@ inline int gai_nsearch(const char* host, // No host and not AI_PASSIVE means connect to local host. switch (hints->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): search[search_count].host = "localhost"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): search[search_count].host = "localhost"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; break; - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = "localhost"; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = "localhost"; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; default: @@ -2199,22 +2494,22 @@ inline int gai_nsearch(const char* host, // Host is specified. switch (hints->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): search[search_count].host = host; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): search[search_count].host = host; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; break; - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): search[search_count].host = host; - search[search_count].family = AF_INET6; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6); ++search_count; search[search_count].host = host; - search[search_count].family = AF_INET; + search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET); ++search_count; break; default: @@ -2242,12 +2537,12 @@ inline void gai_free(void* p) inline void gai_strcpy(char* target, const char* source, std::size_t max_size) { using namespace std; -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) strcpy_s(target, max_size, source); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) *target = 0; strncat(target, source, max_size); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) } enum { gai_clone_flag = 1 << 30 }; @@ -2274,23 +2569,23 @@ inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints, switch (ai->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>(); if (sinptr == 0) return EAI_MEMORY; - sinptr->sin_family = AF_INET; + sinptr->sin_family = BOOST_ASIO_OS_DEF(AF_INET); memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type)); ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr); ai->ai_addrlen = sizeof(sockaddr_in4_type); break; } - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>(); if (sin6ptr == 0) return EAI_MEMORY; - sin6ptr->sin6_family = AF_INET6; + sin6ptr->sin6_family = BOOST_ASIO_OS_DEF(AF_INET6); memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type)); ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr); ai->ai_addrlen = sizeof(sockaddr_in6_type); @@ -2352,7 +2647,7 @@ inline int gai_port(addrinfo_type* aihead, int port, int socktype) switch (ai->ai_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): { sockaddr_in4_type* sinptr = reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr); @@ -2360,7 +2655,7 @@ inline int gai_port(addrinfo_type* aihead, int port, int socktype) ++num_found; break; } - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): { sockaddr_in6_type* sin6ptr = reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr); @@ -2469,10 +2764,10 @@ inline int gai_echeck(const char* host, const char* service, // Check combination of family and socket type. switch (family) { - case AF_UNSPEC: + case BOOST_ASIO_OS_DEF(AF_UNSPEC): break; - case AF_INET: - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET): + case BOOST_ASIO_OS_DEF(AF_INET6): if (service != 0 && service[0] != '\0') if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM) return EAI_SOCKTYPE; @@ -2507,18 +2802,18 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Supply default hints if not specified by caller. addrinfo_type hints = addrinfo_type(); - hints.ai_family = AF_UNSPEC; + hints.ai_family = BOOST_ASIO_OS_DEF(AF_UNSPEC); if (hintsp) hints = *hintsp; // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED // and AI_ALL flags. #if defined(AI_V4MAPPED) - if (hints.ai_family != AF_INET6) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6)) hints.ai_flags &= ~AI_V4MAPPED; #endif #if defined(AI_ALL) - if (hints.ai_family != AF_INET6) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6)) hints.ai_flags &= ~AI_ALL; #endif @@ -2538,17 +2833,19 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Check for IPv4 dotted decimal string. in4_addr_type inaddr; boost::system::error_code ec; - if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1) + if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET), + sptr->host, &inaddr, 0, ec) == 1) { - if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC) + && hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET)) { freeaddrinfo_emulation(aihead); gai_free(canon); return EAI_FAMILY; } - if (sptr->family == AF_INET) + if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET)) { - rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET); + rc = gai_aistruct(&ainext, &hints, &inaddr, BOOST_ASIO_OS_DEF(AF_INET)); if (rc != 0) { freeaddrinfo_emulation(aihead); @@ -2561,17 +2858,20 @@ inline int getaddrinfo_emulation(const char* host, const char* service, // Check for IPv6 hex string. in6_addr_type in6addr; - if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1) + if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET6), + sptr->host, &in6addr, 0, ec) == 1) { - if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC) + && hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6)) { freeaddrinfo_emulation(aihead); gai_free(canon); return EAI_FAMILY; } - if (sptr->family == AF_INET6) + if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET6)) { - rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6); + rc = gai_aistruct(&ainext, &hints, &in6addr, + BOOST_ASIO_OS_DEF(AF_INET6)); if (rc != 0) { freeaddrinfo_emulation(aihead); @@ -2608,7 +2908,8 @@ inline int getaddrinfo_emulation(const char* host, const char* service, } // Check for address family mismatch if one was specified. - if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype) + if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC) + && hints.ai_family != hptr->h_addrtype) { freeaddrinfo_emulation(aihead); gai_free(canon); @@ -2704,7 +3005,7 @@ inline boost::system::error_code getnameinfo_emulation( unsigned short port; switch (sa->sa_family) { - case AF_INET: + case BOOST_ASIO_OS_DEF(AF_INET): if (salen != sizeof(sockaddr_in4_type)) { return ec = boost::asio::error::invalid_argument; @@ -2714,7 +3015,7 @@ inline boost::system::error_code getnameinfo_emulation( addr_len = sizeof(in4_addr_type); port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port; break; - case AF_INET6: + case BOOST_ASIO_OS_DEF(AF_INET6): if (salen != sizeof(sockaddr_in6_type)) { return ec = boost::asio::error::invalid_argument; @@ -2781,20 +3082,18 @@ inline boost::system::error_code getnameinfo_emulation( { return ec = boost::asio::error::no_buffer_space; } -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf_s(serv, servlen, "%u", ntohs(port)); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf(serv, "%u", ntohs(port)); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) } else { -#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \ - && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ::pthread_mutex_lock(&mutex); -#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - // && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0); if (sptr && sptr->s_name && sptr->s_name[0] != '\0') { @@ -2806,17 +3105,15 @@ inline boost::system::error_code getnameinfo_emulation( { return ec = boost::asio::error::no_buffer_space; } -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf_s(serv, servlen, "%u", ntohs(port)); -#else +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) sprintf(serv, "%u", ntohs(port)); -#endif +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) } -#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \ - && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_PTHREADS) ::pthread_mutex_unlock(&mutex); -#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) - // && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_PTHREADS) } } @@ -2824,8 +3121,7 @@ inline boost::system::error_code getnameinfo_emulation( return ec; } -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) - // || defined(__MACH__) && defined(__APPLE__) +#endif // !defined(BOOST_ASIO_HAS_GETADDRINFO) inline boost::system::error_code translate_addrinfo_error(int error) { @@ -2856,7 +3152,7 @@ inline boost::system::error_code translate_addrinfo_error(int error) case EAI_SOCKTYPE: return boost::asio::error::socket_type_not_supported; default: // Possibly the non-portable EAI_SYSTEM. -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) return boost::system::error_code( WSAGetLastError(), boost::asio::error::get_system_category()); #else @@ -2873,8 +3169,8 @@ boost::system::error_code getaddrinfo(const char* host, host = (host && *host) ? host : 0; service = (service && *service) ? service : 0; clear_last_error(); -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. int error = ::getaddrinfo(host, service, &hints, result); return ec = translate_addrinfo_error(error); @@ -2893,7 +3189,7 @@ boost::system::error_code getaddrinfo(const char* host, int error = getaddrinfo_emulation(host, service, &hints, result); return ec = translate_addrinfo_error(error); # endif -#elif defined(__MACH__) && defined(__APPLE__) +#elif !defined(BOOST_ASIO_HAS_GETADDRINFO) int error = getaddrinfo_emulation(host, service, &hints, result); return ec = translate_addrinfo_error(error); #else @@ -2916,8 +3212,8 @@ boost::system::error_code background_getaddrinfo( void freeaddrinfo(addrinfo_type* ai) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. ::freeaddrinfo(ai); # else @@ -2933,7 +3229,7 @@ void freeaddrinfo(addrinfo_type* ai) } freeaddrinfo_emulation(ai); # endif -#elif defined(__MACH__) && defined(__APPLE__) +#elif !defined(BOOST_ASIO_HAS_GETADDRINFO) freeaddrinfo_emulation(ai); #else ::freeaddrinfo(ai); @@ -2944,8 +3240,8 @@ boost::system::error_code getnameinfo(const socket_addr_type* addr, std::size_t addrlen, char* host, std::size_t hostlen, char* serv, std::size_t servlen, int flags, boost::system::error_code& ec) { -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +# if defined(BOOST_ASIO_HAS_GETADDRINFO) // Building for Windows XP, Windows Server 2003, or later. clear_last_error(); int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen), @@ -2971,7 +3267,7 @@ boost::system::error_code getnameinfo(const socket_addr_type* addr, return getnameinfo_emulation(addr, addrlen, host, hostlen, serv, servlen, flags, ec); # endif -#elif defined(__MACH__) && defined(__APPLE__) +#elif !defined(BOOST_ASIO_HAS_GETADDRINFO) using namespace std; // For memcpy. sockaddr_storage_type tmp_addr; memcpy(&tmp_addr, addr, addrlen); @@ -3033,24 +3329,60 @@ boost::system::error_code background_getnameinfo( return ec; } +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + u_long_type network_to_host_long(u_long_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + unsigned char* value_p = reinterpret_cast<unsigned char*>(&value); + u_long_type result = (static_cast<u_long_type>(value_p[0]) << 24) + | (static_cast<u_long_type>(value_p[1]) << 16) + | (static_cast<u_long_type>(value_p[2]) << 8) + | static_cast<u_long_type>(value_p[3]); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return ntohl(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } u_long_type host_to_network_long(u_long_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + u_long_type result; + unsigned char* result_p = reinterpret_cast<unsigned char*>(&result); + result_p[0] = static_cast<unsigned char>((value >> 24) & 0xFF); + result_p[1] = static_cast<unsigned char>((value >> 16) & 0xFF); + result_p[2] = static_cast<unsigned char>((value >> 8) & 0xFF); + result_p[3] = static_cast<unsigned char>(value & 0xFF); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return htonl(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } u_short_type network_to_host_short(u_short_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + unsigned char* value_p = reinterpret_cast<unsigned char*>(&value); + u_short_type result = (static_cast<u_long_type>(value_p[0]) << 8) + | static_cast<u_long_type>(value_p[1]); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return ntohs(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } u_short_type host_to_network_short(u_short_type value) { +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + u_long_type result; + unsigned char* result_p = reinterpret_cast<unsigned char*>(&result); + result_p[0] = static_cast<unsigned char>((value >> 8) & 0xFF); + result_p[1] = static_cast<unsigned char>(value & 0xFF); + return result; +#else // defined(BOOST_ASIO_WINDOWS_RUNTIME) return htons(value); +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) } } // namespace socket_ops diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp index 6005f12..e2dedc7 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/socket_select_interrupter.ipp @@ -2,7 +2,7 @@ // detail/impl/socket_select_interrupter.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) @@ -17,7 +17,9 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) \ +#if !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#if defined(BOOST_ASIO_WINDOWS) \ || defined(__CYGWIN__) \ || defined(__SYMBIAN32__) @@ -57,7 +59,7 @@ void socket_select_interrupter::open_descriptors() std::size_t addr_len = sizeof(addr); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK); addr.sin_port = 0; if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr, addr_len, ec) == socket_error_retval) @@ -70,7 +72,7 @@ void socket_select_interrupter::open_descriptors() // Some broken firewalls on Windows will intermittently cause getsockname to // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We // explicitly specify the target address here to work around this problem. - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK); if (socket_ops::listen(acceptor.get(), SOMAXCONN, ec) == socket_error_retval) @@ -166,8 +168,10 @@ bool socket_select_interrupter::reset() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) // || defined(__CYGWIN__) // || defined(__SYMBIAN32__) +#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) + #endif // BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp index 7581852..17227f9 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.hpp @@ -2,7 +2,7 @@ // detail/impl/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) @@ -15,6 +15,7 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#include <boost/asio/detail/addressof.hpp> #include <boost/asio/detail/call_stack.hpp> #include <boost/asio/detail/completion_handler.hpp> #include <boost/asio/detail/fenced_block.hpp> @@ -46,13 +47,13 @@ struct strand_service::on_dispatch_exit impl_->mutex_.unlock(); if (more_handlers) - io_service_->post_immediate_completion(impl_); + io_service_->post_immediate_completion(impl_, false); } }; template <typename Handler> void strand_service::dispatch(strand_service::implementation_type& impl, - Handler handler) + Handler& handler) { // If we are already in the strand then the handler can run immediately. if (call_stack<strand_impl>::contains(impl)) @@ -64,7 +65,7 @@ void strand_service::dispatch(strand_service::implementation_type& impl, // Allocate and construct an operation to wrap the handler. typedef completion_handler<Handler> op; - typename op::ptr p = { boost::addressof(handler), + typename op::ptr p = { boost::asio::detail::addressof(handler), boost_asio_handler_alloc_helpers::allocate( sizeof(op), handler), 0 }; p.p = new (p.v) op(handler); @@ -92,18 +93,21 @@ void strand_service::dispatch(strand_service::implementation_type& impl, // Request the io_service to invoke the given handler and return immediately. template <typename Handler> void strand_service::post(strand_service::implementation_type& impl, - Handler handler) + Handler& handler) { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + // Allocate and construct an operation to wrap the handler. typedef completion_handler<Handler> op; - typename op::ptr p = { boost::addressof(handler), + typename op::ptr p = { boost::asio::detail::addressof(handler), boost_asio_handler_alloc_helpers::allocate( sizeof(op), handler), 0 }; p.p = new (p.v) op(handler); BOOST_ASIO_HANDLER_CREATION((p.p, "strand", impl, "post")); - do_post(impl, p.p); + do_post(impl, p.p, is_continuation); p.v = p.p = 0; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp index 1912d80..9af0128 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/strand_service.ipp @@ -2,7 +2,7 @@ // detail/impl/strand_service.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) @@ -38,7 +38,7 @@ struct strand_service::on_do_complete_exit impl_->mutex_.unlock(); if (more_handlers) - owner_->post_private_immediate_completion(impl_); + owner_->post_immediate_completion(impl_, true); } }; @@ -85,6 +85,12 @@ void strand_service::construct(strand_service::implementation_type& impl) impl = implementations_[index].get(); } +bool strand_service::running_in_this_thread( + const implementation_type& impl) const +{ + return call_stack<strand_impl>::contains(impl) != 0; +} + bool strand_service::do_dispatch(implementation_type& impl, operation* op) { // If we are running inside the io_service, and no other handler already @@ -112,13 +118,14 @@ bool strand_service::do_dispatch(implementation_type& impl, operation* op) impl->locked_ = true; impl->mutex_.unlock(); impl->ready_queue_.push(op); - io_service_.post_immediate_completion(impl); + io_service_.post_immediate_completion(impl, false); } return false; } -void strand_service::do_post(implementation_type& impl, operation* op) +void strand_service::do_post(implementation_type& impl, + operation* op, bool is_continuation) { impl->mutex_.lock(); if (impl->locked_) @@ -134,7 +141,7 @@ void strand_service::do_post(implementation_type& impl, operation* op) impl->locked_ = true; impl->mutex_.unlock(); impl->ready_queue_.push(op); - io_service_.post_immediate_completion(impl); + io_service_.post_immediate_completion(impl, is_continuation); } } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp index 2cc7b7e..4312de7 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.hpp @@ -2,7 +2,7 @@ // detail/impl/task_io_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) @@ -15,9 +15,11 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#include <boost/asio/detail/addressof.hpp> #include <boost/asio/detail/completion_handler.hpp> #include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> +#include <boost/asio/detail/handler_cont_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/push_options.hpp> @@ -27,7 +29,7 @@ namespace asio { namespace detail { template <typename Handler> -void task_io_service::dispatch(Handler handler) +void task_io_service::dispatch(Handler& handler) { if (thread_call_stack::contains(this)) { @@ -38,31 +40,34 @@ void task_io_service::dispatch(Handler handler) { // Allocate and construct an operation to wrap the handler. typedef completion_handler<Handler> op; - typename op::ptr p = { boost::addressof(handler), + typename op::ptr p = { boost::asio::detail::addressof(handler), boost_asio_handler_alloc_helpers::allocate( sizeof(op), handler), 0 }; p.p = new (p.v) op(handler); BOOST_ASIO_HANDLER_CREATION((p.p, "io_service", this, "dispatch")); - post_non_private_immediate_completion(p.p); + do_dispatch(p.p); p.v = p.p = 0; } } template <typename Handler> -void task_io_service::post(Handler handler) +void task_io_service::post(Handler& handler) { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + // Allocate and construct an operation to wrap the handler. typedef completion_handler<Handler> op; - typename op::ptr p = { boost::addressof(handler), + typename op::ptr p = { boost::asio::detail::addressof(handler), boost_asio_handler_alloc_helpers::allocate( sizeof(op), handler), 0 }; p.p = new (p.v) op(handler); BOOST_ASIO_HANDLER_CREATION((p.p, "io_service", this, "post")); - post_immediate_completion(p.p); + post_immediate_completion(p.p, is_continuation); p.v = p.p = 0; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp index 674df63..e58e11e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/task_io_service.ipp @@ -2,7 +2,7 @@ // detail/impl/task_io_service.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) @@ -19,10 +19,11 @@ #if !defined(BOOST_ASIO_HAS_IOCP) -#include <boost/limits.hpp> #include <boost/asio/detail/event.hpp> +#include <boost/asio/detail/limits.hpp> #include <boost/asio/detail/reactor.hpp> #include <boost/asio/detail/task_io_service.hpp> +#include <boost/asio/detail/task_io_service_thread_info.hpp> #include <boost/asio/detail/push_options.hpp> @@ -30,14 +31,6 @@ namespace boost { namespace asio { namespace detail { -struct task_io_service::thread_info -{ - event* wakeup_event; - op_queue<operation> private_op_queue; - long private_outstanding_work; - thread_info* next; -}; - struct task_io_service::task_cleanup { ~task_cleanup() @@ -79,13 +72,13 @@ struct task_io_service::work_cleanup } this_thread_->private_outstanding_work = 0; -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_THREADS) if (!this_thread_->private_op_queue.empty()) { lock_->lock(); task_io_service_->op_queue_.push(this_thread_->private_op_queue); } -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_THREADS) } task_io_service* task_io_service_; @@ -102,8 +95,7 @@ task_io_service::task_io_service( task_interrupted_(true), outstanding_work_(0), stopped_(false), - shutdown_(false), - first_idle_thread_(0) + shutdown_(false) { BOOST_ASIO_HANDLER_TRACKING_INIT; } @@ -148,10 +140,7 @@ std::size_t task_io_service::run(boost::system::error_code& ec) } thread_info this_thread; - event wakeup_event; - this_thread.wakeup_event = &wakeup_event; this_thread.private_outstanding_work = 0; - this_thread.next = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); @@ -173,10 +162,7 @@ std::size_t task_io_service::run_one(boost::system::error_code& ec) } thread_info this_thread; - event wakeup_event; - this_thread.wakeup_event = &wakeup_event; this_thread.private_outstanding_work = 0; - this_thread.next = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); @@ -194,21 +180,19 @@ std::size_t task_io_service::poll(boost::system::error_code& ec) } thread_info this_thread; - this_thread.wakeup_event = 0; this_thread.private_outstanding_work = 0; - this_thread.next = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_THREADS) // We want to support nested calls to poll() and poll_one(), so any handlers // that are already on a thread-private queue need to be put on to the main // queue now. if (one_thread_) if (thread_info* outer_thread_info = ctx.next_by_key()) op_queue_.push(outer_thread_info->private_op_queue); -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_THREADS) std::size_t n = 0; for (; do_poll_one(lock, this_thread, ec); lock.lock()) @@ -227,21 +211,19 @@ std::size_t task_io_service::poll_one(boost::system::error_code& ec) } thread_info this_thread; - this_thread.wakeup_event = 0; this_thread.private_outstanding_work = 0; - this_thread.next = 0; thread_call_stack::context ctx(this, this_thread); mutex::scoped_lock lock(mutex_); -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_THREADS) // We want to support nested calls to poll() and poll_one(), so any handlers // that are already on a thread-private queue need to be put on to the main // queue now. if (one_thread_) if (thread_info* outer_thread_info = ctx.next_by_key()) op_queue_.push(outer_thread_info->private_op_queue); -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_THREADS) return do_poll_one(lock, this_thread, ec); } @@ -264,10 +246,11 @@ void task_io_service::reset() stopped_ = false; } -void task_io_service::post_immediate_completion(task_io_service::operation* op) +void task_io_service::post_immediate_completion( + task_io_service::operation* op, bool is_continuation) { -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) - if (one_thread_) +#if defined(BOOST_ASIO_HAS_THREADS) + if (one_thread_ || is_continuation) { if (thread_info* this_thread = thread_call_stack::contains(this)) { @@ -276,7 +259,9 @@ void task_io_service::post_immediate_completion(task_io_service::operation* op) return; } } -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#else // defined(BOOST_ASIO_HAS_THREADS) + (void)is_continuation; +#endif // defined(BOOST_ASIO_HAS_THREADS) work_started(); mutex::scoped_lock lock(mutex_); @@ -286,7 +271,7 @@ void task_io_service::post_immediate_completion(task_io_service::operation* op) void task_io_service::post_deferred_completion(task_io_service::operation* op) { -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_THREADS) if (one_thread_) { if (thread_info* this_thread = thread_call_stack::contains(this)) @@ -295,7 +280,7 @@ void task_io_service::post_deferred_completion(task_io_service::operation* op) return; } } -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_THREADS) mutex::scoped_lock lock(mutex_); op_queue_.push(op); @@ -307,7 +292,7 @@ void task_io_service::post_deferred_completions( { if (!ops.empty()) { -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#if defined(BOOST_ASIO_HAS_THREADS) if (one_thread_) { if (thread_info* this_thread = thread_call_stack::contains(this)) @@ -316,7 +301,7 @@ void task_io_service::post_deferred_completions( return; } } -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) +#endif // defined(BOOST_ASIO_HAS_THREADS) mutex::scoped_lock lock(mutex_); op_queue_.push(ops); @@ -324,39 +309,10 @@ void task_io_service::post_deferred_completions( } } -void task_io_service::post_private_immediate_completion( - task_io_service::operation* op) -{ - work_started(); - post_private_deferred_completion(op); -} - -void task_io_service::post_private_deferred_completion( - task_io_service::operation* op) -{ -#if defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) - if (thread_info* this_thread = thread_call_stack::contains(this)) - { - this_thread->private_op_queue.push(op); - return; - } -#endif // defined(BOOST_HAS_THREADS) && !defined(BOOST_ASIO_DISABLE_THREADS) - - mutex::scoped_lock lock(mutex_); - op_queue_.push(op); - wake_one_thread_and_unlock(lock); -} - -void task_io_service::post_non_private_immediate_completion( +void task_io_service::do_dispatch( task_io_service::operation* op) { work_started(); - post_non_private_deferred_completion(op); -} - -void task_io_service::post_non_private_deferred_completion( - task_io_service::operation* op) -{ mutex::scoped_lock lock(mutex_); op_queue_.push(op); wake_one_thread_and_unlock(lock); @@ -387,10 +343,7 @@ std::size_t task_io_service::do_run_one(mutex::scoped_lock& lock, task_interrupted_ = more_handlers; if (more_handlers && !one_thread_) - { - if (!wake_one_idle_thread_and_unlock(lock)) - lock.unlock(); - } + wakeup_event_.unlock_and_signal_one(lock); else lock.unlock(); @@ -423,11 +376,8 @@ std::size_t task_io_service::do_run_one(mutex::scoped_lock& lock, } else { - // Nothing to run right now, so just wait for work to do. - this_thread.next = first_idle_thread_; - first_idle_thread_ = &this_thread; - this_thread.wakeup_event->clear(lock); - this_thread.wakeup_event->wait(lock); + wakeup_event_.clear(lock); + wakeup_event_.wait(lock); } } @@ -459,7 +409,10 @@ std::size_t task_io_service::do_poll_one(mutex::scoped_lock& lock, o = op_queue_.front(); if (o == &task_operation_) + { + wakeup_event_.maybe_unlock_and_signal_one(lock); return 0; + } } if (o == 0) @@ -489,14 +442,7 @@ void task_io_service::stop_all_threads( mutex::scoped_lock& lock) { stopped_ = true; - - while (first_idle_thread_) - { - thread_info* idle_thread = first_idle_thread_; - first_idle_thread_ = idle_thread->next; - idle_thread->next = 0; - idle_thread->wakeup_event->signal(lock); - } + wakeup_event_.signal_all(lock); if (!task_interrupted_ && task_) { @@ -505,24 +451,10 @@ void task_io_service::stop_all_threads( } } -bool task_io_service::wake_one_idle_thread_and_unlock( - mutex::scoped_lock& lock) -{ - if (first_idle_thread_) - { - thread_info* idle_thread = first_idle_thread_; - first_idle_thread_ = idle_thread->next; - idle_thread->next = 0; - idle_thread->wakeup_event->signal_and_unlock(lock); - return true; - } - return false; -} - void task_io_service::wake_one_thread_and_unlock( mutex::scoped_lock& lock) { - if (!wake_one_idle_thread_and_unlock(lock)) + if (!wakeup_event_.maybe_unlock_and_signal_one(lock)) { if (!task_interrupted_ && task_) { diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp index dbe6112..5f6ed39 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/throw_error.ipp @@ -2,7 +2,7 @@ // detail/impl/throw_error.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) @@ -16,8 +16,8 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> -#include <boost/throw_exception.hpp> #include <boost/asio/detail/throw_error.hpp> +#include <boost/asio/detail/throw_exception.hpp> #include <boost/system/system_error.hpp> #include <boost/asio/detail/push_options.hpp> @@ -29,13 +29,13 @@ namespace detail { void do_throw_error(const boost::system::error_code& err) { boost::system::system_error e(err); - boost::throw_exception(e); + boost::asio::detail::throw_exception(e); } void do_throw_error(const boost::system::error_code& err, const char* location) { boost::system::system_error e(err, location); - boost::throw_exception(e); + boost::asio::detail::throw_exception(e); } } // namespace detail diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_ptime.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_ptime.ipp index c72d885..3b16def 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_ptime.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_ptime.ipp @@ -2,7 +2,7 @@ // detail/impl/timer_queue_ptime.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) @@ -20,6 +20,8 @@ #include <boost/asio/detail/push_options.hpp> +#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + namespace boost { namespace asio { namespace detail { @@ -77,6 +79,8 @@ std::size_t timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer( } // namespace asio } // namespace boost +#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) + #include <boost/asio/detail/pop_options.hpp> #endif // BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp index 7f9a662..19b770b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/timer_queue_set.ipp @@ -2,7 +2,7 @@ // detail/impl/timer_queue_set.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) diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp index 252242c..a004c09 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_event.ipp @@ -2,7 +2,7 @@ // detail/win_event.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/win_event.hpp> @@ -30,15 +30,32 @@ namespace asio { namespace detail { win_event::win_event() - : event_(::CreateEvent(0, true, false, 0)) + : state_(0) { - if (!event_) + events_[0] = ::CreateEvent(0, true, false, 0); + if (!events_[0]) { DWORD last_error = ::GetLastError(); boost::system::error_code ec(last_error, boost::asio::error::get_system_category()); boost::asio::detail::throw_error(ec, "event"); } + + events_[1] = ::CreateEvent(0, false, false, 0); + if (!events_[1]) + { + DWORD last_error = ::GetLastError(); + ::CloseHandle(events_[0]); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "event"); + } +} + +win_event::~win_event() +{ + ::CloseHandle(events_[0]); + ::CloseHandle(events_[1]); } } // namespace detail @@ -47,6 +64,6 @@ win_event::win_event() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) #endif // BOOST_ASIO_DETAIL_IMPL_WIN_EVENT_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp index ecd45c0..04a6791 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_handle_service.ipp @@ -2,7 +2,7 @@ // detail/impl/win_iocp_handle_service.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) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -46,7 +46,8 @@ public: // As documented in GetQueuedCompletionStatus, setting the low order // bit of this event prevents our synchronous writes from being treated // as completion port events. - *reinterpret_cast<DWORD_PTR*>(&hEvent) |= 1; + DWORD_PTR tmp = reinterpret_cast<DWORD_PTR>(hEvent); + hEvent = reinterpret_cast<HANDLE>(tmp | 1); } else { @@ -293,7 +294,7 @@ boost::system::error_code win_iocp_handle_service::cancel( } size_t win_iocp_handle_service::do_write( - win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + win_iocp_handle_service::implementation_type& impl, uint64_t offset, const boost::asio::const_buffer& buffer, boost::system::error_code& ec) { if (!is_open(impl)) @@ -349,7 +350,7 @@ size_t win_iocp_handle_service::do_write( } void win_iocp_handle_service::start_write_op( - win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + win_iocp_handle_service::implementation_type& impl, uint64_t offset, const boost::asio::const_buffer& buffer, operation* op) { update_cancellation_thread_id(impl); @@ -387,7 +388,7 @@ void win_iocp_handle_service::start_write_op( } size_t win_iocp_handle_service::do_read( - win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + win_iocp_handle_service::implementation_type& impl, uint64_t offset, const boost::asio::mutable_buffer& buffer, boost::system::error_code& ec) { if (!is_open(impl)) @@ -449,7 +450,7 @@ size_t win_iocp_handle_service::do_read( ec = boost::system::error_code(last_error, boost::asio::error::get_system_category()); } - return 0; + return (last_error == ERROR_MORE_DATA) ? bytes_transferred : 0; } ec = boost::system::error_code(); @@ -457,7 +458,7 @@ size_t win_iocp_handle_service::do_read( } void win_iocp_handle_service::start_read_op( - win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset, + win_iocp_handle_service::implementation_type& impl, uint64_t offset, const boost::asio::mutable_buffer& buffer, operation* op) { update_cancellation_thread_id(impl); diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp index 871f6fa..201a17e 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.hpp @@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// 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) @@ -19,6 +19,7 @@ #if defined(BOOST_ASIO_HAS_IOCP) +#include <boost/asio/detail/addressof.hpp> #include <boost/asio/detail/completion_handler.hpp> #include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> @@ -31,9 +32,9 @@ namespace asio { namespace detail { template <typename Handler> -void win_iocp_io_service::dispatch(Handler handler) +void win_iocp_io_service::dispatch(Handler& handler) { - if (call_stack<win_iocp_io_service>::contains(this)) + if (thread_call_stack::contains(this)) { fenced_block b(fenced_block::full); boost_asio_handler_invoke_helpers::invoke(handler, handler); @@ -42,31 +43,31 @@ void win_iocp_io_service::dispatch(Handler handler) { // Allocate and construct an operation to wrap the handler. typedef completion_handler<Handler> op; - typename op::ptr p = { boost::addressof(handler), + typename op::ptr p = { boost::asio::detail::addressof(handler), boost_asio_handler_alloc_helpers::allocate( sizeof(op), handler), 0 }; p.p = new (p.v) op(handler); BOOST_ASIO_HANDLER_CREATION((p.p, "io_service", this, "dispatch")); - post_immediate_completion(p.p); + post_immediate_completion(p.p, false); p.v = p.p = 0; } } template <typename Handler> -void win_iocp_io_service::post(Handler handler) +void win_iocp_io_service::post(Handler& handler) { // Allocate and construct an operation to wrap the handler. typedef completion_handler<Handler> op; - typename op::ptr p = { boost::addressof(handler), + typename op::ptr p = { boost::asio::detail::addressof(handler), boost_asio_handler_alloc_helpers::allocate( sizeof(op), handler), 0 }; p.p = new (p.v) op(handler); BOOST_ASIO_HANDLER_CREATION((p.p, "io_service", this, "post")); - post_immediate_completion(p.p); + post_immediate_completion(p.p, false); p.v = p.p = 0; } @@ -92,7 +93,7 @@ void win_iocp_io_service::schedule_timer(timer_queue<Time_Traits>& queue, // If the service has been shut down we silently discard the timer. if (::InterlockedExchangeAdd(&shutdown_, 0) != 0) { - post_immediate_completion(op); + post_immediate_completion(op, false); return; } diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp index 72f4af7..fbc1cd0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_io_service.ipp @@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_service.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) @@ -19,11 +19,12 @@ #if defined(BOOST_ASIO_HAS_IOCP) -#include <boost/limits.hpp> #include <boost/asio/error.hpp> #include <boost/asio/io_service.hpp> +#include <boost/asio/detail/cstdint.hpp> #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> +#include <boost/asio/detail/limits.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/win_iocp_io_service.hpp> @@ -68,13 +69,16 @@ win_iocp_io_service::win_iocp_io_service( iocp_(), outstanding_work_(0), stopped_(0), + stop_event_posted_(0), shutdown_(0), + gqcs_timeout_(get_gqcs_timeout()), dispatch_required_(0) { BOOST_ASIO_HANDLER_TRACKING_INIT; iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, - static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0)))); + static_cast<DWORD>(concurrency_hint < DWORD(~0) + ? concurrency_hint : DWORD(~0))); if (!iocp_.handle) { DWORD last_error = ::GetLastError(); @@ -115,7 +119,7 @@ void win_iocp_io_service::shutdown_service() dword_ptr_t completion_key = 0; LPOVERLAPPED overlapped = 0; ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, - &completion_key, &overlapped, gqcs_timeout); + &completion_key, &overlapped, gqcs_timeout_); if (overlapped) { ::InterlockedDecrement(&outstanding_work_); @@ -148,12 +152,13 @@ size_t win_iocp_io_service::run(boost::system::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { - InterlockedExchange(&stopped_, 1); + stop(); ec = boost::system::error_code(); return 0; } - call_stack<win_iocp_io_service>::context ctx(this); + win_iocp_thread_info this_thread; + thread_call_stack::context ctx(this, this_thread); size_t n = 0; while (do_one(true, ec)) @@ -166,12 +171,13 @@ size_t win_iocp_io_service::run_one(boost::system::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { - InterlockedExchange(&stopped_, 1); + stop(); ec = boost::system::error_code(); return 0; } - call_stack<win_iocp_io_service>::context ctx(this); + win_iocp_thread_info this_thread; + thread_call_stack::context ctx(this, this_thread); return do_one(true, ec); } @@ -180,12 +186,13 @@ size_t win_iocp_io_service::poll(boost::system::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { - InterlockedExchange(&stopped_, 1); + stop(); ec = boost::system::error_code(); return 0; } - call_stack<win_iocp_io_service>::context ctx(this); + win_iocp_thread_info this_thread; + thread_call_stack::context ctx(this, this_thread); size_t n = 0; while (do_one(false, ec)) @@ -198,12 +205,13 @@ size_t win_iocp_io_service::poll_one(boost::system::error_code& ec) { if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { - InterlockedExchange(&stopped_, 1); + stop(); ec = boost::system::error_code(); return 0; } - call_stack<win_iocp_io_service>::context ctx(this); + win_iocp_thread_info this_thread; + thread_call_stack::context ctx(this, this_thread); return do_one(false, ec); } @@ -212,12 +220,15 @@ void win_iocp_io_service::stop() { if (::InterlockedExchange(&stopped_, 1) == 0) { - if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + if (::InterlockedExchange(&stop_event_posted_, 1) == 0) { - DWORD last_error = ::GetLastError(); - boost::system::error_code ec(last_error, - boost::asio::error::get_system_category()); - boost::asio::detail::throw_error(ec, "pqcs"); + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + DWORD last_error = ::GetLastError(); + boost::system::error_code ec(last_error, + boost::asio::error::get_system_category()); + boost::asio::detail::throw_error(ec, "pqcs"); + } } } } @@ -228,8 +239,7 @@ void win_iocp_io_service::post_deferred_completion(win_iocp_operation* op) op->ready_ = 1; // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); @@ -249,8 +259,7 @@ void win_iocp_io_service::post_deferred_completions( op->ready_ = 1; // Enqueue the operation on the I/O completion port. - if (!::PostQueuedCompletionStatus(iocp_.handle, - 0, overlapped_contains_result, op)) + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, op)) { // Out of resources. Put on completed queue instead. mutex::scoped_lock lock(dispatch_mutex_); @@ -356,7 +365,7 @@ size_t win_iocp_io_service::do_one(bool block, boost::system::error_code& ec) LPOVERLAPPED overlapped = 0; ::SetLastError(0); BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, - &completion_key, &overlapped, block ? gqcs_timeout : 0); + &completion_key, &overlapped, block ? gqcs_timeout_ : 0); DWORD last_error = ::GetLastError(); if (overlapped) @@ -421,17 +430,23 @@ size_t win_iocp_io_service::do_one(bool block, boost::system::error_code& ec) } else { + // Indicate that there is no longer an in-flight stop event. + ::InterlockedExchange(&stop_event_posted_, 0); + // The stopped_ flag is always checked to ensure that any leftover - // interrupts from a previous run invocation are ignored. + // stop events from a previous run invocation are ignored. if (::InterlockedExchangeAdd(&stopped_, 0) != 0) { // Wake up next thread that is blocked on GetQueuedCompletionStatus. - if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + if (::InterlockedExchange(&stop_event_posted_, 1) == 0) { - last_error = ::GetLastError(); - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - return 0; + if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) + { + last_error = ::GetLastError(); + ec = boost::system::error_code(last_error, + boost::asio::error::get_system_category()); + return 0; + } } ec = boost::system::error_code(); @@ -441,6 +456,22 @@ size_t win_iocp_io_service::do_one(bool block, boost::system::error_code& ec) } } +DWORD win_iocp_io_service::get_gqcs_timeout() +{ + OSVERSIONINFOEX osvi; + ZeroMemory(&osvi, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + osvi.dwMajorVersion = 6ul; + + const uint64_t condition_mask = ::VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL); + + if (!!::VerifyVersionInfo(&osvi, VER_MAJORVERSION, condition_mask)) + return INFINITE; + + return default_gqcs_timeout; +} + void win_iocp_io_service::do_add_timer_queue(timer_queue_base& queue) { mutex::scoped_lock lock(dispatch_mutex_); diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp index e98ad87..e3081af 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_iocp_serial_port_service.ipp @@ -2,7 +2,7 @@ // detail/impl/win_iocp_serial_port_service.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) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) { diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp index 05a7492..f86012b 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_mutex.ipp @@ -2,7 +2,7 @@ // detail/impl/win_mutex.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/win_mutex.hpp> @@ -75,6 +75,6 @@ int win_mutex::do_init() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) #endif // BOOST_ASIO_DETAIL_IMPL_WIN_MUTEX_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_object_handle_service.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_object_handle_service.ipp index d91ccac..081d5eb 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_object_handle_service.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_object_handle_service.ipp @@ -2,7 +2,7 @@ // detail/impl/win_object_handle_service.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) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -421,7 +421,7 @@ void win_object_handle_service::wait_callback(PVOID param, BOOLEAN) boost::system::error_code ec(last_error, boost::asio::error::get_system_category()); - while (wait_op* op = impl->op_queue_.front()) + while ((op = impl->op_queue_.front()) != 0) { op->ec_ = ec; impl->op_queue_.pop(); diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_static_mutex.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_static_mutex.ipp index 3ec104d..84bd454 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_static_mutex.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_static_mutex.ipp @@ -2,7 +2,7 @@ // detail/impl/win_static_mutex.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) #include <cstdio> #include <boost/asio/detail/throw_error.hpp> @@ -42,12 +42,12 @@ int win_static_mutex::do_init() { using namespace std; // For sprintf. wchar_t mutex_name[128]; -#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) - swprintf_s(mutex_name, 128, -#else // BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) - swprintf(mutex_name, -#endif // BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE) - L"asio-58CCDC44-6264-4842-90C2-F3C545CB8AA7-%u-%p", +#if defined(BOOST_ASIO_HAS_SECURE_RTL) + swprintf_s( +#else // defined(BOOST_ASIO_HAS_SECURE_RTL) + _snwprintf( +#endif // defined(BOOST_ASIO_HAS_SECURE_RTL) + mutex_name, 128, L"asio-58CCDC44-6264-4842-90C2-F3C545CB8AA7-%u-%p", static_cast<unsigned int>(::GetCurrentProcessId()), this); HANDLE mutex = ::CreateMutexW(0, TRUE, mutex_name); @@ -115,6 +115,6 @@ int win_static_mutex::do_init() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) #endif // BOOST_ASIO_DETAIL_IMPL_WIN_STATIC_MUTEX_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp index 744990d..4bf09c5 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp @@ -2,7 +2,7 @@ // detail/impl/win_thread.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) && !defined(UNDER_CE) +#if defined(BOOST_ASIO_WINDOWS) && !defined(UNDER_CE) #include <process.h> #include <boost/asio/detail/throw_error.hpp> @@ -136,6 +136,6 @@ void __stdcall apc_function(ULONG_PTR) {} #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) +#endif // defined(BOOST_ASIO_WINDOWS) && !defined(UNDER_CE) #endif // BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp index 9da761c..abaad27 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_tss_ptr.ipp @@ -2,7 +2,7 @@ // detail/impl/win_tss_ptr.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) +#if defined(BOOST_ASIO_WINDOWS) #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/win_tss_ptr.hpp> @@ -54,6 +54,6 @@ DWORD win_tss_ptr_create() #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) +#endif // defined(BOOST_ASIO_WINDOWS) #endif // BOOST_ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/winrt_ssocket_service_base.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/winrt_ssocket_service_base.ipp new file mode 100644 index 0000000..fdd0465 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/winrt_ssocket_service_base.ipp @@ -0,0 +1,614 @@ +// +// detail/impl/winrt_ssocket_service_base.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP +#define BOOST_ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include <cstring> +#include <boost/asio/detail/winrt_ssocket_service_base.hpp> +#include <boost/asio/detail/winrt_async_op.hpp> +#include <boost/asio/detail/winrt_utils.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +winrt_ssocket_service_base::winrt_ssocket_service_base( + boost::asio::io_service& io_service) + : io_service_(use_service<io_service_impl>(io_service)), + async_manager_(use_service<winrt_async_manager>(io_service)), + mutex_(), + impl_list_(0) +{ +} + +void winrt_ssocket_service_base::shutdown_service() +{ + // Close all implementations, causing all operations to complete. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + base_implementation_type* impl = impl_list_; + while (impl) + { + boost::system::error_code ignored_ec; + close(*impl, ignored_ec); + impl = impl->next_; + } +} + +void winrt_ssocket_service_base::construct( + winrt_ssocket_service_base::base_implementation_type& impl) +{ + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; +} + +void winrt_ssocket_service_base::base_move_construct( + winrt_ssocket_service_base::base_implementation_type& impl, + winrt_ssocket_service_base::base_implementation_type& other_impl) +{ + impl.socket_ = other_impl.socket_; + other_impl.socket_ = nullptr; + + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + impl.next_ = impl_list_; + impl.prev_ = 0; + if (impl_list_) + impl_list_->prev_ = &impl; + impl_list_ = &impl; +} + +void winrt_ssocket_service_base::base_move_assign( + winrt_ssocket_service_base::base_implementation_type& impl, + winrt_ssocket_service_base& other_service, + winrt_ssocket_service_base::base_implementation_type& other_impl) +{ + boost::system::error_code ignored_ec; + close(impl, ignored_ec); + + if (this != &other_service) + { + // Remove implementation from linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; + } + + impl.socket_ = other_impl.socket_; + other_impl.socket_ = nullptr; + + if (this != &other_service) + { + // Insert implementation into linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(other_service.mutex_); + impl.next_ = other_service.impl_list_; + impl.prev_ = 0; + if (other_service.impl_list_) + other_service.impl_list_->prev_ = &impl; + other_service.impl_list_ = &impl; + } +} + +void winrt_ssocket_service_base::destroy( + winrt_ssocket_service_base::base_implementation_type& impl) +{ + boost::system::error_code ignored_ec; + close(impl, ignored_ec); + + // Remove implementation from linked list of all implementations. + boost::asio::detail::mutex::scoped_lock lock(mutex_); + if (impl_list_ == &impl) + impl_list_ = impl.next_; + if (impl.prev_) + impl.prev_->next_ = impl.next_; + if (impl.next_) + impl.next_->prev_= impl.prev_; + impl.next_ = 0; + impl.prev_ = 0; +} + +boost::system::error_code winrt_ssocket_service_base::close( + winrt_ssocket_service_base::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (impl.socket_) + { + delete impl.socket_; + impl.socket_ = nullptr; + } + + ec = boost::system::error_code(); + return ec; +} + +std::size_t winrt_ssocket_service_base::do_get_endpoint( + const base_implementation_type& impl, bool local, + void* addr, std::size_t addr_len, boost::system::error_code& ec) const +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return addr_len; + } + + try + { + std::string addr_string = winrt_utils::string(local + ? impl.socket_->Information->LocalAddress->CanonicalName + : impl.socket_->Information->RemoteAddress->CanonicalName); + unsigned short port = winrt_utils::integer(local + ? impl.socket_->Information->LocalPort + : impl.socket_->Information->RemotePort); + unsigned long scope = 0; + + switch (reinterpret_cast<const socket_addr_type*>(addr)->sa_family) + { + case BOOST_ASIO_OS_DEF(AF_INET): + if (addr_len < sizeof(sockaddr_in4_type)) + { + ec = boost::asio::error::invalid_argument; + return addr_len; + } + else + { + socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET), addr_string.c_str(), + &reinterpret_cast<sockaddr_in4_type*>(addr)->sin_addr, &scope, ec); + reinterpret_cast<sockaddr_in4_type*>(addr)->sin_port + = socket_ops::host_to_network_short(port); + ec = boost::system::error_code(); + return sizeof(sockaddr_in4_type); + } + case BOOST_ASIO_OS_DEF(AF_INET6): + if (addr_len < sizeof(sockaddr_in6_type)) + { + ec = boost::asio::error::invalid_argument; + return addr_len; + } + else + { + socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET6), addr_string.c_str(), + &reinterpret_cast<sockaddr_in6_type*>(addr)->sin6_addr, &scope, ec); + reinterpret_cast<sockaddr_in6_type*>(addr)->sin6_port + = socket_ops::host_to_network_short(port); + ec = boost::system::error_code(); + return sizeof(sockaddr_in6_type); + } + default: + ec = boost::asio::error::address_family_not_supported; + return addr_len; + } + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + return addr_len; + } +} + +boost::system::error_code winrt_ssocket_service_base::do_set_option( + winrt_ssocket_service_base::base_implementation_type& impl, + int level, int optname, const void* optval, + std::size_t optlen, boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + try + { + if (level == BOOST_ASIO_OS_DEF(SOL_SOCKET) + && optname == BOOST_ASIO_OS_DEF(SO_KEEPALIVE)) + { + if (optlen == sizeof(int)) + { + int value = 0; + std::memcpy(&value, optval, optlen); + impl.socket_->Control->KeepAlive = !!value; + ec = boost::system::error_code(); + } + else + { + ec = boost::asio::error::invalid_argument; + } + } + else if (level == BOOST_ASIO_OS_DEF(IPPROTO_TCP) + && optname == BOOST_ASIO_OS_DEF(TCP_NODELAY)) + { + if (optlen == sizeof(int)) + { + int value = 0; + std::memcpy(&value, optval, optlen); + impl.socket_->Control->NoDelay = !!value; + ec = boost::system::error_code(); + } + else + { + ec = boost::asio::error::invalid_argument; + } + } + else + { + ec = boost::asio::error::invalid_argument; + } + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + } + + return ec; +} + +void winrt_ssocket_service_base::do_get_option( + const winrt_ssocket_service_base::base_implementation_type& impl, + int level, int optname, void* optval, + std::size_t* optlen, boost::system::error_code& ec) const +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return; + } + + try + { + if (level == BOOST_ASIO_OS_DEF(SOL_SOCKET) + && optname == BOOST_ASIO_OS_DEF(SO_KEEPALIVE)) + { + if (*optlen >= sizeof(int)) + { + int value = impl.socket_->Control->KeepAlive ? 1 : 0; + std::memcpy(optval, &value, sizeof(int)); + *optlen = sizeof(int); + ec = boost::system::error_code(); + } + else + { + ec = boost::asio::error::invalid_argument; + } + } + else if (level == BOOST_ASIO_OS_DEF(IPPROTO_TCP) + && optname == BOOST_ASIO_OS_DEF(TCP_NODELAY)) + { + if (*optlen >= sizeof(int)) + { + int value = impl.socket_->Control->NoDelay ? 1 : 0; + std::memcpy(optval, &value, sizeof(int)); + *optlen = sizeof(int); + ec = boost::system::error_code(); + } + else + { + ec = boost::asio::error::invalid_argument; + } + } + else + { + ec = boost::asio::error::invalid_argument; + } + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + } +} + +boost::system::error_code winrt_ssocket_service_base::do_connect( + winrt_ssocket_service_base::base_implementation_type& impl, + const void* addr, boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + char addr_string[max_addr_v6_str_len]; + unsigned short port; + switch (reinterpret_cast<const socket_addr_type*>(addr)->sa_family) + { + case BOOST_ASIO_OS_DEF(AF_INET): + socket_ops::inet_ntop(BOOST_ASIO_OS_DEF(AF_INET), + &reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_addr, + addr_string, sizeof(addr_string), 0, ec); + port = socket_ops::network_to_host_short( + reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_port); + break; + case BOOST_ASIO_OS_DEF(AF_INET6): + socket_ops::inet_ntop(BOOST_ASIO_OS_DEF(AF_INET6), + &reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_addr, + addr_string, sizeof(addr_string), 0, ec); + port = socket_ops::network_to_host_short( + reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_port); + break; + default: + ec = boost::asio::error::address_family_not_supported; + return ec; + } + + if (!ec) try + { + async_manager_.sync(impl.socket_->ConnectAsync( + ref new Windows::Networking::HostName( + winrt_utils::string(addr_string)), + winrt_utils::string(port)), ec); + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + } + + return ec; +} + +void winrt_ssocket_service_base::start_connect_op( + winrt_ssocket_service_base::base_implementation_type& impl, + const void* addr, winrt_async_op<void>* op, bool is_continuation) +{ + if (!is_open(impl)) + { + op->ec_ = boost::asio::error::bad_descriptor; + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + char addr_string[max_addr_v6_str_len]; + unsigned short port = 0; + switch (reinterpret_cast<const socket_addr_type*>(addr)->sa_family) + { + case BOOST_ASIO_OS_DEF(AF_INET): + socket_ops::inet_ntop(BOOST_ASIO_OS_DEF(AF_INET), + &reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_addr, + addr_string, sizeof(addr_string), 0, op->ec_); + port = socket_ops::network_to_host_short( + reinterpret_cast<const sockaddr_in4_type*>(addr)->sin_port); + break; + case BOOST_ASIO_OS_DEF(AF_INET6): + socket_ops::inet_ntop(BOOST_ASIO_OS_DEF(AF_INET6), + &reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_addr, + addr_string, sizeof(addr_string), 0, op->ec_); + port = socket_ops::network_to_host_short( + reinterpret_cast<const sockaddr_in6_type*>(addr)->sin6_port); + break; + default: + op->ec_ = boost::asio::error::address_family_not_supported; + break; + } + + if (op->ec_) + { + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + try + { + async_manager_.async(impl.socket_->ConnectAsync( + ref new Windows::Networking::HostName( + winrt_utils::string(addr_string)), + winrt_utils::string(port)), op); + } + catch (Platform::Exception^ e) + { + op->ec_ = boost::system::error_code( + e->HResult, boost::system::system_category()); + io_service_.post_immediate_completion(op, is_continuation); + } +} + +std::size_t winrt_ssocket_service_base::do_send( + winrt_ssocket_service_base::base_implementation_type& impl, + const boost::asio::const_buffer& data, + socket_base::message_flags flags, boost::system::error_code& ec) +{ + if (flags) + { + ec = boost::asio::error::operation_not_supported; + return 0; + } + + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + try + { + buffer_sequence_adapter<boost::asio::const_buffer, + boost::asio::const_buffers_1> bufs(boost::asio::buffer(data)); + + if (bufs.all_empty()) + { + ec = boost::system::error_code(); + return 0; + } + + return async_manager_.sync( + impl.socket_->OutputStream->WriteAsync(bufs.buffers()[0]), ec); + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + return 0; + } +} + +void winrt_ssocket_service_base::start_send_op( + winrt_ssocket_service_base::base_implementation_type& impl, + const boost::asio::const_buffer& data, socket_base::message_flags flags, + winrt_async_op<unsigned int>* op, bool is_continuation) +{ + if (flags) + { + op->ec_ = boost::asio::error::operation_not_supported; + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + if (!is_open(impl)) + { + op->ec_ = boost::asio::error::bad_descriptor; + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + try + { + buffer_sequence_adapter<boost::asio::const_buffer, + boost::asio::const_buffers_1> bufs(boost::asio::buffer(data)); + + if (bufs.all_empty()) + { + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + async_manager_.async( + impl.socket_->OutputStream->WriteAsync(bufs.buffers()[0]), op); + } + catch (Platform::Exception^ e) + { + op->ec_ = boost::system::error_code(e->HResult, + boost::system::system_category()); + io_service_.post_immediate_completion(op, is_continuation); + } +} + +std::size_t winrt_ssocket_service_base::do_receive( + winrt_ssocket_service_base::base_implementation_type& impl, + const boost::asio::mutable_buffer& data, + socket_base::message_flags flags, boost::system::error_code& ec) +{ + if (flags) + { + ec = boost::asio::error::operation_not_supported; + return 0; + } + + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + try + { + buffer_sequence_adapter<boost::asio::mutable_buffer, + boost::asio::mutable_buffers_1> bufs(boost::asio::buffer(data)); + + if (bufs.all_empty()) + { + ec = boost::system::error_code(); + return 0; + } + + async_manager_.sync( + impl.socket_->InputStream->ReadAsync( + bufs.buffers()[0], bufs.buffers()[0]->Capacity, + Windows::Storage::Streams::InputStreamOptions::Partial), ec); + + std::size_t bytes_transferred = bufs.buffers()[0]->Length; + if (bytes_transferred == 0 && !ec) + { + ec = boost::asio::error::eof; + } + + return bytes_transferred; + } + catch (Platform::Exception^ e) + { + ec = boost::system::error_code(e->HResult, + boost::system::system_category()); + return 0; + } +} + +void winrt_ssocket_service_base::start_receive_op( + winrt_ssocket_service_base::base_implementation_type& impl, + const boost::asio::mutable_buffer& data, socket_base::message_flags flags, + winrt_async_op<Windows::Storage::Streams::IBuffer^>* op, + bool is_continuation) +{ + if (flags) + { + op->ec_ = boost::asio::error::operation_not_supported; + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + if (!is_open(impl)) + { + op->ec_ = boost::asio::error::bad_descriptor; + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + try + { + buffer_sequence_adapter<boost::asio::mutable_buffer, + boost::asio::mutable_buffers_1> bufs(boost::asio::buffer(data)); + + if (bufs.all_empty()) + { + io_service_.post_immediate_completion(op, is_continuation); + return; + } + + async_manager_.async( + impl.socket_->InputStream->ReadAsync( + bufs.buffers()[0], bufs.buffers()[0]->Capacity, + Windows::Storage::Streams::InputStreamOptions::Partial), op); + } + catch (Platform::Exception^ e) + { + op->ec_ = boost::system::error_code(e->HResult, + boost::system::system_category()); + io_service_.post_immediate_completion(op, is_continuation); + } +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_IMPL_WINRT_SSOCKET_SERVICE_BASE_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/winrt_timer_scheduler.hpp b/3rdParty/Boost/src/boost/asio/detail/impl/winrt_timer_scheduler.hpp new file mode 100644 index 0000000..ff1ee03 --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/winrt_timer_scheduler.hpp @@ -0,0 +1,81 @@ +// +// detail/impl/winrt_timer_scheduler.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP +#define BOOST_ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +template <typename Time_Traits> +void winrt_timer_scheduler::add_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_add_timer_queue(queue); +} + +// Remove a timer queue from the reactor. +template <typename Time_Traits> +void winrt_timer_scheduler::remove_timer_queue(timer_queue<Time_Traits>& queue) +{ + do_remove_timer_queue(queue); +} + +template <typename Time_Traits> +void winrt_timer_scheduler::schedule_timer(timer_queue<Time_Traits>& queue, + const typename Time_Traits::time_type& time, + typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + + if (shutdown_) + { + io_service_.post_immediate_completion(op, false); + return; + } + + bool earliest = queue.enqueue_timer(time, timer, op); + io_service_.work_started(); + if (earliest) + event_.signal(lock); +} + +template <typename Time_Traits> +std::size_t winrt_timer_scheduler::cancel_timer(timer_queue<Time_Traits>& queue, + typename timer_queue<Time_Traits>::per_timer_data& timer, + std::size_t max_cancelled) +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + op_queue<operation> ops; + std::size_t n = queue.cancel_timer(timer, ops, max_cancelled); + lock.unlock(); + io_service_.post_deferred_completions(ops); + return n; +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_HPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/winrt_timer_scheduler.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/winrt_timer_scheduler.ipp new file mode 100644 index 0000000..ef480ea --- /dev/null +++ b/3rdParty/Boost/src/boost/asio/detail/impl/winrt_timer_scheduler.ipp @@ -0,0 +1,124 @@ +// +// detail/impl/winrt_timer_scheduler.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// 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) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_IPP +#define BOOST_ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include <boost/asio/detail/config.hpp> + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include <boost/asio/detail/bind_handler.hpp> +#include <boost/asio/detail/winrt_timer_scheduler.hpp> + +#include <boost/asio/detail/push_options.hpp> + +namespace boost { +namespace asio { +namespace detail { + +winrt_timer_scheduler::winrt_timer_scheduler( + boost::asio::io_service& io_service) + : boost::asio::detail::service_base<winrt_timer_scheduler>(io_service), + io_service_(use_service<io_service_impl>(io_service)), + mutex_(), + event_(), + timer_queues_(), + thread_(0), + stop_thread_(false), + shutdown_(false) +{ + thread_ = new boost::asio::detail::thread( + bind_handler(&winrt_timer_scheduler::call_run_thread, this)); +} + +winrt_timer_scheduler::~winrt_timer_scheduler() +{ + shutdown_service(); +} + +void winrt_timer_scheduler::shutdown_service() +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + shutdown_ = true; + stop_thread_ = true; + event_.signal(lock); + lock.unlock(); + + if (thread_) + { + thread_->join(); + delete thread_; + thread_ = 0; + } + + op_queue<operation> ops; + timer_queues_.get_all_timers(ops); + io_service_.abandon_operations(ops); +} + +void winrt_timer_scheduler::fork_service(boost::asio::io_service::fork_event) +{ +} + +void winrt_timer_scheduler::init_task() +{ +} + +void winrt_timer_scheduler::run_thread() +{ + boost::asio::detail::mutex::scoped_lock lock(mutex_); + while (!stop_thread_) + { + const long max_wait_duration = 5 * 60 * 1000000; + long wait_duration = timer_queues_.wait_duration_usec(max_wait_duration); + event_.wait_for_usec(lock, wait_duration); + event_.clear(lock); + op_queue<operation> ops; + timer_queues_.get_ready_timers(ops); + if (!ops.empty()) + { + lock.unlock(); + io_service_.post_deferred_completions(ops); + lock.lock(); + } + } +} + +void winrt_timer_scheduler::call_run_thread(winrt_timer_scheduler* scheduler) +{ + scheduler->run_thread(); +} + +void winrt_timer_scheduler::do_add_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.insert(&queue); +} + +void winrt_timer_scheduler::do_remove_timer_queue(timer_queue_base& queue) +{ + mutex::scoped_lock lock(mutex_); + timer_queues_.erase(&queue); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include <boost/asio/detail/pop_options.hpp> + +#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_IMPL_WINRT_TIMER_SCHEDULER_IPP diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp index 8916934..08f3280 100644 --- a/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp +++ b/3rdParty/Boost/src/boost/asio/detail/impl/winsock_init.ipp @@ -2,7 +2,7 @@ // detail/impl/winsock_init.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) @@ -17,7 +17,7 @@ #include <boost/asio/detail/config.hpp> -#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/winsock_init.hpp> @@ -41,6 +41,14 @@ void winsock_init_base::startup(data& d, } } +void winsock_init_base::manual_startup(data& d) +{ + if (::InterlockedIncrement(&d.init_count_) == 1) + { + ::InterlockedExchange(&d.result_, 0); + } +} + void winsock_init_base::cleanup(data& d) { if (::InterlockedDecrement(&d.init_count_) == 0) @@ -49,6 +57,11 @@ void winsock_init_base::cleanup(data& d) } } +void winsock_init_base::manual_cleanup(data& d) +{ + ::InterlockedDecrement(&d.init_count_); +} + void winsock_init_base::throw_on_error(data& d) { long result = ::InterlockedExchangeAdd(&d.result_, 0); @@ -66,6 +79,6 @@ void winsock_init_base::throw_on_error(data& d) #include <boost/asio/detail/pop_options.hpp> -#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) #endif // BOOST_ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP |