Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49203 - trunk/boost/asio/detail
From: chris_at_[hidden]
Date: 2008-10-09 02:39:06


Author: chris_kohlhoff
Date: 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
New Revision: 49203
URL: http://svn.boost.org/trac/boost/changeset/49203

Log:
Reduce memory usage by doing lazy initialisation of the io_service's reactor.

Text files modified:
   trunk/boost/asio/detail/deadline_timer_service.hpp | 1 +
   trunk/boost/asio/detail/dev_poll_reactor.hpp | 11 +++++++++++
   trunk/boost/asio/detail/epoll_reactor.hpp | 10 ++++++++++
   trunk/boost/asio/detail/kqueue_reactor.hpp | 10 ++++++++++
   trunk/boost/asio/detail/reactive_descriptor_service.hpp | 1 +
   trunk/boost/asio/detail/reactive_socket_service.hpp | 1 +
   trunk/boost/asio/detail/select_reactor.hpp | 10 ++++++++++
   trunk/boost/asio/detail/task_io_service.hpp | 31 +++++++++++++++++++++----------
   trunk/boost/asio/detail/task_io_service_2lock.hpp | 31 +++++++++++++++++++++----------
   trunk/boost/asio/detail/win_iocp_io_service.hpp | 5 +++++
   10 files changed, 91 insertions(+), 20 deletions(-)

Modified: trunk/boost/asio/detail/deadline_timer_service.hpp
==============================================================================
--- trunk/boost/asio/detail/deadline_timer_service.hpp (original)
+++ trunk/boost/asio/detail/deadline_timer_service.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -64,6 +64,7 @@
         deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
       scheduler_(boost::asio::use_service<Timer_Scheduler>(io_service))
   {
+ scheduler_.init_task();
     scheduler_.add_timer_queue(timer_queue_);
   }
 

Modified: trunk/boost/asio/detail/dev_poll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/dev_poll_reactor.hpp (original)
+++ trunk/boost/asio/detail/dev_poll_reactor.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -123,6 +123,17 @@
     timer_queues_.clear();
   }
 
+ // Initialise the task, but only if the reactor is not in its own thread.
+ void init_task()
+ {
+ if (!Own_Thread)
+ {
+ typedef task_io_service<dev_poll_reactor<Own_Thread> >
+ task_io_service_type;
+ use_service<task_io_service_type>(this->get_io_service()).init_task();
+ }
+ }
+
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
   int register_descriptor(socket_type, per_descriptor_data&)

Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp (original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -124,6 +124,16 @@
     timer_queues_.clear();
   }
 
+ // Initialise the task, but only if the reactor is not in its own thread.
+ void init_task()
+ {
+ if (!Own_Thread)
+ {
+ typedef task_io_service<epoll_reactor<Own_Thread> > task_io_service_type;
+ use_service<task_io_service_type>(this->get_io_service()).init_task();
+ }
+ }
+
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
   int register_descriptor(socket_type descriptor,

Modified: trunk/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor.hpp (original)
+++ trunk/boost/asio/detail/kqueue_reactor.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -132,6 +132,16 @@
     timer_queues_.clear();
   }
 
+ // Initialise the task, but only if the reactor is not in its own thread.
+ void init_task()
+ {
+ if (!Own_Thread)
+ {
+ typedef task_io_service<kqueue_reactor<Own_Thread> > task_io_service_type;
+ use_service<task_io_service_type>(this->get_io_service()).init_task();
+ }
+ }
+
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
   int register_descriptor(socket_type, per_descriptor_data& descriptor_data)

Modified: trunk/boost/asio/detail/reactive_descriptor_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_descriptor_service.hpp (original)
+++ trunk/boost/asio/detail/reactive_descriptor_service.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -82,6 +82,7 @@
         reactive_descriptor_service<Reactor> >(io_service),
       reactor_(boost::asio::use_service<Reactor>(io_service))
   {
+ reactor_.init_task();
   }
 
   // Destroy all user-defined handler objects owned by the service.

Modified: trunk/boost/asio/detail/reactive_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_socket_service.hpp (original)
+++ trunk/boost/asio/detail/reactive_socket_service.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -110,6 +110,7 @@
         reactive_socket_service<Protocol, Reactor> >(io_service),
       reactor_(boost::asio::use_service<Reactor>(io_service))
   {
+ reactor_.init_task();
   }
 
   // Destroy all user-defined handler objects owned by the service.

Modified: trunk/boost/asio/detail/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor.hpp (original)
+++ trunk/boost/asio/detail/select_reactor.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -111,6 +111,16 @@
     timer_queues_.clear();
   }
 
+ // Initialise the task, but only if the reactor is not in its own thread.
+ void init_task()
+ {
+ if (!Own_Thread)
+ {
+ typedef task_io_service<select_reactor<Own_Thread> > task_io_service_type;
+ use_service<task_io_service_type>(this->get_io_service()).init_task();
+ }
+ }
+
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
   int register_descriptor(socket_type, per_descriptor_data&)

Modified: trunk/boost/asio/detail/task_io_service.hpp
==============================================================================
--- trunk/boost/asio/detail/task_io_service.hpp (original)
+++ trunk/boost/asio/detail/task_io_service.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -44,14 +44,13 @@
   task_io_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<task_io_service<Task> >(io_service),
       mutex_(),
