From 03b978c7f9dbaa227275eb83a7e35aeae3808605 Mon Sep 17 00:00:00 2001 From: chris_kohlhoff Date: Sun, 26 Feb 2006 22:27:51 +0000 Subject: [PATCH] Don't use classes nested in function definitions since they cause problems for the VC7.1 linker. --- asio/include/asio/detail/task_io_service.hpp | 119 +++++++++--------- .../asio/detail/win_iocp_io_service.hpp | 34 ++--- 2 files changed, 80 insertions(+), 73 deletions(-) diff --git a/asio/include/asio/detail/task_io_service.hpp b/asio/include/asio/detail/task_io_service.hpp index cb08cbfc..f12c910d 100644 --- a/asio/include/asio/detail/task_io_service.hpp +++ b/asio/include/asio/detail/task_io_service.hpp @@ -74,42 +74,8 @@ public: if (h == &task_handler_) { - // Helper class to perform operations on block exit. - class cleanup - { - public: - cleanup(asio::detail::mutex::scoped_lock& lock, - handler_base*& handler_queue, handler_base*& handler_queue_end, - handler_base& task_handler) - : lock_(lock), - handler_queue_(handler_queue), - handler_queue_end_(handler_queue_end), - task_handler_(task_handler) - { - } - - ~cleanup() - { - // Reinsert the task at the end of the handler queue. - lock_.lock(); - task_handler_.next_ = 0; - if (handler_queue_end_) - { - handler_queue_end_->next_ = &task_handler_; - handler_queue_end_ = &task_handler_; - } - else - { - handler_queue_ = handler_queue_end_ = &task_handler_; - } - } - - private: - asio::detail::mutex::scoped_lock& lock_; - handler_base*& handler_queue_; - handler_base*& handler_queue_end_; - handler_base& task_handler_; - } c(lock, handler_queue_, handler_queue_end_, task_handler_); + task_cleanup c(lock, handler_queue_, + handler_queue_end_, task_handler_); // Run the task. May throw an exception. Only block if the handler // queue is empty, otherwise we want to return as soon as possible to @@ -118,27 +84,7 @@ public: } else { - // Helper class to perform operations on block exit. - class cleanup - { - public: - cleanup(asio::detail::mutex::scoped_lock& lock, - int& outstanding_work) - : lock_(lock), - outstanding_work_(outstanding_work) - { - } - - ~cleanup() - { - lock_.lock(); - --outstanding_work_; - } - - private: - asio::detail::mutex::scoped_lock& lock_; - int& outstanding_work_; - } c(lock, outstanding_work_); + handler_cleanup c(lock, outstanding_work_); // Invoke the handler. May throw an exception. h->call(allocator_); // call() deletes the handler object @@ -357,6 +303,65 @@ private: Handler handler_; }; + // Helper class to perform task-related operations on block exit. + class task_cleanup + { + public: + task_cleanup(asio::detail::mutex::scoped_lock& lock, + handler_base*& handler_queue, handler_base*& handler_queue_end, + handler_base& task_handler) + : lock_(lock), + handler_queue_(handler_queue), + handler_queue_end_(handler_queue_end), + task_handler_(task_handler) + { + } + + ~task_cleanup() + { + // Reinsert the task at the end of the handler queue. + lock_.lock(); + task_handler_.next_ = 0; + if (handler_queue_end_) + { + handler_queue_end_->next_ = &task_handler_; + handler_queue_end_ = &task_handler_; + } + else + { + handler_queue_ = handler_queue_end_ = &task_handler_; + } + } + + private: + asio::detail::mutex::scoped_lock& lock_; + handler_base*& handler_queue_; + handler_base*& handler_queue_end_; + handler_base& task_handler_; + }; + + // Helper class to perform handler-related operations on block exit. + class handler_cleanup + { + public: + handler_cleanup(asio::detail::mutex::scoped_lock& lock, + int& outstanding_work) + : lock_(lock), + outstanding_work_(outstanding_work) + { + } + + ~handler_cleanup() + { + lock_.lock(); + --outstanding_work_; + } + + private: + asio::detail::mutex::scoped_lock& lock_; + int& outstanding_work_; + }; + // Mutex to protect access to internal data. asio::detail::mutex mutex_; diff --git a/asio/include/asio/detail/win_iocp_io_service.hpp b/asio/include/asio/detail/win_iocp_io_service.hpp index 48fe5eb2..002cebd1 100644 --- a/asio/include/asio/detail/win_iocp_io_service.hpp +++ b/asio/include/asio/detail/win_iocp_io_service.hpp @@ -72,6 +72,23 @@ public: ::CreateIoCompletionPort(sock_as_handle, iocp_.handle, 0, 0); } + struct auto_work + { + auto_work(win_iocp_io_service& io_service) + : io_service_(io_service) + { + io_service_.work_started(); + } + + ~auto_work() + { + io_service_.work_finished(); + } + + private: + win_iocp_io_service& io_service_; + }; + // Run the event processing loop. void run() { @@ -100,22 +117,7 @@ public: { // Ensure that the io_service does not exit due to running out of work // while we make the upcall. - struct auto_work - { - auto_work(win_iocp_io_service& io_service) - : io_service_(io_service) - { - io_service_.work_started(); - } - - ~auto_work() - { - io_service_.work_finished(); - } - - private: - win_iocp_io_service& io_service_; - } work(*this); + auto_work work(*this); // Dispatch the operation. operation* op = static_cast(overlapped);