mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-17 22:06:27 +00:00
asio sync
This commit is contained in:
parent
732c3d8674
commit
dc2f24344c
@ -27,7 +27,7 @@
|
|||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
# if defined(_HAS_ITERATOR_DEBUGGING)
|
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
|
||||||
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||||
# define ASIO_ENABLE_BUFFER_DEBUGGING
|
# define ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
|
||||||
@ -390,6 +390,11 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~buffer_debug_check()
|
||||||
|
{
|
||||||
|
iter_ = Iterator();
|
||||||
|
}
|
||||||
|
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
*iter_;
|
*iter_;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "asio/detail/kqueue_reactor.hpp"
|
#include "asio/detail/kqueue_reactor.hpp"
|
||||||
#include "asio/detail/select_reactor.hpp"
|
#include "asio/detail/select_reactor.hpp"
|
||||||
#include "asio/detail/service_base.hpp"
|
#include "asio/detail/service_base.hpp"
|
||||||
|
#include "asio/detail/win_iocp_io_service.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ private:
|
|||||||
// The type of the platform-specific implementation.
|
// The type of the platform-specific implementation.
|
||||||
#if defined(ASIO_HAS_IOCP)
|
#if defined(ASIO_HAS_IOCP)
|
||||||
typedef detail::deadline_timer_service<
|
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)
|
#elif defined(ASIO_HAS_EPOLL)
|
||||||
typedef detail::deadline_timer_service<
|
typedef detail::deadline_timer_service<
|
||||||
traits_type, detail::epoll_reactor<false> > service_impl_type;
|
traits_type, detail::epoll_reactor<false> > service_impl_type;
|
||||||
|
@ -140,22 +140,13 @@ public:
|
|||||||
|
|
||||||
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
if (read_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
{
|
{
|
||||||
::pollfd ev = { 0 };
|
::pollfd& ev = add_pending_event_change(descriptor);
|
||||||
ev.fd = descriptor;
|
|
||||||
ev.events = POLLIN | POLLERR | POLLHUP;
|
ev.events = POLLIN | POLLERR | POLLHUP;
|
||||||
if (write_op_queue_.has_operation(descriptor))
|
if (write_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLOUT;
|
ev.events |= POLLOUT;
|
||||||
if (except_op_queue_.has_operation(descriptor))
|
if (except_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLPRI;
|
ev.events |= POLLPRI;
|
||||||
ev.revents = 0;
|
interrupter_.interrupt();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,22 +166,13 @@ public:
|
|||||||
|
|
||||||
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
if (write_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
{
|
{
|
||||||
::pollfd ev = { 0 };
|
::pollfd& ev = add_pending_event_change(descriptor);
|
||||||
ev.fd = descriptor;
|
|
||||||
ev.events = POLLOUT | POLLERR | POLLHUP;
|
ev.events = POLLOUT | POLLERR | POLLHUP;
|
||||||
if (read_op_queue_.has_operation(descriptor))
|
if (read_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLIN;
|
ev.events |= POLLIN;
|
||||||
if (except_op_queue_.has_operation(descriptor))
|
if (except_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLPRI;
|
ev.events |= POLLPRI;
|
||||||
ev.revents = 0;
|
interrupter_.interrupt();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,22 +188,13 @@ public:
|
|||||||
|
|
||||||
if (except_op_queue_.enqueue_operation(descriptor, handler))
|
if (except_op_queue_.enqueue_operation(descriptor, handler))
|
||||||
{
|
{
|
||||||
::pollfd ev = { 0 };
|
::pollfd& ev = add_pending_event_change(descriptor);
|
||||||
ev.fd = descriptor;
|
|
||||||
ev.events = POLLPRI | POLLERR | POLLHUP;
|
ev.events = POLLPRI | POLLERR | POLLHUP;
|
||||||
if (read_op_queue_.has_operation(descriptor))
|
if (read_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLIN;
|
ev.events |= POLLIN;
|
||||||
if (write_op_queue_.has_operation(descriptor))
|
if (write_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLOUT;
|
ev.events |= POLLOUT;
|
||||||
ev.revents = 0;
|
interrupter_.interrupt();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,21 +214,11 @@ public:
|
|||||||
&& need_mod;
|
&& need_mod;
|
||||||
if (need_mod)
|
if (need_mod)
|
||||||
{
|
{
|
||||||
::pollfd ev = { 0 };
|
::pollfd& ev = add_pending_event_change(descriptor);
|
||||||
ev.fd = descriptor;
|
|
||||||
ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP;
|
ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP;
|
||||||
if (read_op_queue_.has_operation(descriptor))
|
if (read_op_queue_.has_operation(descriptor))
|
||||||
ev.events |= POLLIN;
|
ev.events |= POLLIN;
|
||||||
ev.revents = 0;
|
interrupter_.interrupt();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,11 +248,9 @@ public:
|
|||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
// Remove the descriptor from /dev/poll.
|
// Remove the descriptor from /dev/poll.
|
||||||
::pollfd ev = { 0 };
|
::pollfd& ev = add_pending_event_change(descriptor);
|
||||||
ev.fd = descriptor;
|
|
||||||
ev.events = POLLREMOVE;
|
ev.events = POLLREMOVE;
|
||||||
ev.revents = 0;
|
interrupter_.interrupt();
|
||||||
::write(dev_poll_fd_, &ev, sizeof(ev));
|
|
||||||
|
|
||||||
// Cancel any outstanding operations associated with the descriptor.
|
// Cancel any outstanding operations associated with the descriptor.
|
||||||
cancel_ops_unlocked(descriptor);
|
cancel_ops_unlocked(descriptor);
|
||||||
@ -374,6 +335,26 @@ private:
|
|||||||
return;
|
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;
|
int timeout = block ? get_timeout() : 0;
|
||||||
wait_in_progress_ = true;
|
wait_in_progress_ = true;
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@ -454,7 +435,7 @@ private:
|
|||||||
if (result != sizeof(ev))
|
if (result != sizeof(ev))
|
||||||
{
|
{
|
||||||
ec = asio::error_code(errno,
|
ec = asio::error_code(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
@ -513,7 +494,7 @@ private:
|
|||||||
boost::throw_exception(
|
boost::throw_exception(
|
||||||
asio::system_error(
|
asio::system_error(
|
||||||
asio::error_code(errno,
|
asio::error_code(errno,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"/dev/poll"));
|
"/dev/poll"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
@ -588,12 +569,39 @@ private:
|
|||||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
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.
|
// Mutex to protect access to internal data.
|
||||||
asio::detail::mutex mutex_;
|
asio::detail::mutex mutex_;
|
||||||
|
|
||||||
// The /dev/poll file descriptor.
|
// The /dev/poll file descriptor.
|
||||||
int dev_poll_fd_;
|
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
|
// Whether the DP_POLL operation is currently in progress
|
||||||
bool wait_in_progress_;
|
bool wait_in_progress_;
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ public:
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ public:
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ public:
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,7 +262,7 @@ public:
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
@ -456,7 +456,7 @@ private:
|
|||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
ec = asio::error_code(errno,
|
ec = asio::error_code(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
@ -518,7 +518,7 @@ private:
|
|||||||
boost::throw_exception(
|
boost::throw_exception(
|
||||||
asio::system_error(
|
asio::system_error(
|
||||||
asio::error_code(errno,
|
asio::error_code(errno,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"epoll"));
|
"epoll"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -151,7 +151,7 @@ public:
|
|||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ public:
|
|||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ public:
|
|||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ public:
|
|||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,7 +243,7 @@ public:
|
|||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno,
|
asio::error_code ec(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_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)
|
if (events[i].flags & EV_ERROR)
|
||||||
{
|
{
|
||||||
asio::error_code 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);
|
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
read_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)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code error(errno,
|
asio::error_code error(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
read_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)
|
if (events[i].flags & EV_ERROR)
|
||||||
{
|
{
|
||||||
asio::error_code 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);
|
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -458,7 +458,7 @@ private:
|
|||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code error(errno,
|
asio::error_code error(errno,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,7 +515,7 @@ private:
|
|||||||
boost::throw_exception(
|
boost::throw_exception(
|
||||||
asio::system_error(
|
asio::system_error(
|
||||||
asio::error_code(errno,
|
asio::error_code(errno,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"kqueue"));
|
"kqueue"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -51,7 +51,8 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
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");
|
asio::system_error e(ec, "pipe_select_interrupter");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"event");
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -70,7 +71,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -83,7 +85,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"thread");
|
"thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"tss");
|
"tss");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,8 @@ public:
|
|||||||
|
|
||||||
if (int err = reactor_.register_descriptor(sock.get()))
|
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;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +182,8 @@ public:
|
|||||||
|
|
||||||
if (int err = reactor_.register_descriptor(native_socket))
|
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;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1489,7 +1491,7 @@ public:
|
|||||||
if (connect_error)
|
if (connect_error)
|
||||||
{
|
{
|
||||||
ec = asio::error_code(connect_error,
|
ec = asio::error_code(connect_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
io_service_.post(bind_handler(handler_, ec));
|
io_service_.post(bind_handler(handler_, ec));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,11 @@ extern "C" unsigned int if_nametoindex(const char*);
|
|||||||
|
|
||||||
inline void clear_error(asio::error_code& ec)
|
inline void clear_error(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
errno = 0;
|
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
WSASetLastError(0);
|
WSASetLastError(0);
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else
|
||||||
|
errno = 0;
|
||||||
|
#endif
|
||||||
ec = asio::error_code();
|
ec = asio::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,9 +62,10 @@ inline ReturnType error_wrapper(ReturnType return_value,
|
|||||||
{
|
{
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
ec = asio::error_code(WSAGetLastError(),
|
ec = asio::error_code(WSAGetLastError(),
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
#else
|
#else
|
||||||
ec = asio::error_code(errno, asio::error::system_category);
|
ec = asio::error_code(errno,
|
||||||
|
asio::error::get_system_category());
|
||||||
#endif
|
#endif
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
@ -100,6 +102,10 @@ inline socket_type accept(socket_type s, socket_addr_type* addr,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
#endif
|
||||||
|
|
||||||
return new_s;
|
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)
|
std::size_t addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(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)
|
inline int close(socket_type s, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
return error_wrapper(::close(s), ec);
|
return error_wrapper(::close(s), ec);
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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)
|
inline int shutdown(socket_type s, int what, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(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>
|
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)
|
std::size_t addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(call_connect(
|
int result = error_wrapper(call_connect(
|
||||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
&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)
|
inline int listen(socket_type s, int backlog, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(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__)
|
#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);
|
recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg = msghdr();
|
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;
|
*addrlen = (std::size_t)tmp_addrlen;
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg = msghdr();
|
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);
|
send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg = msghdr();
|
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 send_buf_count = static_cast<DWORD>(count);
|
||||||
DWORD bytes_transferred = 0;
|
DWORD bytes_transferred = 0;
|
||||||
int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
|
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)
|
if (result != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg = msghdr();
|
msghdr msg = msghdr();
|
||||||
@ -327,6 +372,10 @@ inline socket_type socket(int af, int type, int protocol,
|
|||||||
reinterpret_cast<const char*>(&optval), sizeof(optval));
|
reinterpret_cast<const char*>(&optval), sizeof(optval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
socket_type s = error_wrapper(::socket(af, type, protocol), ec);
|
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;
|
return -1;
|
||||||
#else // defined(__BORLANDC__)
|
#else // defined(__BORLANDC__)
|
||||||
clear_error(ec);
|
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);
|
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__)
|
#endif // defined(__BORLANDC__)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,6 +509,10 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
|||||||
*static_cast<DWORD*>(optval) = 1;
|
*static_cast<DWORD*>(optval) = 1;
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
}
|
}
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
if (result == 0)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
return result;
|
return result;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
clear_error(ec);
|
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)
|
std::size_t* addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(call_getpeername(
|
int result = error_wrapper(call_getpeername(
|
||||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
&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>
|
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)
|
std::size_t* addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(call_getsockname(
|
int result = error_wrapper(call_getsockname(
|
||||||
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
&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,
|
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);
|
clear_error(ec);
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
return error_wrapper(::ioctl(s, cmd, arg), ec);
|
return error_wrapper(::ioctl(s, cmd, arg), ec);
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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,
|
return error_wrapper(::pselect(nfds, readfds,
|
||||||
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
|
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
|
||||||
#else
|
#else
|
||||||
return error_wrapper(::select(nfds, readfds,
|
int result = error_wrapper(::select(nfds, readfds,
|
||||||
writefds, exceptfds, timeout), ec);
|
writefds, exceptfds, timeout), ec);
|
||||||
|
# if defined(BOOST_WINDOWS) && defined(UNDER_CE)
|
||||||
|
if (result >= 0)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,7 +646,12 @@ inline int poll_read(socket_type s, asio::error_code& ec)
|
|||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(s, &fds);
|
FD_SET(s, &fds);
|
||||||
clear_error(ec);
|
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__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
pollfd fds;
|
pollfd fds;
|
||||||
fds.fd = s;
|
fds.fd = s;
|
||||||
@ -586,7 +669,12 @@ inline int poll_write(socket_type s, asio::error_code& ec)
|
|||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(s, &fds);
|
FD_SET(s, &fds);
|
||||||
clear_error(ec);
|
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__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
pollfd fds;
|
pollfd fds;
|
||||||
fds.fd = s;
|
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);
|
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(
|
int result = error_wrapper(::WSAAddressToStringA(
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
address_length, 0, dest, &string_length), ec);
|
address_length, 0, dest, &string_length), ec);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Windows may set error code on success.
|
// Windows may set error code on success.
|
||||||
if (result != socket_error_retval)
|
if (result != socket_error_retval)
|
||||||
@ -680,10 +776,20 @@ inline int inet_pton(int af, const char* src, void* dest,
|
|||||||
|
|
||||||
sockaddr_storage_type address;
|
sockaddr_storage_type address;
|
||||||
int address_length = sizeof(sockaddr_storage_type);
|
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(
|
int result = error_wrapper(::WSAStringToAddressA(
|
||||||
const_cast<char*>(src), af, 0,
|
const_cast<char*>(src), af, 0,
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
&address_length), ec);
|
&address_length), ec);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (af == AF_INET)
|
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)
|
if (result == socket_error_retval && !ec)
|
||||||
ec = asio::error::invalid_argument;
|
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;
|
return result == socket_error_retval ? -1 : 1;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
int result = error_wrapper(::inet_pton(af, src, dest), ec);
|
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)
|
inline int gethostname(char* name, int namelen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(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__) \
|
#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);
|
hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
|
||||||
if (!retval)
|
if (!retval)
|
||||||
return 0;
|
return 0;
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
*result = *retval;
|
*result = *retval;
|
||||||
return retval;
|
return retval;
|
||||||
#elif defined(__sun) || defined(__QNX__)
|
#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);
|
hostent* retval = error_wrapper(::gethostbyname(name), ec);
|
||||||
if (!retval)
|
if (!retval)
|
||||||
return 0;
|
return 0;
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
clear_error(ec);
|
||||||
|
# endif
|
||||||
*result = *retval;
|
*result = *retval;
|
||||||
return result;
|
return result;
|
||||||
#elif defined(__sun) || defined(__QNX__)
|
#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.
|
default: // Possibly the non-portable EAI_SYSTEM.
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
return asio::error_code(
|
return asio::error_code(
|
||||||
WSAGetLastError(), asio::error::system_category);
|
WSAGetLastError(), asio::error::get_system_category());
|
||||||
#else
|
#else
|
||||||
return asio::error_code(
|
return asio::error_code(
|
||||||
errno, asio::error::system_category);
|
errno, asio::error::get_system_category());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1615,7 +1737,7 @@ inline asio::error_code getaddrinfo(const char* host,
|
|||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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.
|
// Building for Windows XP, Windows Server 2003, or later.
|
||||||
int error = ::getaddrinfo(host, service, hints, result);
|
int error = ::getaddrinfo(host, service, hints, result);
|
||||||
return ec = translate_addrinfo_error(error);
|
return ec = translate_addrinfo_error(error);
|
||||||
@ -1646,7 +1768,7 @@ inline asio::error_code getaddrinfo(const char* host,
|
|||||||
inline void freeaddrinfo(addrinfo_type* ai)
|
inline void freeaddrinfo(addrinfo_type* ai)
|
||||||
{
|
{
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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.
|
// Building for Windows XP, Windows Server 2003, or later.
|
||||||
::freeaddrinfo(ai);
|
::freeaddrinfo(ai);
|
||||||
# else
|
# 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)
|
char* serv, std::size_t servlen, int flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#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.
|
// Building for Windows XP, Windows Server 2003, or later.
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
int error = ::getnameinfo(addr, addrlen, host, static_cast<DWORD>(hostlen),
|
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 detail
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
#undef ASIO_SOCKET_CALL
|
|
||||||
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#endif // ASIO_DETAIL_SOCKET_OPS_HPP
|
#endif // ASIO_DETAIL_SOCKET_OPS_HPP
|
||||||
|
@ -80,7 +80,9 @@
|
|||||||
# undef ASIO_WSPIAPI_H_DEFINED
|
# undef ASIO_WSPIAPI_H_DEFINED
|
||||||
# endif // defined(ASIO_WSPIAPI_H_DEFINED)
|
# endif // defined(ASIO_WSPIAPI_H_DEFINED)
|
||||||
# if !defined(ASIO_NO_DEFAULT_LINKED_LIBS)
|
# 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, "ws2_32.lib")
|
||||||
# pragma comment(lib, "mswsock.lib")
|
# pragma comment(lib, "mswsock.lib")
|
||||||
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
|
@ -24,7 +24,11 @@
|
|||||||
#if !defined(BOOST_HAS_THREADS)
|
#if !defined(BOOST_HAS_THREADS)
|
||||||
# include "asio/detail/null_thread.hpp"
|
# include "asio/detail/null_thread.hpp"
|
||||||
#elif defined(BOOST_WINDOWS)
|
#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)
|
#elif defined(BOOST_HAS_PTHREADS)
|
||||||
# include "asio/detail/posix_thread.hpp"
|
# include "asio/detail/posix_thread.hpp"
|
||||||
#else
|
#else
|
||||||
@ -37,7 +41,11 @@ namespace detail {
|
|||||||
#if !defined(BOOST_HAS_THREADS)
|
#if !defined(BOOST_HAS_THREADS)
|
||||||
typedef null_thread thread;
|
typedef null_thread thread;
|
||||||
#elif defined(BOOST_WINDOWS)
|
#elif defined(BOOST_WINDOWS)
|
||||||
|
# if defined(UNDER_CE)
|
||||||
|
typedef wince_thread thread;
|
||||||
|
# else
|
||||||
typedef win_thread thread;
|
typedef win_thread thread;
|
||||||
|
# endif
|
||||||
#elif defined(BOOST_HAS_PTHREADS)
|
#elif defined(BOOST_HAS_PTHREADS)
|
||||||
typedef posix_thread thread;
|
typedef posix_thread thread;
|
||||||
#endif
|
#endif
|
||||||
|
@ -162,13 +162,7 @@ public:
|
|||||||
// Destroy timers that are waiting to be cleaned up.
|
// Destroy timers that are waiting to be cleaned up.
|
||||||
virtual void cleanup_timers()
|
virtual void cleanup_timers()
|
||||||
{
|
{
|
||||||
while (cleanup_timers_)
|
destroy_timer_list(cleanup_timers_);
|
||||||
{
|
|
||||||
timer_base* next_timer = cleanup_timers_->next_;
|
|
||||||
cleanup_timers_->next_ = 0;
|
|
||||||
cleanup_timers_->destroy();
|
|
||||||
cleanup_timers_ = next_timer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy all timers.
|
// Destroy all timers.
|
||||||
@ -181,11 +175,12 @@ public:
|
|||||||
timer_base* t = i->second;
|
timer_base* t = i->second;
|
||||||
typename hash_map<void*, timer_base*>::iterator old_i = i++;
|
typename hash_map<void*, timer_base*>::iterator old_i = i++;
|
||||||
timers_.erase(old_i);
|
timers_.erase(old_i);
|
||||||
t->destroy();
|
destroy_timer_list(t);
|
||||||
}
|
}
|
||||||
heap_.clear();
|
heap_.clear();
|
||||||
timers_.clear();
|
timers_.clear();
|
||||||
cleanup_timers();
|
destroy_timer_list(cancelled_timers_);
|
||||||
|
destroy_timer_list(cleanup_timers_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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.
|
// A hash of timer token to linked lists of timers.
|
||||||
hash_map<void*, timer_base*> timers_;
|
hash_map<void*, timer_base*> timers_;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"event");
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,9 @@
|
|||||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
#include "asio/detail/service_base.hpp"
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
#include "asio/detail/timer_queue.hpp"
|
||||||
#include "asio/detail/win_iocp_operation.hpp"
|
#include "asio/detail/win_iocp_operation.hpp"
|
||||||
|
#include "asio/detail/mutex.hpp"
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -51,7 +53,9 @@ public:
|
|||||||
iocp_(),
|
iocp_(),
|
||||||
outstanding_work_(0),
|
outstanding_work_(0),
|
||||||
stopped_(0),
|
stopped_(0),
|
||||||
shutdown_(0)
|
shutdown_(0),
|
||||||
|
timer_thread_(0),
|
||||||
|
timer_interrupt_issued_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +68,7 @@ public:
|
|||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"iocp");
|
"iocp");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -93,6 +97,10 @@ public:
|
|||||||
if (overlapped)
|
if (overlapped)
|
||||||
static_cast<operation*>(overlapped)->destroy();
|
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.
|
// Register a handle with the IO completion port.
|
||||||
@ -175,7 +183,7 @@ public:
|
|||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"pqcs");
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -231,7 +239,7 @@ public:
|
|||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"pqcs");
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -251,20 +259,102 @@ public:
|
|||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"pqcs");
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
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:
|
private:
|
||||||
// Dequeues at most one operation from the I/O completion port, and then
|
// 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.
|
// executes it. Returns the number of operations that were dequeued (i.e.
|
||||||
// either 0 or 1).
|
// either 0 or 1).
|
||||||
size_t do_one(bool block, asio::error_code& ec)
|
size_t do_one(bool block, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
|
long this_thread_id = static_cast<long>(::GetCurrentThreadId());
|
||||||
|
|
||||||
for (;;)
|
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.
|
// Get the next operation from the queue.
|
||||||
DWORD bytes_transferred = 0;
|
DWORD bytes_transferred = 0;
|
||||||
#if (WINVER < 0x0500)
|
#if (WINVER < 0x0500)
|
||||||
@ -275,18 +365,47 @@ private:
|
|||||||
LPOVERLAPPED overlapped = 0;
|
LPOVERLAPPED overlapped = 0;
|
||||||
::SetLastError(0);
|
::SetLastError(0);
|
||||||
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
||||||
&completion_key, &overlapped, block ? 1000 : 0);
|
&completion_key, &overlapped, block ? timeout : 0);
|
||||||
DWORD last_error = ::GetLastError();
|
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 (!ok && overlapped == 0)
|
||||||
{
|
{
|
||||||
if (block && last_error == WAIT_TIMEOUT)
|
if (block && last_error == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
// Relinquish responsibility for dispatching timers.
|
||||||
|
if (dispatching_timers)
|
||||||
|
{
|
||||||
|
::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
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();
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (overlapped)
|
||||||
if (overlapped)
|
|
||||||
{
|
{
|
||||||
// We may have been passed a last_error value in the completion_key.
|
// We may have been passed a last_error value in the completion_key.
|
||||||
if (last_error == 0)
|
if (last_error == 0)
|
||||||
@ -294,6 +413,14 @@ private:
|
|||||||
last_error = completion_key;
|
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
|
// Ensure that the io_service does not exit due to running out of work
|
||||||
// while we make the upcall.
|
// while we make the upcall.
|
||||||
auto_work work(*this);
|
auto_work work(*this);
|
||||||
@ -305,18 +432,34 @@ private:
|
|||||||
ec = asio::error_code();
|
ec = asio::error_code();
|
||||||
return 1;
|
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
|
else
|
||||||
{
|
{
|
||||||
// The stopped_ flag is always checked to ensure that any leftover
|
// The stopped_ flag is always checked to ensure that any leftover
|
||||||
// interrupts from a previous run invocation are ignored.
|
// interrupts from a previous run invocation are ignored.
|
||||||
if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
|
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.
|
// Wake up next thread that is blocked on GetQueuedCompletionStatus.
|
||||||
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
return 0;
|
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
|
struct auto_work
|
||||||
{
|
{
|
||||||
auto_work(win_iocp_io_service& io_service)
|
auto_work(win_iocp_io_service& io_service)
|
||||||
@ -416,6 +598,37 @@ private:
|
|||||||
|
|
||||||
// Flag to indicate whether the service has been shut down.
|
// Flag to indicate whether the service has been shut down.
|
||||||
long shutdown_;
|
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
|
} // namespace detail
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#if !defined(ASIO_DISABLE_IOCP)
|
#if !defined(ASIO_DISABLE_IOCP)
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
|
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
|
||||||
|
#if !defined(UNDER_CE)
|
||||||
|
|
||||||
// Define this to indicate that IOCP is supported on the target platform.
|
// Define this to indicate that IOCP is supported on the target platform.
|
||||||
#define ASIO_HAS_IOCP 1
|
#define ASIO_HAS_IOCP 1
|
||||||
@ -39,6 +40,7 @@ class win_iocp_io_service;
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
|
#endif // !defined(UNDER_CE)
|
||||||
#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
|
#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
#endif // !defined(ASIO_DISABLE_IOCP)
|
#endif // !defined(ASIO_DISABLE_IOCP)
|
||||||
|
@ -338,7 +338,7 @@ public:
|
|||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -360,7 +360,7 @@ public:
|
|||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -667,7 +667,7 @@ public:
|
|||||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,7 +719,7 @@ public:
|
|||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||||
{
|
{
|
||||||
if (handler_op->cancel_token_.expired())
|
if (handler_op->cancel_token_.expired())
|
||||||
@ -822,7 +822,7 @@ public:
|
|||||||
asio::io_service::work work(this->get_io_service());
|
asio::io_service::work work(this->get_io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -867,7 +867,7 @@ public:
|
|||||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,7 +917,7 @@ public:
|
|||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||||
{
|
{
|
||||||
ec = asio::error::connection_refused;
|
ec = asio::error::connection_refused;
|
||||||
@ -1001,7 +1001,7 @@ public:
|
|||||||
asio::io_service::work work(this->get_io_service());
|
asio::io_service::work work(this->get_io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1056,7 +1056,7 @@ public:
|
|||||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (bytes_transferred == 0)
|
if (bytes_transferred == 0)
|
||||||
@ -1115,7 +1115,7 @@ public:
|
|||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||||
{
|
{
|
||||||
if (handler_op->cancel_token_.expired())
|
if (handler_op->cancel_token_.expired())
|
||||||
@ -1223,7 +1223,7 @@ public:
|
|||||||
asio::io_service::work work(this->get_io_service());
|
asio::io_service::work work(this->get_io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1270,7 +1270,7 @@ public:
|
|||||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (bytes_transferred == 0)
|
if (bytes_transferred == 0)
|
||||||
@ -1337,7 +1337,7 @@ public:
|
|||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||||
{
|
{
|
||||||
ec = asio::error::connection_refused;
|
ec = asio::error::connection_refused;
|
||||||
@ -1432,7 +1432,7 @@ public:
|
|||||||
asio::io_service::work work(this->get_io_service());
|
asio::io_service::work work(this->get_io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1671,7 +1671,7 @@ public:
|
|||||||
|
|
||||||
// Call the handler.
|
// Call the handler.
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
asio_handler_invoke_helpers::invoke(
|
asio_handler_invoke_helpers::invoke(
|
||||||
detail::bind_handler(handler, ec), &handler);
|
detail::bind_handler(handler, ec), &handler);
|
||||||
}
|
}
|
||||||
@ -1772,7 +1772,7 @@ public:
|
|||||||
asio::io_service::work work(this->get_io_service());
|
asio::io_service::work work(this->get_io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error,
|
asio::error_code ec(last_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
iocp_service_.post(bind_handler(handler, ec));
|
iocp_service_.post(bind_handler(handler, ec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1849,7 +1849,7 @@ public:
|
|||||||
if (connect_error)
|
if (connect_error)
|
||||||
{
|
{
|
||||||
ec = asio::error_code(connect_error,
|
ec = asio::error_code(connect_error,
|
||||||
asio::error::system_category);
|
asio::error::get_system_category());
|
||||||
io_service_.post(bind_handler(handler_, ec));
|
io_service_.post(bind_handler(handler_, ec));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -68,7 +69,8 @@ public:
|
|||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::error::system_category),
|
asio::error_code(error,
|
||||||
|
asio::error::get_system_category()),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
|
||||||
|
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
@ -56,7 +56,7 @@ public:
|
|||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"thread");
|
"thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ inline unsigned int __stdcall win_thread_function(void* arg)
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
#endif // defined(BOOST_WINDOWS)
|
#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
|
||||||
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
@ -40,16 +40,22 @@ class win_tss_ptr
|
|||||||
: private noncopyable
|
: private noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if defined(UNDER_CE)
|
||||||
|
enum { out_of_indexes = 0xFFFFFFFF };
|
||||||
|
#else
|
||||||
|
enum { out_of_indexes = TLS_OUT_OF_INDEXES };
|
||||||
|
#endif
|
||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
win_tss_ptr()
|
win_tss_ptr()
|
||||||
{
|
{
|
||||||
tss_key_ = ::TlsAlloc();
|
tss_key_ = ::TlsAlloc();
|
||||||
if (tss_key_ == TLS_OUT_OF_INDEXES)
|
if (tss_key_ == out_of_indexes)
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error,
|
asio::error_code(last_error,
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"tss");
|
"tss");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
124
libtorrent/include/libtorrent/asio/detail/wince_thread.hpp
Normal file
124
libtorrent/include/libtorrent/asio/detail/wince_thread.hpp
Normal file
@ -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::system_error e(
|
||||||
asio::error_code(ref_->result(),
|
asio::error_code(ref_->result(),
|
||||||
asio::error::system_category),
|
asio::error::get_system_category()),
|
||||||
"winsock");
|
"winsock");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ enum basic_errors
|
|||||||
/// Address family not supported by protocol.
|
/// Address family not supported by protocol.
|
||||||
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
|
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
|
||||||
|
|
||||||
/// Port already in use.
|
/// Address already in use.
|
||||||
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
||||||
|
|
||||||
/// Transport endpoint is already connected.
|
/// Transport endpoint is already connected.
|
||||||
@ -82,7 +82,7 @@ enum basic_errors
|
|||||||
/// Bad file descriptor.
|
/// Bad file descriptor.
|
||||||
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
||||||
|
|
||||||
/// Bad port.
|
/// Bad address.
|
||||||
fault = ASIO_SOCKET_ERROR(EFAULT),
|
fault = ASIO_SOCKET_ERROR(EFAULT),
|
||||||
|
|
||||||
/// No route to host.
|
/// No route to host.
|
||||||
@ -205,27 +205,32 @@ enum ssl_errors
|
|||||||
|
|
||||||
inline asio::error_code make_error_code(basic_errors e)
|
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)
|
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)
|
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)
|
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)
|
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
|
} // namespace error
|
||||||
|
@ -41,10 +41,10 @@ namespace error
|
|||||||
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||||
|
|
||||||
/// Error codes from NetDB functions.
|
/// 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.
|
/// 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.
|
/// Miscellaneous error codes.
|
||||||
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||||
@ -52,6 +52,14 @@ namespace error
|
|||||||
/// SSL error codes.
|
/// SSL error codes.
|
||||||
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
|
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
|
} // namespace error
|
||||||
|
|
||||||
/// Bring error category type into the asio namespace.
|
/// Bring error category type into the asio namespace.
|
||||||
|
@ -35,11 +35,11 @@ inline std::string error_code::message() const
|
|||||||
return "Already open.";
|
return "Already open.";
|
||||||
if (*this == error::not_found)
|
if (*this == error::not_found)
|
||||||
return "Not found.";
|
return "Not found.";
|
||||||
if (category_ == error::ssl_category)
|
if (category_ == error::get_ssl_category())
|
||||||
return "SSL error.";
|
return "SSL error.";
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
value_type value = value_;
|
value_type value = value_;
|
||||||
if (category() != error::system_category && *this != error::eof)
|
if (category() != error::get_system_category() && *this != error::eof)
|
||||||
return "asio error";
|
return "asio error";
|
||||||
if (*this == error::eof)
|
if (*this == error::eof)
|
||||||
value = ERROR_HANDLE_EOF;
|
value = ERROR_HANDLE_EOF;
|
||||||
@ -78,7 +78,7 @@ inline std::string error_code::message() const
|
|||||||
return "Service not found.";
|
return "Service not found.";
|
||||||
if (*this == error::socket_type_not_supported)
|
if (*this == error::socket_type_not_supported)
|
||||||
return "Socket type not supported.";
|
return "Socket type not supported.";
|
||||||
if (category() != error::system_category)
|
if (category() != error::get_system_category())
|
||||||
return "asio error";
|
return "asio error";
|
||||||
#if defined(__sun) || defined(__QNX__)
|
#if defined(__sun) || defined(__QNX__)
|
||||||
return strerror(value_);
|
return strerror(value_);
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/buffer.hpp"
|
#include "asio/buffer.hpp"
|
||||||
@ -139,25 +138,23 @@ namespace detail
|
|||||||
std::size_t bytes_transferred)
|
std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
total_transferred_ += bytes_transferred;
|
total_transferred_ += bytes_transferred;
|
||||||
buffers_->consume(bytes_transferred);
|
buffers_.consume(bytes_transferred);
|
||||||
if ((*completion_condition_)(ec, total_transferred_)
|
if (completion_condition_(ec, total_transferred_)
|
||||||
|| buffers_->begin() == buffers_->end())
|
|| buffers_.begin() == buffers_.end())
|
||||||
{
|
{
|
||||||
buffers_.reset();
|
|
||||||
completion_condition_.reset();
|
|
||||||
handler_(ec, total_transferred_);
|
handler_(ec, total_transferred_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stream_.async_read_some(*buffers_, *this);
|
stream_.async_read_some(buffers_, *this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
AsyncReadStream& stream_;
|
AsyncReadStream& stream_;
|
||||||
boost::optional<buffers_type> buffers_;
|
buffers_type buffers_;
|
||||||
std::size_t total_transferred_;
|
std::size_t total_transferred_;
|
||||||
boost::optional<CompletionCondition> completion_condition_;
|
CompletionCondition completion_condition_;
|
||||||
ReadHandler handler_;
|
ReadHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -238,9 +235,8 @@ namespace detail
|
|||||||
total_transferred_ += bytes_transferred;
|
total_transferred_ += bytes_transferred;
|
||||||
streambuf_.commit(bytes_transferred);
|
streambuf_.commit(bytes_transferred);
|
||||||
if (streambuf_.size() == streambuf_.max_size()
|
if (streambuf_.size() == streambuf_.max_size()
|
||||||
|| (*completion_condition_)(ec, total_transferred_))
|
|| completion_condition_(ec, total_transferred_))
|
||||||
{
|
{
|
||||||
completion_condition_.reset();
|
|
||||||
handler_(ec, total_transferred_);
|
handler_(ec, total_transferred_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -255,7 +251,7 @@ namespace detail
|
|||||||
AsyncReadStream& stream_;
|
AsyncReadStream& stream_;
|
||||||
asio::basic_streambuf<Allocator>& streambuf_;
|
asio::basic_streambuf<Allocator>& streambuf_;
|
||||||
std::size_t total_transferred_;
|
std::size_t total_transferred_;
|
||||||
boost::optional<CompletionCondition> completion_condition_;
|
CompletionCondition completion_condition_;
|
||||||
ReadHandler handler_;
|
ReadHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#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/buffer.hpp"
|
||||||
#include "asio/completion_condition.hpp"
|
#include "asio/completion_condition.hpp"
|
||||||
#include "asio/detail/bind_handler.hpp"
|
#include "asio/detail/bind_handler.hpp"
|
||||||
@ -128,25 +124,23 @@ namespace detail
|
|||||||
std::size_t bytes_transferred)
|
std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
total_transferred_ += bytes_transferred;
|
total_transferred_ += bytes_transferred;
|
||||||
buffers_->consume(bytes_transferred);
|
buffers_.consume(bytes_transferred);
|
||||||
if ((*completion_condition_)(ec, total_transferred_)
|
if (completion_condition_(ec, total_transferred_)
|
||||||
|| buffers_->begin() == buffers_->end())
|
|| buffers_.begin() == buffers_.end())
|
||||||
{
|
{
|
||||||
buffers_.reset();
|
|
||||||
completion_condition_.reset();
|
|
||||||
handler_(ec, total_transferred_);
|
handler_(ec, total_transferred_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stream_.async_write_some(*buffers_, *this);
|
stream_.async_write_some(buffers_, *this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
AsyncWriteStream& stream_;
|
AsyncWriteStream& stream_;
|
||||||
boost::optional<buffers_type> buffers_;
|
buffers_type buffers_;
|
||||||
std::size_t total_transferred_;
|
std::size_t total_transferred_;
|
||||||
boost::optional<CompletionCondition> completion_condition_;
|
CompletionCondition completion_condition_;
|
||||||
WriteHandler handler_;
|
WriteHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -252,6 +252,13 @@ template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name>
|
|||||||
class multicast_hops
|
class multicast_hops
|
||||||
{
|
{
|
||||||
public:
|
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.
|
// Default constructor.
|
||||||
multicast_hops()
|
multicast_hops()
|
||||||
: ipv4_value_(0),
|
: ipv4_value_(0),
|
||||||
@ -264,7 +271,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (v < 0 || v > 255)
|
if (v < 0 || v > 255)
|
||||||
throw std::out_of_range("multicast hops value out of range");
|
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;
|
ipv6_value_ = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +280,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (v < 0 || v > 255)
|
if (v < 0 || v > 255)
|
||||||
throw std::out_of_range("multicast hops value out of range");
|
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;
|
ipv6_value_ = v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -342,7 +349,7 @@ public:
|
|||||||
else if (ipv6_value_ > 255)
|
else if (ipv6_value_ > 255)
|
||||||
ipv4_value_ = 255;
|
ipv4_value_ = 255;
|
||||||
else
|
else
|
||||||
ipv4_value_ = static_cast<unsigned char>(ipv6_value_);
|
ipv4_value_ = (ipv4_value_type)ipv6_value_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -353,8 +360,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned char ipv4_value_;
|
ipv4_value_type ipv4_value_;
|
||||||
int ipv6_value_;
|
ipv6_value_type ipv6_value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper template for implementing ip_mreq-based options.
|
// Helper template for implementing ip_mreq-based options.
|
||||||
|
@ -179,7 +179,7 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return handler_(asio::error_code(
|
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()
|
void lsd::close()
|
||||||
{
|
{
|
||||||
m_socket.close();
|
|
||||||
m_broadcast_timer.cancel();
|
m_broadcast_timer.cancel();
|
||||||
|
m_socket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2317,6 +2317,8 @@ namespace detail
|
|||||||
void session_impl::stop_lsd()
|
void session_impl::stop_lsd()
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
if (m_lsd.get())
|
||||||
|
m_lsd->close();
|
||||||
m_lsd = 0;
|
m_lsd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user