- task_(use_service<Task>(io_service)),
+ task_(0),
       task_interrupted_(true),
       outstanding_work_(0),
       stopped_(false),
       shutdown_(false),
       first_idle_thread_(0)
   {
- handler_queue_.push(&task_handler_);
   }
 
   void init(size_t /*concurrency_hint*/)
@@ -74,8 +73,20 @@
         h->destroy();
     }
 
- // Reset handler queue to initial state.
- handler_queue_.push(&task_handler_);
+ // Reset to initial state.
+ task_ = 0;
+ }
+
+ // Initialise the task, if required.
+ void init_task()
+ {
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (!shutdown_ && !task_)
+ {
+ task_ = &use_service<Task>(this->get_io_service());
+ handler_queue_.push(&task_handler_);
+ interrupt_one_idle_thread(lock);
+ }
   }
 
   // Run the event loop until interrupted or no more work.
@@ -194,10 +205,10 @@
     // Wake up a thread to execute the handler.
     if (!interrupt_one_idle_thread(lock))
     {
- if (!task_interrupted_)
+ if (!task_interrupted_ && task_)
       {
         task_interrupted_ = true;
- task_.interrupt();
+ task_->interrupt();
       }
     }
   }
@@ -246,7 +257,7 @@
           // Run the task. May throw an exception. Only block if the handler
           // queue is empty and we have an idle_thread_info object, otherwise
           // we want to return as soon as possible.
- task_.run(!more_handlers && !polling);
+ task_->run(!more_handlers && !polling);
         }
         else
         {
@@ -285,10 +296,10 @@
   {
     stopped_ = true;
     interrupt_all_idle_threads(lock);
- if (!task_interrupted_)
+ if (!task_interrupted_ && task_)
     {
       task_interrupted_ = true;
- task_.interrupt();
+ task_->interrupt();
     }
   }
 
@@ -376,7 +387,7 @@
   boost::asio::detail::mutex mutex_;
 
   // The task to be run by this service.
- Task& task_;
+ Task* task_;
 
   // Handler object to represent the position of the task in the queue.
   class task_handler

Modified: trunk/boost/asio/detail/task_io_service_2lock.hpp
==============================================================================
--- trunk/boost/asio/detail/task_io_service_2lock.hpp (original)
+++ trunk/boost/asio/detail/task_io_service_2lock.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -50,7 +50,7 @@
     : boost::asio::detail::service_base<task_io_service<Task> >(io_service),
       front_mutex_(),
       back_mutex_(),
- task_(use_service<Task>(io_service)),
+ task_(&use_service<Task>(io_service)),
       outstanding_work_(0),
       front_stopped_(false),
       back_stopped_(false),
@@ -58,7 +58,6 @@
       back_first_idle_thread_(0),
       back_task_thread_(0)
   {
- handler_queue_.push(&task_handler_);
   }
 
   void init(size_t /*concurrency_hint*/)
@@ -77,8 +76,20 @@
       if (h != &task_handler_)
         h->destroy();
 
- // Reset handler queue to initial state.
- handler_queue_.push(&task_handler_);
+ // Reset to initial state.
+ task_ = 0;
+ }
+
+ // Initialise the task, if required.
+ void init_task()
+ {
+ boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
+ if (!back_shutdown_ && !task_)
+ {
+ task_ = &use_service<Task>(this->get_io_service());
+ handler_queue_.push(&task_handler_);
+ interrupt_one_idle_thread(back_lock);
+ }
   }
 
   // Run the event loop until interrupted or no more work.
@@ -287,7 +298,7 @@
           // queue is empty and we're not polling, otherwise we want to return
           // as soon as possible.
           task_has_run = true;
- task_.run(!more_handlers && !polling);
+ task_->run(!more_handlers && !polling);
         }
         else
         {
@@ -342,10 +353,10 @@
       idle_thread->next = 0;
       idle_thread->wakeup_event.signal(back_lock);
     }
- else if (back_task_thread_)
+ else if (back_task_thread_ && task_)
     {
       back_task_thread_ = 0;
- task_.interrupt();
+ task_->interrupt();
     }
   }
 
@@ -361,10 +372,10 @@
       idle_thread->wakeup_event.signal(back_lock);
     }
 
- if (back_task_thread_)
+ if (back_task_thread_ && task_)
     {
       back_task_thread_ = 0;
- task_.interrupt();
+ task_->interrupt();
     }
   }
 
@@ -415,7 +426,7 @@
   boost::asio::detail::mutex back_mutex_;
 
   // The task to be run by this service.
- Task& task_;
+ Task* task_;
 
   // Handler object to represent the position of the task in the queue.
   class task_handler

Modified: trunk/boost/asio/detail/win_iocp_io_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_io_service.hpp (original)
+++ trunk/boost/asio/detail/win_iocp_io_service.hpp 2008-10-09 02:39:05 EDT (Thu, 09 Oct 2008)
@@ -149,6 +149,11 @@
     timer_queues_.clear();
   }
 
+ // Initialise the task. Nothing to do here.
+ void init_task()
+ {
+ }
+
   // Register a handle with the IO completion port.
   boost::system::error_code register_handle(
       HANDLE handle, boost::system::error_code& ec)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk