asio sync
This commit is contained in:
parent
732c3d8674
commit
dc2f24344c
|
@ -27,7 +27,7 @@
|
|||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# if defined(_HAS_ITERATOR_DEBUGGING)
|
||||
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
|
||||
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||
# define ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||
|
@ -390,6 +390,11 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
~buffer_debug_check()
|
||||
{
|
||||
iter_ = Iterator();
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
*iter_;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "asio/detail/kqueue_reactor.hpp"
|
||||
#include "asio/detail/select_reactor.hpp"
|
||||
#include "asio/detail/service_base.hpp"
|
||||
#include "asio/detail/win_iocp_io_service.hpp"
|
||||
|
||||
namespace asio {
|
||||
|
||||
|
@ -62,7 +63,7 @@ private:
|
|||
// The type of the platform-specific implementation.
|
||||
#if defined(ASIO_HAS_IOCP)
|
||||
typedef detail::deadline_timer_service<
|
||||
traits_type, detail::select_reactor<true> > service_impl_type;
|
||||
traits_type, detail::win_iocp_io_service> service_impl_type;
|
||||
#elif defined(ASIO_HAS_EPOLL)
|
||||
typedef detail::deadline_timer_service<
|
||||
traits_type, detail::epoll_reactor<false> > service_impl_type;
|
||||
|
|
|
@ -140,22 +140,13 @@ public:
|
|||
|
||||
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
||||
{
|
||||
::pollfd ev = { 0 };
|
||||
ev.fd = descriptor;
|
||||
::pollfd& ev = add_pending_event_change(descriptor);
|
||||
ev.events = POLLIN | POLLERR | POLLHUP;
|
||||
if (write_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLOUT;
|
||||
if (except_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLPRI;
|
||||
ev.revents = 0;
|
||||
|
||||
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
|
||||
if (result != sizeof(ev))
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,22 +166,13 @@ public:
|
|||
|
||||
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
||||
{
|
||||
::pollfd ev = { 0 };
|
||||
ev.fd = descriptor;
|
||||
::pollfd& ev = add_pending_event_change(descriptor);
|
||||
ev.events = POLLOUT | POLLERR | POLLHUP;
|
||||
if (read_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLIN;
|
||||
if (except_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLPRI;
|
||||
ev.revents = 0;
|
||||
|
||||
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
|
||||
if (result != sizeof(ev))
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,22 +188,13 @@ public:
|
|||
|
||||
if (except_op_queue_.enqueue_operation(descriptor, handler))
|
||||
{
|
||||
::pollfd ev = { 0 };
|
||||
ev.fd = descriptor;
|
||||
::pollfd& ev = add_pending_event_change(descriptor);
|
||||
ev.events = POLLPRI | POLLERR | POLLHUP;
|
||||
if (read_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLIN;
|
||||
if (write_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLOUT;
|
||||
ev.revents = 0;
|
||||
|
||||
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
|
||||
if (result != sizeof(ev))
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,21 +214,11 @@ public:
|
|||
&& need_mod;
|
||||
if (need_mod)
|
||||
{
|
||||
::pollfd ev = { 0 };
|
||||
ev.fd = descriptor;
|
||||
::pollfd& ev = add_pending_event_change(descriptor);
|
||||
ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP;
|
||||
if (read_op_queue_.has_operation(descriptor))
|
||||
ev.events |= POLLIN;
|
||||
ev.revents = 0;
|
||||
|
||||
int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
|
||||
if (result != sizeof(ev))
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
interrupter_.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,11 +248,9 @@ public:
|
|||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
// Remove the descriptor from /dev/poll.
|
||||
::pollfd ev = { 0 };
|
||||
ev.fd = descriptor;
|
||||
::pollfd& ev = add_pending_event_change(descriptor);
|
||||
ev.events = POLLREMOVE;
|
||||
ev.revents = 0;
|
||||
::write(dev_poll_fd_, &ev, sizeof(ev));
|
||||
interrupter_.interrupt();
|
||||
|
||||
// Cancel any outstanding operations associated with the descriptor.
|
||||
cancel_ops_unlocked(descriptor);
|
||||
|
@ -374,6 +335,26 @@ private:
|
|||
return;
|
||||
}
|
||||
|
||||
// Write the pending event registration changes to the /dev/poll descriptor.
|
||||
std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size();
|
||||
errno = 0;
|
||||
int result = ::write(dev_poll_fd_,
|
||||
&pending_event_changes_[0], events_size);
|
||||
if (result != static_cast<int>(events_size))
|
||||
{
|
||||
for (std::size_t i = 0; i < pending_event_changes_.size(); ++i)
|
||||
{
|
||||
int descriptor = pending_event_changes_[i].fd;
|
||||
asio::error_code ec = asio::error_code(
|
||||
errno, asio::error::get_system_category());
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
pending_event_changes_.clear();
|
||||
pending_event_change_index_.clear();
|
||||
|
||||
int timeout = block ? get_timeout() : 0;
|
||||
wait_in_progress_ = true;
|
||||
lock.unlock();
|
||||
|
@ -454,7 +435,7 @@ private:
|
|||
if (result != sizeof(ev))
|
||||
{
|
||||
ec = asio::error_code(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
|
@ -513,7 +494,7 @@ private:
|
|||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"/dev/poll"));
|
||||
}
|
||||
return fd;
|
||||
|
@ -588,12 +569,39 @@ private:
|
|||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Add a pending event entry for the given descriptor.
|
||||
::pollfd& add_pending_event_change(int descriptor)
|
||||
{
|
||||
hash_map<int, std::size_t>::iterator iter
|
||||
= pending_event_change_index_.find(descriptor);
|
||||
if (iter == pending_event_change_index_.end())
|
||||
{
|
||||
std::size_t index = pending_event_changes_.size();
|
||||
pending_event_changes_.reserve(pending_event_changes_.size() + 1);
|
||||
pending_event_change_index_.insert(std::make_pair(descriptor, index));
|
||||
pending_event_changes_.push_back(::pollfd());
|
||||
pending_event_changes_[index].fd = descriptor;
|
||||
pending_event_changes_[index].revents = 0;
|
||||
return pending_event_changes_[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return pending_event_changes_[iter->second];
|
||||
}
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
// The /dev/poll file descriptor.
|
||||
int dev_poll_fd_;
|
||||
|
||||
// Vector of /dev/poll events waiting to be written to the descriptor.
|
||||
std::vector< ::pollfd> pending_event_changes_;
|
||||
|
||||
// Hash map to associate a descriptor with a pending event change index.
|
||||
hash_map<int, std::size_t> pending_event_change_index_;
|
||||
|
||||
// Whether the DP_POLL operation is currently in progress
|
||||
bool wait_in_progress_;
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ public:
|
|||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ public:
|
|||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ public:
|
|||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ private:
|
|||
if (result != 0)
|
||||
{
|
||||
ec = asio::error_code(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
|
@ -518,7 +518,7 @@ private:
|
|||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"epoll"));
|
||||
}
|
||||
return fd;
|
||||
|
|
|
@ -151,7 +151,7 @@ public:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ public:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ public:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ public:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ private:
|
|||
if (events[i].flags & EV_ERROR)
|
||||
{
|
||||
asio::error_code error(
|
||||
events[i].data, asio::error::system_category);
|
||||
events[i].data, asio::error::get_system_category());
|
||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ private:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code error(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ private:
|
|||
if (events[i].flags & EV_ERROR)
|
||||
{
|
||||
asio::error_code error(
|
||||
events[i].data, asio::error::system_category);
|
||||
events[i].data, asio::error::get_system_category());
|
||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
else
|
||||
|
@ -458,7 +458,7 @@ private:
|
|||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code error(errno,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ private:
|
|||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"kqueue"));
|
||||
}
|
||||
return fd;
|
||||
|
|
|
@ -51,7 +51,8 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
asio::error_code ec(errno, asio::error::system_category);
|
||||
asio::error_code ec(errno,
|
||||
asio::error::get_system_category());
|
||||
asio::system_error e(ec, "pipe_select_interrupter");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -70,7 +71,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -83,7 +85,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"tss");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -157,7 +157,8 @@ public:
|
|||
|
||||
if (int err = reactor_.register_descriptor(sock.get()))
|
||||
{
|
||||
ec = asio::error_code(err, asio::error::system_category);
|
||||
ec = asio::error_code(err,
|
||||
asio::error::get_system_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
@ -181,7 +182,8 @@ public:
|
|||
|
||||
if (int err = reactor_.register_descriptor(native_socket))
|
||||
{
|
||||
ec = asio::error_code(err, asio::error::system_category);
|
||||
ec = asio::error_code(err,
|
||||
asio::error::get_system_category());
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
@ -1489,7 +1491,7 @@ public:
|
|||
if (connect_error)
|
||||
{
|
||||
ec = asio::error_code(connect_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
io_service_.post(bind_handler(handler_, ec));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -48,10 +48,11 @@ extern "C" unsigned int if_nametoindex(const char*);
|
|||
|
||||
inline void clear_error(asio::error_code& ec)
|
||||
{
|
||||
errno = 0;
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
WSASetLastError(0);
|
||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#else
|
||||
errno = 0;
|
||||
#endif
|
||||
ec = asio::error_code();
|
||||
}
|
||||
|
||||
|
@ -61,9 +62,10 @@ inline ReturnType error_wrapper(ReturnType return_value,
|
|||
{
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
ec = asio::error_code(WSAGetLastError(),
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
#else
|
||||
ec = asio::error_code(errno, asio::error::system_category);
|
||||
ec = asio::error_code(errno,
|
||||
asio::error::get_system_category());
|
||||
#endif
|
||||
return return_value;
|
||||
}
|
||||
|
@ -100,6 +102,10 @@ inline socket_type accept(socket_type s, socket_addr_type* addr,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
|
||||
return new_s;
|
||||
}
|
||||
|
||||
|
@ -114,14 +120,25 @@ inline int bind(socket_type s, const socket_addr_type* addr,
|
|||
std::size_t addrlen, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(call_bind(&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||
int result = error_wrapper(call_bind(
|
||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
inline int close(socket_type s, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return error_wrapper(::closesocket(s), ec);
|
||||
int result = error_wrapper(::closesocket(s), ec);
|
||||
# if defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return error_wrapper(::close(s), ec);
|
||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
|
@ -130,7 +147,12 @@ inline int close(socket_type s, asio::error_code& ec)
|
|||
inline int shutdown(socket_type s, int what, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(::shutdown(s, what), ec);
|
||||
int result = error_wrapper(::shutdown(s, what), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename SockLenType>
|
||||
|
@ -144,14 +166,24 @@ inline int connect(socket_type s, const socket_addr_type* addr,
|
|||
std::size_t addrlen, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(call_connect(
|
||||
int result = error_wrapper(call_connect(
|
||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
inline int listen(socket_type s, int backlog, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(::listen(s, backlog), ec);
|
||||
int result = error_wrapper(::listen(s, backlog), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
|
@ -217,6 +249,9 @@ inline int recv(socket_type s, buf* bufs, size_t count, int flags,
|
|||
recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
|
||||
if (result != 0)
|
||||
return -1;
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return bytes_transferred;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
msghdr msg = msghdr();
|
||||
|
@ -242,6 +277,9 @@ inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
|
|||
*addrlen = (std::size_t)tmp_addrlen;
|
||||
if (result != 0)
|
||||
return -1;
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return bytes_transferred;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
msghdr msg = msghdr();
|
||||
|
@ -268,6 +306,9 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
|
|||
send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
|
||||
if (result != 0)
|
||||
return -1;
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return bytes_transferred;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
msghdr msg = msghdr();
|
||||
|
@ -290,9 +331,13 @@ inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
|
|||
DWORD send_buf_count = static_cast<DWORD>(count);
|
||||
DWORD bytes_transferred = 0;
|
||||
int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
|
||||
send_buf_count, &bytes_transferred, flags, addr, addrlen, 0, 0), ec);
|
||||
send_buf_count, &bytes_transferred, flags, addr,
|
||||
static_cast<int>(addrlen), 0, 0), ec);
|
||||
if (result != 0)
|
||||
return -1;
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return bytes_transferred;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
msghdr msg = msghdr();
|
||||
|
@ -327,6 +372,10 @@ inline socket_type socket(int af, int type, int protocol,
|
|||
reinterpret_cast<const char*>(&optval), sizeof(optval));
|
||||
}
|
||||
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
|
||||
return s;
|
||||
#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
||||
socket_type s = error_wrapper(::socket(af, type, protocol), ec);
|
||||
|
@ -385,8 +434,13 @@ inline int setsockopt(socket_type s, int level, int optname,
|
|||
return -1;
|
||||
#else // defined(__BORLANDC__)
|
||||
clear_error(ec);
|
||||
return error_wrapper(call_setsockopt(&msghdr::msg_namelen,
|
||||
int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
|
||||
s, level, optname, optval, optlen), ec);
|
||||
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#endif // defined(__BORLANDC__)
|
||||
}
|
||||
|
||||
|
@ -455,6 +509,10 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
|||
*static_cast<DWORD*>(optval) = 1;
|
||||
clear_error(ec);
|
||||
}
|
||||
# if defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
clear_error(ec);
|
||||
|
@ -490,8 +548,13 @@ inline int getpeername(socket_type s, socket_addr_type* addr,
|
|||
std::size_t* addrlen, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(call_getpeername(
|
||||
int result = error_wrapper(call_getpeername(
|
||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename SockLenType>
|
||||
|
@ -508,8 +571,13 @@ inline int getsockname(socket_type s, socket_addr_type* addr,
|
|||
std::size_t* addrlen, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(call_getsockname(
|
||||
int result = error_wrapper(call_getsockname(
|
||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
|
||||
|
@ -517,7 +585,12 @@ inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
|
|||
{
|
||||
clear_error(ec);
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return error_wrapper(::ioctlsocket(s, cmd, arg), ec);
|
||||
int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
|
||||
# if defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return error_wrapper(::ioctl(s, cmd, arg), ec);
|
||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
|
@ -556,8 +629,13 @@ inline int select(int nfds, fd_set* readfds, fd_set* writefds,
|
|||
return error_wrapper(::pselect(nfds, readfds,
|
||||
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
|
||||
#else
|
||||
return error_wrapper(::select(nfds, readfds,
|
||||
int result = error_wrapper(::select(nfds, readfds,
|
||||
writefds, exceptfds, timeout), ec);
|
||||
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result >= 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -568,7 +646,12 @@ inline int poll_read(socket_type s, asio::error_code& ec)
|
|||
FD_ZERO(&fds);
|
||||
FD_SET(s, &fds);
|
||||
clear_error(ec);
|
||||
return error_wrapper(::select(s, &fds, 0, 0, 0), ec);
|
||||
int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec);
|
||||
# if defined(UNDER_CE)
|
||||
if (result >= 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
pollfd fds;
|
||||
fds.fd = s;
|
||||
|
@ -586,7 +669,12 @@ inline int poll_write(socket_type s, asio::error_code& ec)
|
|||
FD_ZERO(&fds);
|
||||
FD_SET(s, &fds);
|
||||
clear_error(ec);
|
||||
return error_wrapper(::select(s, 0, &fds, 0, 0), ec);
|
||||
int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec);
|
||||
# if defined(UNDER_CE)
|
||||
if (result >= 0)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
return result;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
pollfd fds;
|
||||
fds.fd = s;
|
||||
|
@ -634,9 +722,17 @@ inline 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)
|
||||
LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
|
||||
int result = error_wrapper(::WSAAddressToStringW(
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
address_length, 0, string_buffer, &string_length), ec);
|
||||
::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);
|
||||
#else
|
||||
int result = error_wrapper(::WSAAddressToStringA(
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
address_length, 0, dest, &string_length), ec);
|
||||
#endif
|
||||
|
||||
// Windows may set error code on success.
|
||||
if (result != socket_error_retval)
|
||||
|
@ -680,10 +776,20 @@ inline int inet_pton(int af, const char* src, void* dest,
|
|||
|
||||
sockaddr_storage_type address;
|
||||
int address_length = sizeof(sockaddr_storage_type);
|
||||
#if defined(BOOST_NO_ANSI_APIS)
|
||||
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);
|
||||
int result = error_wrapper(::WSAStringToAddressW(
|
||||
wide_buffer, af, 0,
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
&address_length), ec);
|
||||
#else
|
||||
int result = error_wrapper(::WSAStringToAddressA(
|
||||
const_cast<char*>(src), af, 0,
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
&address_length), ec);
|
||||
#endif
|
||||
|
||||
if (af == AF_INET)
|
||||
{
|
||||
|
@ -717,6 +823,11 @@ inline int inet_pton(int af, const char* src, void* dest,
|
|||
if (result == socket_error_retval && !ec)
|
||||
ec = asio::error::invalid_argument;
|
||||
|
||||
#if defined(UNDER_CE)
|
||||
if (result != socket_error_retval)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
|
||||
return result == socket_error_retval ? -1 : 1;
|
||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
int result = error_wrapper(::inet_pton(af, src, dest), ec);
|
||||
|
@ -743,7 +854,12 @@ inline int inet_pton(int af, const char* src, void* dest,
|
|||
inline int gethostname(char* name, int namelen, asio::error_code& ec)
|
||||
{
|
||||
clear_error(ec);
|
||||
return error_wrapper(::gethostname(name, namelen), ec);
|
||||
int result = error_wrapper(::gethostname(name, namelen), ec);
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
if (result == 0)
|
||||
clear_error(ec);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \
|
||||
|
@ -782,6 +898,9 @@ inline hostent* gethostbyaddr(const char* addr, int length, int af,
|
|||
hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
|
||||
if (!retval)
|
||||
return 0;
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
*result = *retval;
|
||||
return retval;
|
||||
#elif defined(__sun) || defined(__QNX__)
|
||||
|
@ -830,6 +949,9 @@ inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
|
|||
hostent* retval = error_wrapper(::gethostbyname(name), ec);
|
||||
if (!retval)
|
||||
return 0;
|
||||
# if defined(UNDER_CE)
|
||||
clear_error(ec);
|
||||
# endif
|
||||
*result = *retval;
|
||||
return result;
|
||||
#elif defined(__sun) || defined(__QNX__)
|
||||
|
@ -1601,10 +1723,10 @@ inline asio::error_code translate_addrinfo_error(int error)
|
|||
default: // Possibly the non-portable EAI_SYSTEM.
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return asio::error_code(
|
||||
WSAGetLastError(), asio::error::system_category);
|
||||
WSAGetLastError(), asio::error::get_system_category());
|
||||
#else
|
||||
return asio::error_code(
|
||||
errno, asio::error::system_category);
|
||||
errno, asio::error::get_system_category());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1615,7 +1737,7 @@ inline asio::error_code getaddrinfo(const char* host,
|
|||
{
|
||||
clear_error(ec);
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
|
||||
// Building for Windows XP, Windows Server 2003, or later.
|
||||
int error = ::getaddrinfo(host, service, hints, result);
|
||||
return ec = translate_addrinfo_error(error);
|
||||
|
@ -1646,7 +1768,7 @@ inline asio::error_code getaddrinfo(const char* host,
|
|||
inline void freeaddrinfo(addrinfo_type* ai)
|
||||
{
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
|
||||
// Building for Windows XP, Windows Server 2003, or later.
|
||||
::freeaddrinfo(ai);
|
||||
# else
|
||||
|
@ -1674,7 +1796,7 @@ inline asio::error_code getnameinfo(const socket_addr_type* addr,
|
|||
char* serv, std::size_t servlen, int flags, asio::error_code& ec)
|
||||
{
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
|
||||
// Building for Windows XP, Windows Server 2003, or later.
|
||||
clear_error(ec);
|
||||
int error = ::getnameinfo(addr, addrlen, host, static_cast<DWORD>(hostlen),
|
||||
|
@ -1737,8 +1859,6 @@ inline u_short_type host_to_network_short(u_short_type value)
|
|||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#undef ASIO_SOCKET_CALL
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_SOCKET_OPS_HPP
|
||||
|
|
|
@ -80,7 +80,9 @@
|
|||
# undef ASIO_WSPIAPI_H_DEFINED
|
||||
# endif // defined(ASIO_WSPIAPI_H_DEFINED)
|
||||
# if !defined(ASIO_NO_DEFAULT_LINKED_LIBS)
|
||||
# if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# if defined(UNDER_CE)
|
||||
# pragma comment(lib, "ws2.lib")
|
||||
# elif defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# pragma comment(lib, "ws2_32.lib")
|
||||
# pragma comment(lib, "mswsock.lib")
|
||||
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
|
|
|
@ -24,7 +24,11 @@
|
|||
#if !defined(BOOST_HAS_THREADS)
|
||||
# include "asio/detail/null_thread.hpp"
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
# include "asio/detail/win_thread.hpp"
|
||||
# if defined(UNDER_CE)
|
||||
# include "asio/detail/wince_thread.hpp"
|
||||
# else
|
||||
# include "asio/detail/win_thread.hpp"
|
||||
# endif
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include "asio/detail/posix_thread.hpp"
|
||||
#else
|
||||
|
@ -37,7 +41,11 @@ namespace detail {
|
|||
#if !defined(BOOST_HAS_THREADS)
|
||||
typedef null_thread thread;
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
# if defined(UNDER_CE)
|
||||
typedef wince_thread thread;
|
||||
# else
|
||||
typedef win_thread thread;
|
||||
# endif
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
typedef posix_thread thread;
|
||||
#endif
|
||||
|
|
|
@ -162,13 +162,7 @@ public:
|
|||
// Destroy timers that are waiting to be cleaned up.
|
||||
virtual void cleanup_timers()
|
||||
{
|
||||
while (cleanup_timers_)
|
||||
{
|
||||
timer_base* next_timer = cleanup_timers_->next_;
|
||||
cleanup_timers_->next_ = 0;
|
||||
cleanup_timers_->destroy();
|
||||
cleanup_timers_ = next_timer;
|
||||
}
|
||||
destroy_timer_list(cleanup_timers_);
|
||||
}
|
||||
|
||||
// Destroy all timers.
|
||||
|
@ -181,11 +175,12 @@ public:
|
|||
timer_base* t = i->second;
|
||||
typename hash_map<void*, timer_base*>::iterator old_i = i++;
|
||||
timers_.erase(old_i);
|
||||
t->destroy();
|
||||
destroy_timer_list(t);
|
||||
}
|
||||
heap_.clear();
|
||||
timers_.clear();
|
||||
cleanup_timers();
|
||||
destroy_timer_list(cancelled_timers_);
|
||||
destroy_timer_list(cleanup_timers_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -367,6 +362,18 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Destroy all timers in a linked list.
|
||||
void destroy_timer_list(timer_base*& t)
|
||||
{
|
||||
while (t)
|
||||
{
|
||||
timer_base* next = t->next_;
|
||||
t->next_ = 0;
|
||||
t->destroy();
|
||||
t = next;
|
||||
}
|
||||
}
|
||||
|
||||
// A hash of timer token to linked lists of timers.
|
||||
hash_map<void*, timer_base*> timers_;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||
#include "asio/detail/service_base.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
#include "asio/detail/timer_queue.hpp"
|
||||
#include "asio/detail/win_iocp_operation.hpp"
|
||||
#include "asio/detail/mutex.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
@ -51,7 +53,9 @@ public:
|
|||
iocp_(),
|
||||
outstanding_work_(0),
|
||||
stopped_(0),
|
||||
shutdown_(0)
|
||||
shutdown_(0),
|
||||
timer_thread_(0),
|
||||
timer_interrupt_issued_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -64,7 +68,7 @@ public:
|
|||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"iocp");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -93,6 +97,10 @@ public:
|
|||
if (overlapped)
|
||||
static_cast<operation*>(overlapped)->destroy();
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->destroy_timers();
|
||||
timer_queues_.clear();
|
||||
}
|
||||
|
||||
// Register a handle with the IO completion port.
|
||||
|
@ -175,7 +183,7 @@ public:
|
|||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -231,7 +239,7 @@ public:
|
|||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -251,20 +259,102 @@ public:
|
|||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new timer queue to the service.
|
||||
template <typename Time_Traits>
|
||||
void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(timer_mutex_);
|
||||
timer_queues_.push_back(&timer_queue);
|
||||
}
|
||||
|
||||
// Remove a timer queue from the service.
|
||||
template <typename Time_Traits>
|
||||
void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(timer_mutex_);
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
if (timer_queues_[i] == &timer_queue)
|
||||
{
|
||||
timer_queues_.erase(timer_queues_.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule a timer in the given timer queue to expire at the specified
|
||||
// absolute time. The handler object will be invoked when the timer expires.
|
||||
template <typename Time_Traits, typename Handler>
|
||||
void schedule_timer(timer_queue<Time_Traits>& timer_queue,
|
||||
const typename Time_Traits::time_type& time, Handler handler, void* token)
|
||||
{
|
||||
// If the service has been shut down we silently discard the timer.
|
||||
if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
|
||||
return;
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(timer_mutex_);
|
||||
if (timer_queue.enqueue_timer(time, handler, token))
|
||||
{
|
||||
if (!timer_interrupt_issued_)
|
||||
{
|
||||
timer_interrupt_issued_ = true;
|
||||
lock.unlock();
|
||||
::PostQueuedCompletionStatus(iocp_.handle,
|
||||
0, steal_timer_dispatching, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the timer associated with the given token. Returns the number of
|
||||
// handlers that have been posted or dispatched.
|
||||
template <typename Time_Traits>
|
||||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||
{
|
||||
// If the service has been shut down we silently ignore the cancellation.
|
||||
if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
|
||||
return 0;
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(timer_mutex_);
|
||||
std::size_t n = timer_queue.cancel_timer(token);
|
||||
if (n > 0 && !timer_interrupt_issued_)
|
||||
{
|
||||
timer_interrupt_issued_ = true;
|
||||
lock.unlock();
|
||||
::PostQueuedCompletionStatus(iocp_.handle,
|
||||
0, steal_timer_dispatching, 0);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private:
|
||||
// Dequeues at most one operation from the I/O completion port, and then
|
||||
// executes it. Returns the number of operations that were dequeued (i.e.
|
||||
// either 0 or 1).
|
||||
size_t do_one(bool block, asio::error_code& ec)
|
||||
{
|
||||
long this_thread_id = static_cast<long>(::GetCurrentThreadId());
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Try to acquire responsibility for dispatching timers.
|
||||
bool dispatching_timers = (::InterlockedCompareExchange(
|
||||
&timer_thread_, this_thread_id, 0) == 0);
|
||||
|
||||
// Calculate timeout for GetQueuedCompletionStatus call.
|
||||
DWORD timeout = max_timeout;
|
||||
if (dispatching_timers)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(timer_mutex_);
|
||||
timer_interrupt_issued_ = false;
|
||||
timeout = get_timeout();
|
||||
}
|
||||
|
||||
// Get the next operation from the queue.
|
||||
DWORD bytes_transferred = 0;
|
||||
#if (WINVER < 0x0500)
|
||||
|
@ -275,18 +365,47 @@ private:
|
|||
LPOVERLAPPED overlapped = 0;
|
||||
::SetLastError(0);
|
||||
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
||||
&completion_key, &overlapped, block ? 1000 : 0);
|
||||
&completion_key, &overlapped, block ? timeout : 0);
|
||||
DWORD last_error = ::GetLastError();
|
||||
|
||||
// Dispatch any pending timers.
|
||||
if (dispatching_timers)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(timer_mutex_);
|
||||
timer_queues_copy_ = timer_queues_;
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
timer_queues_[i]->cleanup_timers();
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok && overlapped == 0)
|
||||
{
|
||||
if (block && last_error == WAIT_TIMEOUT)
|
||||
{
|
||||
// Relinquish responsibility for dispatching timers.
|
||||
if (dispatching_timers)
|
||||
{
|
||||
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Transfer responsibility for dispatching timers to another thread.
|
||||
if (dispatching_timers && ::InterlockedCompareExchange(
|
||||
&timer_thread_, 0, this_thread_id) == this_thread_id)
|
||||
{
|
||||
::PostQueuedCompletionStatus(iocp_.handle,
|
||||
0, transfer_timer_dispatching, 0);
|
||||
}
|
||||
|
||||
ec = asio::error_code();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (overlapped)
|
||||
else if (overlapped)
|
||||
{
|
||||
// We may have been passed a last_error value in the completion_key.
|
||||
if (last_error == 0)
|
||||
|
@ -294,6 +413,14 @@ private:
|
|||
last_error = completion_key;
|
||||
}
|
||||
|
||||
// Transfer responsibility for dispatching timers to another thread.
|
||||
if (dispatching_timers && ::InterlockedCompareExchange(
|
||||
&timer_thread_, 0, this_thread_id) == this_thread_id)
|
||||
{
|
||||
::PostQueuedCompletionStatus(iocp_.handle,
|
||||
0, transfer_timer_dispatching, 0);
|
||||
}
|
||||
|
||||
// Ensure that the io_service does not exit due to running out of work
|
||||
// while we make the upcall.
|
||||
auto_work work(*this);
|
||||
|
@ -305,18 +432,34 @@ private:
|
|||
ec = asio::error_code();
|
||||
return 1;
|
||||
}
|
||||
else if (completion_key == transfer_timer_dispatching)
|
||||
{
|
||||
// Woken up to try to acquire responsibility for dispatching timers.
|
||||
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
|
||||
}
|
||||
else if (completion_key == steal_timer_dispatching)
|
||||
{
|
||||
// Woken up to steal responsibility for dispatching timers.
|
||||
::InterlockedExchange(&timer_thread_, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The stopped_ flag is always checked to ensure that any leftover
|
||||
// interrupts from a previous run invocation are ignored.
|
||||
if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
|
||||
{
|
||||
// Relinquish responsibility for dispatching timers.
|
||||
if (dispatching_timers)
|
||||
{
|
||||
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
|
||||
}
|
||||
|
||||
// Wake up next thread that is blocked on GetQueuedCompletionStatus.
|
||||
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -327,6 +470,45 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Check if all timer queues are empty.
|
||||
bool all_timer_queues_are_empty() const
|
||||
{
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
if (!timer_queues_[i]->empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the timeout value for the GetQueuedCompletionStatus call. The timeout
|
||||
// value is returned as a number of milliseconds. We will wait no longer than
|
||||
// 1000 milliseconds.
|
||||
DWORD get_timeout()
|
||||
{
|
||||
if (all_timer_queues_are_empty())
|
||||
return max_timeout;
|
||||
|
||||
boost::posix_time::time_duration minimum_wait_duration
|
||||
= boost::posix_time::milliseconds(max_timeout);
|
||||
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
boost::posix_time::time_duration wait_duration
|
||||
= timer_queues_[i]->wait_duration();
|
||||
if (wait_duration < minimum_wait_duration)
|
||||
minimum_wait_duration = wait_duration;
|
||||
}
|
||||
|
||||
if (minimum_wait_duration > boost::posix_time::time_duration())
|
||||
{
|
||||
int milliseconds = minimum_wait_duration.total_milliseconds();
|
||||
return static_cast<DWORD>(milliseconds > 0 ? milliseconds : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct auto_work
|
||||
{
|
||||
auto_work(win_iocp_io_service& io_service)
|
||||
|
@ -416,6 +598,37 @@ private:
|
|||
|
||||
// Flag to indicate whether the service has been shut down.
|
||||
long shutdown_;
|
||||
|
||||
enum
|
||||
{
|
||||
// Maximum GetQueuedCompletionStatus timeout, in milliseconds.
|
||||
max_timeout = 1000,
|
||||
|
||||
// Completion key value to indicate that responsibility for dispatching
|
||||
// timers is being cooperatively transferred from one thread to another.
|
||||
transfer_timer_dispatching = 1,
|
||||
|
||||
// Completion key value to indicate that responsibility for dispatching
|
||||
// timers should be stolen from another thread.
|
||||
steal_timer_dispatching = 2
|
||||
};
|
||||
|
||||
// The thread that's currently in charge of dispatching timers.
|
||||
long timer_thread_;
|
||||
|
||||
// Mutex for protecting access to the timer queues.
|
||||
mutex timer_mutex_;
|
||||
|
||||
// Whether a thread has been interrupted to process a new timeout.
|
||||
bool timer_interrupt_issued_;
|
||||
|
||||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when dispatching, cancelling and cleaning
|
||||
// up timers. The copy is stored as a class data member to avoid unnecessary
|
||||
// memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_copy_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#if !defined(ASIO_DISABLE_IOCP)
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
|
||||
#if !defined(UNDER_CE)
|
||||
|
||||
// Define this to indicate that IOCP is supported on the target platform.
|
||||
#define ASIO_HAS_IOCP 1
|
||||
|
@ -39,6 +40,7 @@ class win_iocp_io_service;
|
|||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#endif // !defined(UNDER_CE)
|
||||
#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
|
||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
#endif // !defined(ASIO_DISABLE_IOCP)
|
||||
|
|
|
@ -338,7 +338,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -360,7 +360,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -667,7 +667,7 @@ public:
|
|||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -719,7 +719,7 @@ public:
|
|||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||
{
|
||||
if (handler_op->cancel_token_.expired())
|
||||
|
@ -822,7 +822,7 @@ public:
|
|||
asio::io_service::work work(this->get_io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -867,7 +867,7 @@ public:
|
|||
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -917,7 +917,7 @@ public:
|
|||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||
{
|
||||
ec = asio::error::connection_refused;
|
||||
|
@ -1001,7 +1001,7 @@ public:
|
|||
asio::io_service::work work(this->get_io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -1056,7 +1056,7 @@ public:
|
|||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
return 0;
|
||||
}
|
||||
if (bytes_transferred == 0)
|
||||
|
@ -1115,7 +1115,7 @@ public:
|
|||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||
{
|
||||
if (handler_op->cancel_token_.expired())
|
||||
|
@ -1223,7 +1223,7 @@ public:
|
|||
asio::io_service::work work(this->get_io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -1270,7 +1270,7 @@ public:
|
|||
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
return 0;
|
||||
}
|
||||
if (bytes_transferred == 0)
|
||||
|
@ -1337,7 +1337,7 @@ public:
|
|||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||
{
|
||||
ec = asio::error::connection_refused;
|
||||
|
@ -1432,7 +1432,7 @@ public:
|
|||
asio::io_service::work work(this->get_io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -1671,7 +1671,7 @@ public:
|
|||
|
||||
// Call the handler.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
detail::bind_handler(handler, ec), &handler);
|
||||
}
|
||||
|
@ -1772,7 +1772,7 @@ public:
|
|||
asio::io_service::work work(this->get_io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
iocp_service_.post(bind_handler(handler, ec));
|
||||
}
|
||||
}
|
||||
|
@ -1849,7 +1849,7 @@ public:
|
|||
if (connect_error)
|
||||
{
|
||||
ec = asio::error_code(connect_error,
|
||||
asio::error::system_category);
|
||||
asio::error::get_system_category());
|
||||
io_service_.post(bind_handler(handler_, ec));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -68,7 +69,8 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error,
|
||||
asio::error::get_system_category()),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
#if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ inline unsigned int __stdcall win_thread_function(void* arg)
|
|||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#endif // defined(BOOST_WINDOWS)
|
||||
#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
|
|
|
@ -40,16 +40,22 @@ class win_tss_ptr
|
|||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
#if defined(UNDER_CE)
|
||||
enum { out_of_indexes = 0xFFFFFFFF };
|
||||
#else
|
||||
enum { out_of_indexes = TLS_OUT_OF_INDEXES };
|
||||
#endif
|
||||
|
||||
// Constructor.
|
||||
win_tss_ptr()
|
||||
{
|
||||
tss_key_ = ::TlsAlloc();
|
||||
if (tss_key_ == TLS_OUT_OF_INDEXES)
|
||||
if (tss_key_ == out_of_indexes)
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"tss");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// wince_thread.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2007 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 ASIO_DETAIL_WINCE_THREAD_HPP
|
||||
#define ASIO_DETAIL_WINCE_THREAD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <memory>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
DWORD WINAPI wince_thread_function(LPVOID arg);
|
||||
|
||||
class wince_thread
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
// Constructor.
|
||||
template <typename Function>
|
||||
wince_thread(Function f)
|
||||
{
|
||||
std::auto_ptr<func_base> arg(new func<Function>(f));
|
||||
DWORD thread_id = 0;
|
||||
thread_ = ::CreateThread(0, 0, wince_thread_function,
|
||||
arg.get(), 0, &thread_id);
|
||||
if (!thread_)
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::get_system_category()),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
arg.release();
|
||||
}
|
||||
|
||||
// Destructor.
|
||||
~wince_thread()
|
||||
{
|
||||
::CloseHandle(thread_);
|
||||
}
|
||||
|
||||
// Wait for the thread to exit.
|
||||
void join()
|
||||
{
|
||||
::WaitForSingleObject(thread_, INFINITE);
|
||||
}
|
||||
|
||||
private:
|
||||
friend DWORD WINAPI wince_thread_function(LPVOID arg);
|
||||
|
||||
class func_base
|
||||
{
|
||||
public:
|
||||
virtual ~func_base() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
template <typename Function>
|
||||
class func
|
||||
: public func_base
|
||||
{
|
||||
public:
|
||||
func(Function f)
|
||||
: f_(f)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
Function f_;
|
||||
};
|
||||
|
||||
::HANDLE thread_;
|
||||
};
|
||||
|
||||
inline DWORD WINAPI wince_thread_function(LPVOID arg)
|
||||
{
|
||||
std::auto_ptr<wince_thread::func_base> func(
|
||||
static_cast<wince_thread::func_base*>(arg));
|
||||
func->run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace asio
|
||||
|
||||
#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_DETAIL_WINCE_THREAD_HPP
|
|
@ -87,7 +87,7 @@ public:
|
|||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(ref_->result(),
|
||||
asio::error::system_category),
|
||||
asio::error::get_system_category()),
|
||||
"winsock");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ enum basic_errors
|
|||
/// Address family not supported by protocol.
|
||||
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
|
||||
|
||||
/// Port already in use.
|
||||
/// Address already in use.
|
||||
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
||||
|
||||
/// Transport endpoint is already connected.
|
||||
|
@ -82,7 +82,7 @@ enum basic_errors
|
|||
/// Bad file descriptor.
|
||||
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
||||
|
||||
/// Bad port.
|
||||
/// Bad address.
|
||||
fault = ASIO_SOCKET_ERROR(EFAULT),
|
||||
|
||||
/// No route to host.
|
||||
|
@ -205,27 +205,32 @@ enum ssl_errors
|
|||
|
||||
inline asio::error_code make_error_code(basic_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), system_category);
|
||||
return asio::error_code(
|
||||
static_cast<int>(e), get_system_category());
|
||||
}
|
||||
|
||||
inline asio::error_code make_error_code(netdb_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), netdb_category);
|
||||
return asio::error_code(
|
||||
static_cast<int>(e), get_netdb_category());
|
||||
}
|
||||
|
||||
inline asio::error_code make_error_code(addrinfo_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), addrinfo_category);
|
||||
return asio::error_code(
|
||||
static_cast<int>(e), get_addrinfo_category());
|
||||
}
|
||||
|
||||
inline asio::error_code make_error_code(misc_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), misc_category);
|
||||
return asio::error_code(
|
||||
static_cast<int>(e), get_misc_category());
|
||||
}
|
||||
|
||||
inline asio::error_code make_error_code(ssl_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), ssl_category);
|
||||
return asio::error_code(
|
||||
static_cast<int>(e), get_ssl_category());
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
|
|
|
@ -41,10 +41,10 @@ namespace error
|
|||
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||
|
||||
/// Error codes from NetDB functions.
|
||||
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
|
||||
netdb_category = ASIO_WIN_OR_POSIX(_system_category, 1),
|
||||
|
||||
/// Error codes from getaddrinfo.
|
||||
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
|
||||
addrinfo_category = ASIO_WIN_OR_POSIX(_system_category, 2),
|
||||
|
||||
/// Miscellaneous error codes.
|
||||
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||
|
@ -52,6 +52,14 @@ namespace error
|
|||
/// SSL error codes.
|
||||
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
|
||||
};
|
||||
|
||||
// Category getters.
|
||||
inline error_category get_system_category() { return system_category; }
|
||||
inline error_category get_netdb_category() { return netdb_category; }
|
||||
inline error_category get_addrinfo_category() { return addrinfo_category; }
|
||||
inline error_category get_misc_category() { return misc_category; }
|
||||
inline error_category get_ssl_category() { return ssl_category; }
|
||||
|
||||
} // namespace error
|
||||
|
||||
/// Bring error category type into the asio namespace.
|
||||
|
|
|
@ -35,11 +35,11 @@ inline std::string error_code::message() const
|
|||
return "Already open.";
|
||||
if (*this == error::not_found)
|
||||
return "Not found.";
|
||||
if (category_ == error::ssl_category)
|
||||
if (category_ == error::get_ssl_category())
|
||||
return "SSL error.";
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
value_type value = value_;
|
||||
if (category() != error::system_category && *this != error::eof)
|
||||
if (category() != error::get_system_category() && *this != error::eof)
|
||||
return "asio error";
|
||||
if (*this == error::eof)
|
||||
value = ERROR_HANDLE_EOF;
|
||||
|
@ -78,7 +78,7 @@ inline std::string error_code::message() const
|
|||
return "Service not found.";
|
||||
if (*this == error::socket_type_not_supported)
|
||||
return "Socket type not supported.";
|
||||
if (category() != error::system_category)
|
||||
if (category() != error::get_system_category())
|
||||
return "asio error";
|
||||
#if defined(__sun) || defined(__QNX__)
|
||||
return strerror(value_);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <algorithm>
|
||||
#include <boost/optional.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffer.hpp"
|
||||
|
@ -139,25 +138,23 @@ namespace detail
|
|||
std::size_t bytes_transferred)
|
||||
{
|
||||
total_transferred_ += bytes_transferred;
|
||||
buffers_->consume(bytes_transferred);
|
||||
if ((*completion_condition_)(ec, total_transferred_)
|
||||
|| buffers_->begin() == buffers_->end())
|
||||
buffers_.consume(bytes_transferred);
|
||||
if (completion_condition_(ec, total_transferred_)
|
||||
|| buffers_.begin() == buffers_.end())
|
||||
{
|
||||
buffers_.reset();
|
||||
completion_condition_.reset();
|
||||
handler_(ec, total_transferred_);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_.async_read_some(*buffers_, *this);
|
||||
stream_.async_read_some(buffers_, *this);
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
AsyncReadStream& stream_;
|
||||
boost::optional<buffers_type> buffers_;
|
||||
buffers_type buffers_;
|
||||
std::size_t total_transferred_;
|
||||
boost::optional<CompletionCondition> completion_condition_;
|
||||
CompletionCondition completion_condition_;
|
||||
ReadHandler handler_;
|
||||
};
|
||||
|
||||
|
@ -238,9 +235,8 @@ namespace detail
|
|||
total_transferred_ += bytes_transferred;
|
||||
streambuf_.commit(bytes_transferred);
|
||||
if (streambuf_.size() == streambuf_.max_size()
|
||||
|| (*completion_condition_)(ec, total_transferred_))
|
||||
|| completion_condition_(ec, total_transferred_))
|
||||
{
|
||||
completion_condition_.reset();
|
||||
handler_(ec, total_transferred_);
|
||||
}
|
||||
else
|
||||
|
@ -255,7 +251,7 @@ namespace detail
|
|||
AsyncReadStream& stream_;
|
||||
asio::basic_streambuf<Allocator>& streambuf_;
|
||||
std::size_t total_transferred_;
|
||||
boost::optional<CompletionCondition> completion_condition_;
|
||||
CompletionCondition completion_condition_;
|
||||
ReadHandler handler_;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/buffer.hpp"
|
||||
#include "asio/completion_condition.hpp"
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
|
@ -128,25 +124,23 @@ namespace detail
|
|||
std::size_t bytes_transferred)
|
||||
{
|
||||
total_transferred_ += bytes_transferred;
|
||||
buffers_->consume(bytes_transferred);
|
||||
if ((*completion_condition_)(ec, total_transferred_)
|
||||
|| buffers_->begin() == buffers_->end())
|
||||
buffers_.consume(bytes_transferred);
|
||||
if (completion_condition_(ec, total_transferred_)
|
||||
|| buffers_.begin() == buffers_.end())
|
||||
{
|
||||
buffers_.reset();
|
||||
completion_condition_.reset();
|
||||
handler_(ec, total_transferred_);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_.async_write_some(*buffers_, *this);
|
||||
stream_.async_write_some(buffers_, *this);
|
||||
}
|
||||
}
|
||||
|
||||
//private:
|
||||
AsyncWriteStream& stream_;
|
||||
boost::optional<buffers_type> buffers_;
|
||||
buffers_type buffers_;
|
||||
std::size_t total_transferred_;
|
||||
boost::optional<CompletionCondition> completion_condition_;
|
||||
CompletionCondition completion_condition_;
|
||||
WriteHandler handler_;
|
||||
};
|
||||
|
||||
|
|
|
@ -252,6 +252,13 @@ template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name>
|
|||
class multicast_hops
|
||||
{
|
||||
public:
|
||||
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||
typedef int ipv4_value_type;
|
||||
#else
|
||||
typedef unsigned char ipv4_value_type;
|
||||
#endif
|
||||
typedef int ipv6_value_type;
|
||||
|
||||
// Default constructor.
|
||||
multicast_hops()
|
||||
: ipv4_value_(0),
|
||||
|
@ -264,7 +271,7 @@ public:
|
|||
{
|
||||
if (v < 0 || v > 255)
|
||||
throw std::out_of_range("multicast hops value out of range");
|
||||
ipv4_value_ = static_cast<unsigned char>(v);
|
||||
ipv4_value_ = (ipv4_value_type)v;
|
||||
ipv6_value_ = v;
|
||||
}
|
||||
|
||||
|
@ -273,7 +280,7 @@ public:
|
|||
{
|
||||
if (v < 0 || v > 255)
|
||||
throw std::out_of_range("multicast hops value out of range");
|
||||
ipv4_value_ = static_cast<unsigned char>(v);
|
||||
ipv4_value_ = (ipv4_value_type)v;
|
||||
ipv6_value_ = v;
|
||||
return *this;
|
||||
}
|
||||
|
@ -342,7 +349,7 @@ public:
|
|||
else if (ipv6_value_ > 255)
|
||||
ipv4_value_ = 255;
|
||||
else
|
||||
ipv4_value_ = static_cast<unsigned char>(ipv6_value_);
|
||||
ipv4_value_ = (ipv4_value_type)ipv6_value_;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -353,8 +360,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
unsigned char ipv4_value_;
|
||||
int ipv6_value_;
|
||||
ipv4_value_type ipv4_value_;
|
||||
ipv6_value_type ipv6_value_;
|
||||
};
|
||||
|
||||
// Helper template for implementing ip_mreq-based options.
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
else
|
||||
{
|
||||
return handler_(asio::error_code(
|
||||
error_code, asio::error::ssl_category), rc);
|
||||
error_code, asio::error::get_ssl_category()), rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer
|
|||
|
||||
void lsd::close()
|
||||
{
|
||||
m_socket.close();
|
||||
m_broadcast_timer.cancel();
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
|
|
|
@ -2317,6 +2317,8 @@ namespace detail
|
|||
void session_impl::stop_lsd()
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
if (m_lsd.get())
|
||||
m_lsd->close();
|
||||
m_lsd = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue