summaryrefslogtreecommitdiff
path: root/boost/asio/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/asio/detail')
-rw-r--r--boost/asio/detail/config.hpp21
-rw-r--r--boost/asio/detail/dev_poll_reactor.hpp12
-rw-r--r--boost/asio/detail/epoll_reactor.hpp13
-rw-r--r--boost/asio/detail/impl/dev_poll_reactor.ipp5
-rw-r--r--boost/asio/detail/impl/epoll_reactor.ipp39
-rw-r--r--boost/asio/detail/impl/kqueue_reactor.ipp28
-rw-r--r--boost/asio/detail/impl/reactive_descriptor_service.ipp19
-rw-r--r--boost/asio/detail/impl/reactive_socket_service_base.ipp14
-rw-r--r--boost/asio/detail/impl/select_reactor.ipp5
-rw-r--r--boost/asio/detail/impl/signal_set_service.ipp6
-rw-r--r--boost/asio/detail/impl/win_iocp_socket_service_base.ipp19
-rw-r--r--boost/asio/detail/kqueue_reactor.hpp12
-rw-r--r--boost/asio/detail/op_queue.hpp6
-rw-r--r--boost/asio/detail/select_reactor.hpp13
-rw-r--r--boost/asio/detail/socket_types.hpp6
-rw-r--r--boost/asio/detail/winapi_thread.hpp6
16 files changed, 184 insertions, 40 deletions
diff --git a/boost/asio/detail/config.hpp b/boost/asio/detail/config.hpp
index baeb86d78e..afe400e5b7 100644
--- a/boost/asio/detail/config.hpp
+++ b/boost/asio/detail/config.hpp
@@ -65,7 +65,8 @@
#if !defined(BOOST_ASIO_MSVC)
# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
# define BOOST_ASIO_MSVC BOOST_MSVC
-# elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__)
+# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \
+ || (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))
# define BOOST_ASIO_MSVC _MSC_VER
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
#endif // defined(BOOST_ASIO_MSVC)
@@ -154,6 +155,11 @@
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
+# if defined(BOOST_ASIO_MSVC)
+# if (_MSC_VER >= 1900)
+# define BOOST_ASIO_HAS_VARIADIC_TEMPLATES 1
+# endif // (_MSC_VER >= 1900)
+# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_VARIADIC_TEMPLATES)
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
@@ -172,6 +178,11 @@
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
+# if defined(BOOST_ASIO_MSVC)
+# if (_MSC_VER >= 1900)
+# define BOOST_ASIO_HAS_CONSTEXPR 1
+# endif // (_MSC_VER >= 1900)
+# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_CONSTEXPR)
#endif // !defined(BOOST_ASIO_HAS_CONSTEXPR)
#if !defined(BOOST_ASIO_CONSTEXPR)
@@ -296,11 +307,11 @@
# endif // (__cplusplus >= 201103)
# endif // defined(__clang__)
# if defined(__GNUC__)
-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_ASIO_HAS_STD_ATOMIC 1
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1700)
@@ -988,12 +999,14 @@
# if defined(__linux__)
# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
-# if !defined(__INTEL_COMPILER) && !defined(__ICL)
+# if !defined(__INTEL_COMPILER) && !defined(__ICL) \
+ && !(defined(__clang__) && defined(__ANDROID__))
# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
# define BOOST_ASIO_THREAD_KEYWORD __thread
# elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
# define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
+ // && !(defined(__clang__) && defined(__ANDROID__))
# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
# endif // defined(__linux__)
diff --git a/boost/asio/detail/dev_poll_reactor.hpp b/boost/asio/detail/dev_poll_reactor.hpp
index db6f3d1b8f..17f57d5221 100644
--- a/boost/asio/detail/dev_poll_reactor.hpp
+++ b/boost/asio/detail/dev_poll_reactor.hpp
@@ -102,15 +102,21 @@ public:
BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
// Cancel any operations that are running against the descriptor and remove
- // its registration from the reactor.
+ // its registration from the reactor. The reactor resources associated with
+ // the descriptor must be released by calling cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
per_descriptor_data&, bool closing);
- // Cancel any operations that are running against the descriptor and remove
- // its registration from the reactor.
+ // Remove the descriptor's registration from the reactor. The reactor
+ // resources associated with the descriptor must be released by calling
+ // cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_internal_descriptor(
socket_type descriptor, per_descriptor_data&);
+ // Perform any post-deregistration cleanup tasks associated with the
+ // descriptor data.
+ BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
+
// Add a new timer queue to the reactor.
template <typename Time_Traits>
void add_timer_queue(timer_queue<Time_Traits>& queue);
diff --git a/boost/asio/detail/epoll_reactor.hpp b/boost/asio/detail/epoll_reactor.hpp
index 64c5b2704c..34ed0370f5 100644
--- a/boost/asio/detail/epoll_reactor.hpp
+++ b/boost/asio/detail/epoll_reactor.hpp
@@ -63,6 +63,7 @@ public:
BOOST_ASIO_DECL descriptor_state();
void set_ready_events(uint32_t events) { task_result_ = events; }
+ void add_ready_events(uint32_t events) { task_result_ |= events; }
BOOST_ASIO_DECL operation* perform_io(uint32_t events);
BOOST_ASIO_DECL static void do_complete(
io_service_impl* owner, operation* base,
@@ -123,14 +124,22 @@ public:
per_descriptor_data& descriptor_data);
// Cancel any operations that are running against the descriptor and remove
- // its registration from the reactor.
+ // its registration from the reactor. The reactor resources associated with
+ // the descriptor must be released by calling cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
per_descriptor_data& descriptor_data, bool closing);
- // Remote the descriptor's registration from the reactor.
+ // Remove the descriptor's registration from the reactor. The reactor
+ // resources associated with the descriptor must be released by calling
+ // cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_internal_descriptor(
socket_type descriptor, per_descriptor_data& descriptor_data);
+ // Perform any post-deregistration cleanup tasks associated with the
+ // descriptor data.
+ BOOST_ASIO_DECL void cleanup_descriptor_data(
+ per_descriptor_data& descriptor_data);
+
// Add a new timer queue to the reactor.
template <typename Time_Traits>
void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
diff --git a/boost/asio/detail/impl/dev_poll_reactor.ipp b/boost/asio/detail/impl/dev_poll_reactor.ipp
index efe2ba7086..7efb05ed02 100644
--- a/boost/asio/detail/impl/dev_poll_reactor.ipp
+++ b/boost/asio/detail/impl/dev_poll_reactor.ipp
@@ -235,6 +235,11 @@ void dev_poll_reactor::deregister_internal_descriptor(
op_queue_[i].cancel_operations(descriptor, ops, ec);
}
+void dev_poll_reactor::cleanup_descriptor_data(
+ dev_poll_reactor::per_descriptor_data&)
+{
+}
+
void dev_poll_reactor::run(bool block, op_queue<operation>& ops)
{
boost::asio::detail::mutex::scoped_lock lock(mutex_);
diff --git a/boost/asio/detail/impl/epoll_reactor.ipp b/boost/asio/detail/impl/epoll_reactor.ipp
index 610ce31ce5..3d3d244e0a 100644
--- a/boost/asio/detail/impl/epoll_reactor.ipp
+++ b/boost/asio/detail/impl/epoll_reactor.ipp
@@ -359,10 +359,16 @@ void epoll_reactor::deregister_descriptor(socket_type descriptor,
descriptor_lock.unlock();
- free_descriptor_state(descriptor_data);
- descriptor_data = 0;
-
io_service_.post_deferred_completions(ops);
+
+ // Leave descriptor_data set so that it will be freed by the subsequent
+ // call to cleanup_descriptor_data.
+ }
+ else
+ {
+ // We are shutting down, so prevent cleanup_descriptor_data from freeing
+ // the descriptor_data object and let the destructor free it instead.
+ descriptor_data = 0;
}
}
@@ -388,6 +394,22 @@ void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
descriptor_lock.unlock();
+ // Leave descriptor_data set so that it will be freed by the subsequent
+ // call to cleanup_descriptor_data.
+ }
+ else
+ {
+ // We are shutting down, so prevent cleanup_descriptor_data from freeing
+ // the descriptor_data object and let the destructor free it instead.
+ descriptor_data = 0;
+ }
+}
+
+void epoll_reactor::cleanup_descriptor_data(
+ per_descriptor_data& descriptor_data)
+{
+ if (descriptor_data)
+ {
free_descriptor_state(descriptor_data);
descriptor_data = 0;
}
@@ -451,8 +473,15 @@ void epoll_reactor::run(bool block, op_queue<operation>& ops)
// don't call work_started() here. This still allows the io_service to
// stop if the only remaining operations are descriptor operations.
descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
- descriptor_data->set_ready_events(events[i].events);
- ops.push(descriptor_data);
+ if (!ops.is_enqueued(descriptor_data))
+ {
+ descriptor_data->set_ready_events(events[i].events);
+ ops.push(descriptor_data);
+ }
+ else
+ {
+ descriptor_data->add_ready_events(events[i].events);
+ }
}
}
diff --git a/boost/asio/detail/impl/kqueue_reactor.ipp b/boost/asio/detail/impl/kqueue_reactor.ipp
index b4a7a10b71..8057606ce6 100644
--- a/boost/asio/detail/impl/kqueue_reactor.ipp
+++ b/boost/asio/detail/impl/kqueue_reactor.ipp
@@ -312,10 +312,16 @@ void kqueue_reactor::deregister_descriptor(socket_type descriptor,
descriptor_lock.unlock();
- free_descriptor_state(descriptor_data);
- descriptor_data = 0;
-
io_service_.post_deferred_completions(ops);
+
+ // Leave descriptor_data set so that it will be freed by the subsequent
+ // call to cleanup_descriptor_data.
+ }
+ else
+ {
+ // We are shutting down, so prevent cleanup_descriptor_data from freeing
+ // the descriptor_data object and let the destructor free it instead.
+ descriptor_data = 0;
}
}
@@ -345,6 +351,22 @@ void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor,
descriptor_lock.unlock();
+ // Leave descriptor_data set so that it will be freed by the subsequent
+ // call to cleanup_descriptor_data.
+ }
+ else
+ {
+ // We are shutting down, so prevent cleanup_descriptor_data from freeing
+ // the descriptor_data object and let the destructor free it instead.
+ descriptor_data = 0;
+ }
+}
+
+void kqueue_reactor::cleanup_descriptor_data(
+ per_descriptor_data& descriptor_data)
+{
+ if (descriptor_data)
+ {
free_descriptor_state(descriptor_data);
descriptor_data = 0;
}
diff --git a/boost/asio/detail/impl/reactive_descriptor_service.ipp b/boost/asio/detail/impl/reactive_descriptor_service.ipp
index 56caec9fd3..a0300c47d0 100644
--- a/boost/asio/detail/impl/reactive_descriptor_service.ipp
+++ b/boost/asio/detail/impl/reactive_descriptor_service.ipp
@@ -88,10 +88,12 @@ void reactive_descriptor_service::destroy(
reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
(impl.state_ & descriptor_ops::possible_dup) == 0);
- }
- boost::system::error_code ignored_ec;
- descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
+ boost::system::error_code ignored_ec;
+ descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
}
boost::system::error_code reactive_descriptor_service::assign(
@@ -128,9 +130,15 @@ boost::system::error_code reactive_descriptor_service::close(
reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
(impl.state_ & descriptor_ops::possible_dup) == 0);
- }
- descriptor_ops::close(impl.descriptor_, impl.state_, ec);
+ descriptor_ops::close(impl.descriptor_, impl.state_, ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
// The descriptor is closed by the OS even if close() returns an error.
//
@@ -154,6 +162,7 @@ reactive_descriptor_service::release(
BOOST_ASIO_HANDLER_OPERATION(("descriptor", &impl, "release"));
reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, false);
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
construct(impl);
}
diff --git a/boost/asio/detail/impl/reactive_socket_service_base.ipp b/boost/asio/detail/impl/reactive_socket_service_base.ipp
index 21e77e9f93..3594ae0528 100644
--- a/boost/asio/detail/impl/reactive_socket_service_base.ipp
+++ b/boost/asio/detail/impl/reactive_socket_service_base.ipp
@@ -89,6 +89,8 @@ void reactive_socket_service_base::destroy(
boost::system::error_code ignored_ec;
socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
}
}
@@ -102,9 +104,15 @@ boost::system::error_code reactive_socket_service_base::close(
reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_,
(impl.state_ & socket_ops::possible_dup) == 0);
- }
- socket_ops::close(impl.socket_, impl.state_, false, ec);
+ socket_ops::close(impl.socket_, impl.state_, false, ec);
+
+ reactor_.cleanup_descriptor_data(impl.reactor_data_);
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
// The descriptor is closed by the OS even if close() returns an error.
//
@@ -224,7 +232,7 @@ void reactive_socket_service_base::start_accept_op(
reactor_op* op, bool is_continuation, bool peer_is_open)
{
if (!peer_is_open)
- start_op(impl, reactor::read_op, op, true, is_continuation, false);
+ start_op(impl, reactor::read_op, op, is_continuation, true, false);
else
{
op->ec_ = boost::asio::error::already_open;
diff --git a/boost/asio/detail/impl/select_reactor.ipp b/boost/asio/detail/impl/select_reactor.ipp
index 80686eaf97..869f73492b 100644
--- a/boost/asio/detail/impl/select_reactor.ipp
+++ b/boost/asio/detail/impl/select_reactor.ipp
@@ -163,6 +163,11 @@ void select_reactor::deregister_internal_descriptor(
op_queue_[i].cancel_operations(descriptor, ops);
}
+void select_reactor::cleanup_descriptor_data(
+ select_reactor::per_descriptor_data&)
+{
+}
+
void select_reactor::run(bool block, op_queue<operation>& ops)
{
boost::asio::detail::mutex::scoped_lock lock(mutex_);
diff --git a/boost/asio/detail/impl/signal_set_service.ipp b/boost/asio/detail/impl/signal_set_service.ipp
index 56313e0923..95ea8bee21 100644
--- a/boost/asio/detail/impl/signal_set_service.ipp
+++ b/boost/asio/detail/impl/signal_set_service.ipp
@@ -187,6 +187,7 @@ void signal_set_service::fork_service(
state->fork_prepared_ = true;
lock.unlock();
reactor_.deregister_internal_descriptor(read_descriptor, reactor_data_);
+ reactor_.cleanup_descriptor_data(reactor_data_);
}
break;
case boost::asio::io_service::fork_parent:
@@ -539,8 +540,9 @@ void signal_set_service::remove_service(signal_set_service* service)
// Disable the pipe readiness notifications.
int read_descriptor = state->read_descriptor_;
lock.unlock();
- service->reactor_.deregister_descriptor(
- read_descriptor, service->reactor_data_, false);
+ service->reactor_.deregister_internal_descriptor(
+ read_descriptor, service->reactor_data_);
+ service->reactor_.cleanup_descriptor_data(service->reactor_data_);
lock.lock();
#endif // !defined(BOOST_ASIO_WINDOWS)
// && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
diff --git a/boost/asio/detail/impl/win_iocp_socket_service_base.ipp b/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
index 22818f7e92..93f5ed0713 100644
--- a/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
+++ b/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
@@ -177,9 +177,16 @@ boost::system::error_code win_iocp_socket_service_base::close(
reinterpret_cast<void**>(&reactor_), 0, 0));
if (r)
r->deregister_descriptor(impl.socket_, impl.reactor_data_, true);
- }
- socket_ops::close(impl.socket_, impl.state_, false, ec);
+ socket_ops::close(impl.socket_, impl.state_, false, ec);
+
+ if (r)
+ r->cleanup_descriptor_data(impl.reactor_data_);
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
impl.socket_ = invalid_socket;
impl.state_ = 0;
@@ -629,10 +636,14 @@ void win_iocp_socket_service_base::close_for_destruction(
reinterpret_cast<void**>(&reactor_), 0, 0));
if (r)
r->deregister_descriptor(impl.socket_, impl.reactor_data_, true);
+
+ boost::system::error_code ignored_ec;
+ socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
+
+ if (r)
+ r->cleanup_descriptor_data(impl.reactor_data_);
}
- boost::system::error_code ignored_ec;
- socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
impl.socket_ = invalid_socket;
impl.state_ = 0;
impl.cancel_token_.reset();
diff --git a/boost/asio/detail/kqueue_reactor.hpp b/boost/asio/detail/kqueue_reactor.hpp
index 6aba2b264f..c6182b4d55 100644
--- a/boost/asio/detail/kqueue_reactor.hpp
+++ b/boost/asio/detail/kqueue_reactor.hpp
@@ -125,14 +125,22 @@ public:
per_descriptor_data& descriptor_data);
// Cancel any operations that are running against the descriptor and remove
- // its registration from the reactor.
+ // its registration from the reactor. The reactor resources associated with
+ // the descriptor must be released by calling cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
per_descriptor_data& descriptor_data, bool closing);
- // Remote the descriptor's registration from the reactor.
+ // Remove the descriptor's registration from the reactor. The reactor
+ // resources associated with the descriptor must be released by calling
+ // cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_internal_descriptor(
socket_type descriptor, per_descriptor_data& descriptor_data);
+ // Perform any post-deregistration cleanup tasks associated with the
+ // descriptor data.
+ BOOST_ASIO_DECL void cleanup_descriptor_data(
+ per_descriptor_data& descriptor_data);
+
// Add a new timer queue to the reactor.
template <typename Time_Traits>
void add_timer_queue(timer_queue<Time_Traits>& queue);
diff --git a/boost/asio/detail/op_queue.hpp b/boost/asio/detail/op_queue.hpp
index 9605248567..89f318eedf 100644
--- a/boost/asio/detail/op_queue.hpp
+++ b/boost/asio/detail/op_queue.hpp
@@ -139,6 +139,12 @@ public:
return front_ == 0;
}
+ // Test whether an operation is already enqueued.
+ bool is_enqueued(Operation* o) const
+ {
+ return op_queue_access::next(o) != 0 || back_ == o;
+ }
+
private:
friend class op_queue_access;
diff --git a/boost/asio/detail/select_reactor.hpp b/boost/asio/detail/select_reactor.hpp
index 69b04c82b5..d6f75242e5 100644
--- a/boost/asio/detail/select_reactor.hpp
+++ b/boost/asio/detail/select_reactor.hpp
@@ -107,13 +107,20 @@ public:
BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
// Cancel any operations that are running against the descriptor and remove
- // its registration from the reactor.
+ // its registration from the reactor. The reactor resources associated with
+ // the descriptor must be released by calling cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
per_descriptor_data&, bool closing);
- // Remote the descriptor's registration from the reactor.
+ // Remove the descriptor's registration from the reactor. The reactor
+ // resources associated with the descriptor must be released by calling
+ // cleanup_descriptor_data.
BOOST_ASIO_DECL void deregister_internal_descriptor(
- socket_type descriptor, per_descriptor_data& descriptor_data);
+ socket_type descriptor, per_descriptor_data&);
+
+ // Perform any post-deregistration cleanup tasks associated with the
+ // descriptor data.
+ BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
// Move descriptor registration from one descriptor_data object to another.
BOOST_ASIO_DECL void move_descriptor(socket_type descriptor,
diff --git a/boost/asio/detail/socket_types.hpp b/boost/asio/detail/socket_types.hpp
index 8467118b54..0768f70077 100644
--- a/boost/asio/detail/socket_types.hpp
+++ b/boost/asio/detail/socket_types.hpp
@@ -57,7 +57,11 @@
# include <boost/asio/detail/old_win_sdk_compat.hpp>
#else
# include <sys/ioctl.h>
-# if !defined(__SYMBIAN32__)
+# if (defined(__MACH__) && defined(__APPLE__)) \
+ || defined(__FreeBSD__) || defined(__NetBSD__) \
+ || defined(__OpenBSD__) || defined(__linux__)
+# include <poll.h>
+# elif !defined(__SYMBIAN32__)
# include <sys/poll.h>
# endif
# include <sys/types.h>
diff --git a/boost/asio/detail/winapi_thread.hpp b/boost/asio/detail/winapi_thread.hpp
index 204e73f42a..79aba9b519 100644
--- a/boost/asio/detail/winapi_thread.hpp
+++ b/boost/asio/detail/winapi_thread.hpp
@@ -20,8 +20,8 @@
#if defined(BOOST_ASIO_WINDOWS)
#if defined(BOOST_ASIO_WINDOWS_APP) || defined(UNDER_CE)
-#include <memory>
#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/scoped_ptr.hpp>
#include <boost/asio/detail/socket_types.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
@@ -42,7 +42,7 @@ public:
template <typename Function>
winapi_thread(Function f, unsigned int = 0)
{
- std::auto_ptr<func_base> arg(new func<Function>(f));
+ scoped_ptr<func_base> arg(new func<Function>(f));
DWORD thread_id = 0;
thread_ = ::CreateThread(0, 0, winapi_thread_function,
arg.get(), 0, &thread_id);
@@ -106,7 +106,7 @@ private:
inline DWORD WINAPI winapi_thread_function(LPVOID arg)
{
- std::auto_ptr<winapi_thread::func_base> func(
+ scoped_ptr<winapi_thread::func_base> func(
static_cast<winapi_thread::func_base*>(arg));
func->run();
return 0;