From 591d9716c3c24e8246ed613eec5a66feaa404da9 Mon Sep 17 00:00:00 2001 From: Alden Torres Date: Wed, 12 Apr 2017 10:25:02 -0400 Subject: [PATCH] refactored windows based ip_notifier in a separated class --- src/ip_notifier.cpp | 55 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/ip_notifier.cpp b/src/ip_notifier.cpp index 7db4cac08..8296134bc 100644 --- a/src/ip_notifier.cpp +++ b/src/ip_notifier.cpp @@ -311,13 +311,60 @@ private: #endif // TORRENT_USE_SC_NETWORK_REACHABILITY #elif defined TORRENT_WINDOWS - // TODO: ip_change_notifier_win -#else - // TODO: ip_change_notifier_default +struct ip_change_notifier_impl final : ip_change_notifier +{ + explicit ip_change_notifier_impl(io_service& ios) + : m_hnd(ios, WSACreateEvent()) + { + if (!m_hnd.is_open()) aux::throw_ex(WSAGetLastError(), system_category()); + m_ovl.hEvent = m_hnd.native_handle(); + } + + // noncopyable + ip_change_notifier_impl(ip_change_notifier_impl const&) = delete; + ip_change_notifier_impl& operator=(ip_change_notifier_impl const&) = delete; + + ~ip_change_notifier_impl() override + { + cancel(); + // the reason to call close() here is because the + // object_handle destructor doesn't close the handle + m_hnd.close(); + } + + void async_wait(std::function cb) override + { + HANDLE hnd; + DWORD err = NotifyAddrChange(&hnd, &m_ovl); + if (err == ERROR_IO_PENDING) + { + m_hnd.async_wait([cb](error_code const& ec) + { + // call CancelIPChangeNotify here? + cb(ec); + }); + } + else + { + m_hnd.get_io_service().post([cb, err]() + { cb(error_code(err, system_category())); }); + } + } + + void cancel() override + { + CancelIPChangeNotify(&m_ovl); + m_hnd.cancel(); + } + +private: + OVERLAPPED m_ovl = {}; + boost::asio::windows::object_handle m_hnd; +}; #endif // TODO: to remove when separated per platform -#if defined TORRENT_BUILD_SIMULATOR || defined TORRENT_WINDOWS +#if defined TORRENT_BUILD_SIMULATOR struct ip_change_notifier_impl final : ip_change_notifier { explicit ip_change_notifier_impl(io_service& ios);