@@ -27,49 +27,76 @@ static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("hedwig."__FILE__));
2727
2828using namespace Hedwig ;
2929
30- EventDispatcher::EventDispatcher () : service(), dummy_work(NULL ), t(NULL ) {
30+ EventDispatcher::EventDispatcher (int numThreads)
31+ : num_threads(numThreads), running(false ), next_io_service(0 ) {
32+ if (0 == num_threads) {
33+ throw std::runtime_error (" number of threads in dispatcher is zero" );
34+ }
35+ for (size_t i = 0 ; i < num_threads; i++) {
36+ io_service_ptr service (new boost::asio::io_service);
37+ services.push_back (service);
38+ }
3139}
3240
33- void EventDispatcher::run_forever () {
34- LOG4CXX_DEBUG (logger, " Starting event dispatcher" );
41+ void EventDispatcher::run_forever (io_service_ptr service, size_t idx ) {
42+ LOG4CXX_DEBUG (logger, " Starting event dispatcher " << idx );
3543
3644 while (true ) {
3745 try {
38- service. run ();
46+ service-> run ();
3947 break ;
4048 } catch (std::exception &e) {
41- LOG4CXX_ERROR (logger, " Exception in dispatch handler. " << e.what ());
49+ LOG4CXX_ERROR (logger, " Exception in dispatch handler " << idx << " : " << e.what ());
4250 }
4351 }
44- LOG4CXX_DEBUG (logger, " Event dispatcher done" );
52+ LOG4CXX_DEBUG (logger, " Event dispatcher " << idx << " done" );
4553}
4654
4755void EventDispatcher::start () {
48- if (t ) {
56+ if (running ) {
4957 return ;
5058 }
51- dummy_work = new boost::asio::io_service::work (service);
52- t = new boost::thread (boost::bind (&EventDispatcher::run_forever, this ));
59+ for (size_t i = 0 ; i < num_threads; i++) {
60+ io_service_ptr service = services[i];
61+ work_ptr work (new boost::asio::io_service::work (*service));
62+ works.push_back (work);
63+ // new thread
64+ thread_ptr t (new boost::thread (boost::bind (&EventDispatcher::run_forever, this , service, i)));
65+ threads.push_back (t);
66+ }
67+ running = true ;
5368}
5469
5570void EventDispatcher::stop () {
56- if (!t ) {
71+ if (!running ) {
5772 return ;
5873 }
59- delete dummy_work;
60- dummy_work = NULL ;
61-
62- service.stop ();
63-
64- t->join ();
65- delete t;
66- t = NULL ;
74+
75+ works.clear ();
76+
77+ for (size_t i = 0 ; i < num_threads; i++) {
78+ services[i]->stop ();
79+ }
80+
81+ for (size_t i = 0 ; i < num_threads; i++) {
82+ threads[i]->join ();
83+ }
84+ threads.clear ();
85+
86+ running = false ;
6787}
6888
6989EventDispatcher::~EventDispatcher () {
70- delete dummy_work ;
90+ services. clear () ;
7191}
7292
7393boost::asio::io_service& EventDispatcher::getService () {
94+ size_t next = 0 ;
95+ {
96+ boost::lock_guard<boost::mutex> lock (next_lock);
97+ next = next_io_service;
98+ next_io_service = (next_io_service + 1 ) % num_threads;
99+ }
100+ boost::asio::io_service& service = *services[next];
74101 return service;
75102}
0 commit comments