diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-05-06 17:44:27 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-05-06 17:44:27 (GMT) |
commit | d76ada0ab59634e3333f9eb5a92d0e850f60d7bf (patch) | |
tree | 5eaae441173fad2ec19ba67d6589f28ecd740991 /3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp | |
parent | 6f49e5abee37d37b351d68c01374232eccdac458 (diff) | |
download | swift-contrib-d76ada0ab59634e3333f9eb5a92d0e850f60d7bf.zip swift-contrib-d76ada0ab59634e3333f9eb5a92d0e850f60d7bf.tar.bz2 |
Updated Boost to 1.43.0.
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp | 124 |
1 files changed, 44 insertions, 80 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp b/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp index bb64014..082a5b1 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_iocp_overlapped_ptr.hpp @@ -21,8 +21,10 @@ #if defined(BOOST_ASIO_HAS_IOCP) +#include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/win_iocp_io_service.hpp> +#include <boost/asio/detail/win_iocp_operation.hpp> namespace boost { namespace asio { @@ -35,7 +37,8 @@ class win_iocp_overlapped_ptr public: // Construct an empty win_iocp_overlapped_ptr. win_iocp_overlapped_ptr() - : ptr_(0) + : ptr_(0), + iocp_service_(0) { } @@ -43,7 +46,8 @@ public: template <typename Handler> explicit win_iocp_overlapped_ptr( boost::asio::io_service& io_service, Handler handler) - : ptr_(0) + : ptr_(0), + iocp_service_(0) { this->reset(io_service, handler); } @@ -61,6 +65,8 @@ public: { ptr_->destroy(); ptr_ = 0; + iocp_service_->work_finished(); + iocp_service_ = 0; } } @@ -69,12 +75,14 @@ public: template <typename Handler> void reset(boost::asio::io_service& io_service, Handler handler) { - typedef overlapped_operation<Handler> value_type; + typedef overlapped_op<Handler> value_type; typedef handler_alloc_traits<Handler, value_type> alloc_traits; raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> ptr(raw_ptr, io_service.impl_, handler); + handler_ptr<alloc_traits> ptr(raw_ptr, handler); + io_service.impl_.work_started(); reset(); ptr_ = ptr.release(); + iocp_service_ = &io_service.impl_; } // Get the contained OVERLAPPED object. @@ -93,10 +101,11 @@ public: OVERLAPPED* release() { if (ptr_) - ptr_->on_pending(); + iocp_service_->on_pending(ptr_); OVERLAPPED* tmp = ptr_; ptr_ = 0; + iocp_service_ = 0; return tmp; } @@ -106,99 +115,54 @@ public: { if (ptr_) { - ptr_->ec_ = ec; - ptr_->on_immediate_completion(0, static_cast<DWORD>(bytes_transferred)); + iocp_service_->on_completion(ptr_, ec, + static_cast<DWORD>(bytes_transferred)); ptr_ = 0; + iocp_service_ = 0; } } private: - struct overlapped_operation_base - : public win_iocp_io_service::operation - { - overlapped_operation_base(win_iocp_io_service& io_service, - invoke_func_type invoke_func, destroy_func_type destroy_func) - : win_iocp_io_service::operation(io_service, invoke_func, destroy_func), - io_service_(io_service) - { - io_service_.work_started(); - } - - ~overlapped_operation_base() - { - io_service_.work_finished(); - } - - win_iocp_io_service& io_service_; - boost::system::error_code ec_; - }; - template <typename Handler> - struct overlapped_operation - : public overlapped_operation_base + struct overlapped_op : public win_iocp_operation { - overlapped_operation(win_iocp_io_service& io_service, - Handler handler) - : overlapped_operation_base(io_service, - &overlapped_operation<Handler>::do_completion_impl, - &overlapped_operation<Handler>::destroy_impl), + overlapped_op(Handler handler) + : win_iocp_operation(&overlapped_op::do_complete), handler_(handler) { } - private: - // Prevent copying and assignment. - overlapped_operation(const overlapped_operation&); - void operator=(const overlapped_operation&); - - static void do_completion_impl(win_iocp_io_service::operation* op, - DWORD last_error, size_t bytes_transferred) + static void do_complete(io_service_impl* owner, operation* base, + boost::system::error_code ec, std::size_t bytes_transferred) { // Take ownership of the operation object. - typedef overlapped_operation<Handler> op_type; - op_type* handler_op(static_cast<op_type*>(op)); - typedef handler_alloc_traits<Handler, op_type> alloc_traits; - handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op); - - // Make a copy of the handler and error_code so that the memory can be - // deallocated before the upcall is made. - Handler handler(handler_op->handler_); - boost::system::error_code ec(handler_op->ec_); - if (last_error) - ec = boost::system::error_code(last_error, - boost::asio::error::get_system_category()); - - // Free the memory associated with the handler. - ptr.reset(); - - // Make the upcall. - boost_asio_handler_invoke_helpers::invoke( - bind_handler(handler, ec, bytes_transferred), handler); - } - - static void destroy_impl(win_iocp_io_service::operation* op) - { - // Take ownership of the operation object. - typedef overlapped_operation<Handler> op_type; - op_type* handler_op(static_cast<op_type*>(op)); - typedef handler_alloc_traits<Handler, op_type> alloc_traits; - handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op); - - // A sub-object of the handler may be the true owner of the memory - // associated with the handler. Consequently, a local copy of the handler - // is required to ensure that any owning sub-object remains valid until - // after we have deallocated the memory here. - Handler handler(handler_op->handler_); - (void)handler; - - // Free the memory associated with the handler. - ptr.reset(); + overlapped_op* o(static_cast<overlapped_op*>(base)); + typedef handler_alloc_traits<Handler, overlapped_op> alloc_traits; + handler_ptr<alloc_traits> ptr(o->handler_, o); + + // Make the upcall if required. + if (owner) + { + // Make a copy of the handler so that the memory can be deallocated + // before the upcall is made. Even if we're not about to make an + // upcall, a sub-object of the handler may be the true owner of the + // memory associated with the handler. Consequently, a local copy of + // the handler is required to ensure that any owning sub-object remains + // valid until after we have deallocated the memory here. + detail::binder2<Handler, boost::system::error_code, std::size_t> + handler(o->handler_, ec, bytes_transferred); + ptr.reset(); + boost::asio::detail::fenced_block b; + boost_asio_handler_invoke_helpers::invoke(handler, handler); + } } + private: Handler handler_; }; - overlapped_operation_base* ptr_; + win_iocp_operation* ptr_; + win_iocp_io_service* iocp_service_; }; } // namespace detail |