This file is indexed.

/usr/share/doc/libpion-doc/html/scheduler_8cpp_source.html is in libpion-doc 5.0.4+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>pion: src/scheduler.cpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
    </ul>
  </div>
<h1>src/scheduler.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00002"></a>00002 <span class="comment">// pion:  a Boost C++ framework for building lightweight HTTP interfaces</span>
<a name="l00003"></a>00003 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (C) 2007-2012 Cloudmeter, Inc.  (http://www.cloudmeter.com)</span>
<a name="l00005"></a>00005 <span class="comment">//</span>
<a name="l00006"></a>00006 <span class="comment">// Distributed under the Boost Software License, Version 1.0.</span>
<a name="l00007"></a>00007 <span class="comment">// See http://www.boost.org/LICENSE_1_0.txt</span>
<a name="l00008"></a>00008 <span class="comment">//</span>
<a name="l00009"></a>00009 
<a name="l00010"></a>00010 <span class="preprocessor">#include &lt;boost/exception/diagnostic_information.hpp&gt;</span>
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;boost/date_time/posix_time/posix_time_duration.hpp&gt;</span>
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;pion/scheduler.hpp&gt;</span>
<a name="l00013"></a>00013 
<a name="l00014"></a>00014 <span class="keyword">namespace </span>pion {    <span class="comment">// begin namespace pion</span>
<a name="l00015"></a>00015 
<a name="l00016"></a>00016 
<a name="l00017"></a>00017 <span class="comment">// static members of scheduler</span>
<a name="l00018"></a>00018     
<a name="l00019"></a>00019 <span class="keyword">const</span> boost::uint32_t   <a class="code" href="classpion_1_1scheduler.html#ab8d6ac8ea6a3946abe86cbd20f0783e0" title="default number of worker threads in the thread pool">scheduler::DEFAULT_NUM_THREADS</a> = 8;
<a name="l00020"></a>00020 <span class="keyword">const</span> boost::uint32_t   <a class="code" href="classpion_1_1scheduler.html#aa5633b15c629c78c2aeb451ae428ea25" title="number of nanoseconds in one full second (10 ^ 9)">scheduler::NSEC_IN_SECOND</a> = 1000000000; <span class="comment">// (10^9)</span>
<a name="l00021"></a>00021 <span class="keyword">const</span> boost::uint32_t   <a class="code" href="classpion_1_1scheduler.html#acbe8f3104aa4713c93bbf3f2abe8615a" title="number of microseconds in one full second (10 ^ 6)">scheduler::MICROSEC_IN_SECOND</a> = 1000000;    <span class="comment">// (10^6)</span>
<a name="l00022"></a>00022 <span class="keyword">const</span> boost::uint32_t   <a class="code" href="classpion_1_1scheduler.html#a4f2047f8ecdaf5901f3548ee693b39ce" title="number of seconds a timer should wait for to keep the IO services running">scheduler::KEEP_RUNNING_TIMER_SECONDS</a> = 5;
<a name="l00023"></a>00023 
<a name="l00024"></a>00024 
<a name="l00025"></a>00025 <span class="comment">// scheduler member functions</span>
<a name="l00026"></a>00026 
<a name="l00027"></a><a class="code" href="classpion_1_1scheduler.html#a54887d0e772ed9c01156a46f2d89ce93">00027</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1scheduler.html#a54887d0e772ed9c01156a46f2d89ce93" title="Stops the thread scheduler (this is called automatically when the program exits)...">scheduler::shutdown</a>(<span class="keywordtype">void</span>)
<a name="l00028"></a>00028 {
<a name="l00029"></a>00029     <span class="comment">// lock mutex for thread safety</span>
<a name="l00030"></a>00030     boost::mutex::scoped_lock scheduler_lock(<a class="code" href="classpion_1_1scheduler.html#a0a1cf13bf9b31229c6d6f030ddbb0d09" title="mutex to make class thread-safe">m_mutex</a>);
<a name="l00031"></a>00031     
<a name="l00032"></a>00032     <span class="keywordflow">if</span> (<a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) {
<a name="l00033"></a>00033         
<a name="l00034"></a>00034         PION_LOG_INFO(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Shutting down the thread scheduler&quot;</span>);
<a name="l00035"></a>00035         
<a name="l00036"></a>00036         <span class="keywordflow">while</span> (<a class="code" href="classpion_1_1scheduler.html#aa8028397b2e084c8808032ac448955b8" title="the scheduler will not shutdown until there are no more active users">m_active_users</a> &gt; 0) {
<a name="l00037"></a>00037             <span class="comment">// first, wait for any active users to exit</span>
<a name="l00038"></a>00038             PION_LOG_INFO(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Waiting for &quot;</span> &lt;&lt; <a class="code" href="classpion_1_1scheduler.html#aa8028397b2e084c8808032ac448955b8" title="the scheduler will not shutdown until there are no more active users">m_active_users</a> &lt;&lt; <span class="stringliteral">&quot; scheduler users to finish&quot;</span>);
<a name="l00039"></a>00039             <a class="code" href="classpion_1_1scheduler.html#a35fe165b525a1babfa8dd2a602d0e598" title="condition triggered when there are no more active users">m_no_more_active_users</a>.wait(scheduler_lock);
<a name="l00040"></a>00040         }
<a name="l00041"></a>00041 
<a name="l00042"></a>00042         <span class="comment">// shut everything down</span>
<a name="l00043"></a>00043         <a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a> = <span class="keyword">false</span>;
<a name="l00044"></a>00044         <a class="code" href="classpion_1_1scheduler.html#a62b59f0561bd527d78768fd3a5ceeb36" title="stops all services used to schedule work">stop_services</a>();
<a name="l00045"></a>00045         <a class="code" href="classpion_1_1scheduler.html#abd7b1239bb9cf5a6ca1492341adfc4db" title="stops all threads used to perform work">stop_threads</a>();
<a name="l00046"></a>00046         <a class="code" href="classpion_1_1scheduler.html#a64dbc267db8e1481f80ba6d42bbb24ea" title="finishes all services used to schedule work">finish_services</a>();
<a name="l00047"></a>00047         <a class="code" href="classpion_1_1scheduler.html#a6436e075a8c23734e55329f4286b5509" title="finishes all threads used to perform work">finish_threads</a>();
<a name="l00048"></a>00048         
<a name="l00049"></a>00049         PION_LOG_INFO(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;The thread scheduler has shutdown&quot;</span>);
<a name="l00050"></a>00050 
<a name="l00051"></a>00051         <span class="comment">// Make sure anyone waiting on shutdown gets notified</span>
<a name="l00052"></a>00052         <a class="code" href="classpion_1_1scheduler.html#ab5321fccd4a1136f4358cce8679d22fd" title="condition triggered when the scheduler has stopped">m_scheduler_has_stopped</a>.notify_all();
<a name="l00053"></a>00053         
<a name="l00054"></a>00054     } <span class="keywordflow">else</span> {
<a name="l00055"></a>00055         
<a name="l00056"></a>00056         <span class="comment">// stop and finish everything to be certain that no events are pending</span>
<a name="l00057"></a>00057         <a class="code" href="classpion_1_1scheduler.html#a62b59f0561bd527d78768fd3a5ceeb36" title="stops all services used to schedule work">stop_services</a>();
<a name="l00058"></a>00058         <a class="code" href="classpion_1_1scheduler.html#abd7b1239bb9cf5a6ca1492341adfc4db" title="stops all threads used to perform work">stop_threads</a>();
<a name="l00059"></a>00059         <a class="code" href="classpion_1_1scheduler.html#a64dbc267db8e1481f80ba6d42bbb24ea" title="finishes all services used to schedule work">finish_services</a>();
<a name="l00060"></a>00060         <a class="code" href="classpion_1_1scheduler.html#a6436e075a8c23734e55329f4286b5509" title="finishes all threads used to perform work">finish_threads</a>();
<a name="l00061"></a>00061         
<a name="l00062"></a>00062         <span class="comment">// Make sure anyone waiting on shutdown gets notified</span>
<a name="l00063"></a>00063         <span class="comment">// even if the scheduler did not startup successfully</span>
<a name="l00064"></a>00064         <a class="code" href="classpion_1_1scheduler.html#ab5321fccd4a1136f4358cce8679d22fd" title="condition triggered when the scheduler has stopped">m_scheduler_has_stopped</a>.notify_all();
<a name="l00065"></a>00065     }
<a name="l00066"></a>00066 }
<a name="l00067"></a>00067 
<a name="l00068"></a><a class="code" href="classpion_1_1scheduler.html#ab9a1777f25b90f1970ea97035dd7310d">00068</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1scheduler.html#ab9a1777f25b90f1970ea97035dd7310d" title="the calling thread will sleep until the scheduler has stopped">scheduler::join</a>(<span class="keywordtype">void</span>)
<a name="l00069"></a>00069 {
<a name="l00070"></a>00070     boost::mutex::scoped_lock scheduler_lock(<a class="code" href="classpion_1_1scheduler.html#a0a1cf13bf9b31229c6d6f030ddbb0d09" title="mutex to make class thread-safe">m_mutex</a>);
<a name="l00071"></a>00071     <span class="keywordflow">while</span> (<a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) {
<a name="l00072"></a>00072         <span class="comment">// sleep until scheduler_has_stopped condition is signaled</span>
<a name="l00073"></a>00073         <a class="code" href="classpion_1_1scheduler.html#ab5321fccd4a1136f4358cce8679d22fd" title="condition triggered when the scheduler has stopped">m_scheduler_has_stopped</a>.wait(scheduler_lock);
<a name="l00074"></a>00074     }
<a name="l00075"></a>00075 }
<a name="l00076"></a>00076     
<a name="l00077"></a><a class="code" href="classpion_1_1scheduler.html#a8bda557ed5c95e2fbec96e14c793e844">00077</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1scheduler.html#a8bda557ed5c95e2fbec96e14c793e844">scheduler::keep_running</a>(boost::asio::io_service&amp; my_service,
<a name="l00078"></a>00078                                 boost::asio::deadline_timer&amp; my_timer)
<a name="l00079"></a>00079 {
<a name="l00080"></a>00080     <span class="keywordflow">if</span> (<a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) {
<a name="l00081"></a>00081         <span class="comment">// schedule this again to make sure the service doesn&apos;t complete</span>
<a name="l00082"></a>00082         my_timer.expires_from_now(boost::posix_time::seconds(<a class="code" href="classpion_1_1scheduler.html#a4f2047f8ecdaf5901f3548ee693b39ce" title="number of seconds a timer should wait for to keep the IO services running">KEEP_RUNNING_TIMER_SECONDS</a>));
<a name="l00083"></a>00083         my_timer.async_wait(boost::bind(&amp;<a class="code" href="classpion_1_1scheduler.html#a8bda557ed5c95e2fbec96e14c793e844">scheduler::keep_running</a>, <span class="keyword">this</span>,
<a name="l00084"></a>00084                                         boost::ref(my_service), boost::ref(my_timer)));
<a name="l00085"></a>00085     }
<a name="l00086"></a>00086 }
<a name="l00087"></a>00087 
<a name="l00088"></a><a class="code" href="classpion_1_1scheduler.html#aff5a6778a3a6174d7d684b709901d1d0">00088</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1scheduler.html#aff5a6778a3a6174d7d684b709901d1d0">scheduler::add_active_user</a>(<span class="keywordtype">void</span>)
<a name="l00089"></a>00089 {
<a name="l00090"></a>00090     <span class="keywordflow">if</span> (!<a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) <a class="code" href="classpion_1_1scheduler.html#ab656139dc844a547d5c1001b3ef17d13" title="Starts the thread scheduler (this is called automatically when necessary).">startup</a>();
<a name="l00091"></a>00091     boost::mutex::scoped_lock scheduler_lock(<a class="code" href="classpion_1_1scheduler.html#a0a1cf13bf9b31229c6d6f030ddbb0d09" title="mutex to make class thread-safe">m_mutex</a>);
<a name="l00092"></a>00092     ++<a class="code" href="classpion_1_1scheduler.html#aa8028397b2e084c8808032ac448955b8" title="the scheduler will not shutdown until there are no more active users">m_active_users</a>;
<a name="l00093"></a>00093 }
<a name="l00094"></a>00094 
<a name="l00095"></a><a class="code" href="classpion_1_1scheduler.html#a402e15e25d6c4b63241a636bd3ca53cf">00095</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1scheduler.html#a402e15e25d6c4b63241a636bd3ca53cf" title="unregisters an active user with the thread scheduler">scheduler::remove_active_user</a>(<span class="keywordtype">void</span>)
<a name="l00096"></a>00096 {
<a name="l00097"></a>00097     boost::mutex::scoped_lock scheduler_lock(<a class="code" href="classpion_1_1scheduler.html#a0a1cf13bf9b31229c6d6f030ddbb0d09" title="mutex to make class thread-safe">m_mutex</a>);
<a name="l00098"></a>00098     <span class="keywordflow">if</span> (--<a class="code" href="classpion_1_1scheduler.html#aa8028397b2e084c8808032ac448955b8" title="the scheduler will not shutdown until there are no more active users">m_active_users</a> == 0)
<a name="l00099"></a>00099         <a class="code" href="classpion_1_1scheduler.html#a35fe165b525a1babfa8dd2a602d0e598" title="condition triggered when there are no more active users">m_no_more_active_users</a>.notify_all();
<a name="l00100"></a>00100 }
<a name="l00101"></a>00101 
<a name="l00102"></a><a class="code" href="classpion_1_1scheduler.html#ad4ca39f249281cb2c6bd354cc52d0b9e">00102</a> boost::system_time <a class="code" href="classpion_1_1scheduler.html#ad4ca39f249281cb2c6bd354cc52d0b9e">scheduler::get_wakeup_time</a>(boost::uint32_t sleep_sec,
<a name="l00103"></a>00103     boost::uint32_t sleep_nsec)
<a name="l00104"></a>00104 {
<a name="l00105"></a>00105     <span class="keywordflow">return</span> boost::get_system_time() + boost::posix_time::seconds(sleep_sec) + boost::posix_time::microseconds(sleep_nsec / 1000);
<a name="l00106"></a>00106 }
<a name="l00107"></a>00107                      
<a name="l00108"></a><a class="code" href="classpion_1_1scheduler.html#a53cdc5fc1fb829de12cefd4183021d28">00108</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1scheduler.html#a53cdc5fc1fb829de12cefd4183021d28" title="processes work passed to the asio service &amp;amp; handles uncaught exceptions">scheduler::process_service_work</a>(boost::asio::io_service&amp; service) {
<a name="l00109"></a>00109     <span class="keywordflow">while</span> (<a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) {
<a name="l00110"></a>00110         <span class="keywordflow">try</span> {
<a name="l00111"></a>00111             service.run();
<a name="l00112"></a>00112         } <span class="keywordflow">catch</span> (std::exception&amp; e) {
<a name="l00113"></a>00113             PION_LOG_ERROR(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, boost::diagnostic_information(e));
<a name="l00114"></a>00114         } <span class="keywordflow">catch</span> (...) {
<a name="l00115"></a>00115             PION_LOG_ERROR(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;caught unrecognized exception&quot;</span>);
<a name="l00116"></a>00116         }
<a name="l00117"></a>00117     }   
<a name="l00118"></a>00118 }
<a name="l00119"></a>00119                      
<a name="l00120"></a>00120 
<a name="l00121"></a>00121 <span class="comment">// single_service_scheduler member functions</span>
<a name="l00122"></a>00122 
<a name="l00123"></a><a class="code" href="classpion_1_1single__service__scheduler.html#a1f7e3583fb384e97eea9303201ae1631">00123</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1single__service__scheduler.html#a1f7e3583fb384e97eea9303201ae1631" title="Starts the thread scheduler (this is called automatically when necessary).">single_service_scheduler::startup</a>(<span class="keywordtype">void</span>)
<a name="l00124"></a>00124 {
<a name="l00125"></a>00125     <span class="comment">// lock mutex for thread safety</span>
<a name="l00126"></a>00126     boost::mutex::scoped_lock scheduler_lock(<a class="code" href="classpion_1_1scheduler.html#a0a1cf13bf9b31229c6d6f030ddbb0d09" title="mutex to make class thread-safe">m_mutex</a>);
<a name="l00127"></a>00127     
<a name="l00128"></a>00128     <span class="keywordflow">if</span> (! <a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) {
<a name="l00129"></a>00129         PION_LOG_INFO(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Starting thread scheduler&quot;</span>);
<a name="l00130"></a>00130         <a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a> = <span class="keyword">true</span>;
<a name="l00131"></a>00131         
<a name="l00132"></a>00132         <span class="comment">// schedule a work item to make sure that the service doesn&apos;t complete</span>
<a name="l00133"></a>00133         <a class="code" href="classpion_1_1single__service__scheduler.html#a2c46174147ba01f522f5e2e0a9f81d8c" title="service used to manage async I/O events">m_service</a>.reset();
<a name="l00134"></a>00134         <a class="code" href="classpion_1_1scheduler.html#a8bda557ed5c95e2fbec96e14c793e844">keep_running</a>(<a class="code" href="classpion_1_1single__service__scheduler.html#a2c46174147ba01f522f5e2e0a9f81d8c" title="service used to manage async I/O events">m_service</a>, <a class="code" href="classpion_1_1single__service__scheduler.html#a5898ac8ca81dfedb2b38b14d63519c2d" title="timer used to periodically check for shutdown">m_timer</a>);
<a name="l00135"></a>00135         
<a name="l00136"></a>00136         <span class="comment">// start multiple threads to handle async tasks</span>
<a name="l00137"></a>00137         <span class="keywordflow">for</span> (boost::uint32_t n = 0; n &lt; <a class="code" href="classpion_1_1scheduler.html#a0ecf6f549714b0e9e33fea80a11a073f" title="total number of worker threads in the pool">m_num_threads</a>; ++n) {
<a name="l00138"></a>00138             boost::shared_ptr&lt;boost::thread&gt; new_thread(<span class="keyword">new</span> boost::thread( boost::bind(&amp;<a class="code" href="classpion_1_1scheduler.html#a53cdc5fc1fb829de12cefd4183021d28" title="processes work passed to the asio service &amp;amp; handles uncaught exceptions">scheduler::process_service_work</a>,
<a name="l00139"></a>00139                                                                                        <span class="keyword">this</span>, boost::ref(<a class="code" href="classpion_1_1single__service__scheduler.html#a2c46174147ba01f522f5e2e0a9f81d8c" title="service used to manage async I/O events">m_service</a>)) ));
<a name="l00140"></a>00140             <a class="code" href="classpion_1_1multi__thread__scheduler.html#ad2b984248e4b064faae3cc3c7e75d30e" title="pool of threads used to perform work">m_thread_pool</a>.push_back(new_thread);
<a name="l00141"></a>00141         }
<a name="l00142"></a>00142     }
<a name="l00143"></a>00143 }
<a name="l00144"></a>00144 
<a name="l00145"></a>00145     
<a name="l00146"></a>00146 <span class="comment">// one_to_one_scheduler member functions</span>
<a name="l00147"></a>00147 
<a name="l00148"></a><a class="code" href="classpion_1_1one__to__one__scheduler.html#a8f32fd88bc0d95d9952c5045849e09b9">00148</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1one__to__one__scheduler.html#a8f32fd88bc0d95d9952c5045849e09b9" title="Starts the thread scheduler (this is called automatically when necessary).">one_to_one_scheduler::startup</a>(<span class="keywordtype">void</span>)
<a name="l00149"></a>00149 {
<a name="l00150"></a>00150     <span class="comment">// lock mutex for thread safety</span>
<a name="l00151"></a>00151     boost::mutex::scoped_lock scheduler_lock(<a class="code" href="classpion_1_1scheduler.html#a0a1cf13bf9b31229c6d6f030ddbb0d09" title="mutex to make class thread-safe">m_mutex</a>);
<a name="l00152"></a>00152     
<a name="l00153"></a>00153     <span class="keywordflow">if</span> (! <a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a>) {
<a name="l00154"></a>00154         PION_LOG_INFO(<a class="code" href="classpion_1_1scheduler.html#aa611e2e63bc69eefce43c243846d99e5" title="primary logging interface used by this class">m_logger</a>, <span class="stringliteral">&quot;Starting thread scheduler&quot;</span>);
<a name="l00155"></a>00155         <a class="code" href="classpion_1_1scheduler.html#a1fa5ef108570fe6c4a984fb1c01e8bd9" title="true if the thread scheduler is running">m_is_running</a> = <span class="keyword">true</span>;
<a name="l00156"></a>00156         
<a name="l00157"></a>00157         <span class="comment">// make sure there are enough services initialized</span>
<a name="l00158"></a>00158         <span class="keywordflow">while</span> (<a class="code" href="classpion_1_1one__to__one__scheduler.html#a8b6ae075086a579e46ca08a89085c07a" title="pool of IO services used to schedule work">m_service_pool</a>.size() &lt; <a class="code" href="classpion_1_1scheduler.html#a0ecf6f549714b0e9e33fea80a11a073f" title="total number of worker threads in the pool">m_num_threads</a>) {
<a name="l00159"></a>00159             boost::shared_ptr&lt;service_pair_type&gt;  service_ptr(<span class="keyword">new</span> <a class="code" href="structpion_1_1one__to__one__scheduler_1_1service__pair__type.html" title="typedef for a pair object where first is an IO service and second is a deadline timer...">service_pair_type</a>());
<a name="l00160"></a>00160             <a class="code" href="classpion_1_1one__to__one__scheduler.html#a8b6ae075086a579e46ca08a89085c07a" title="pool of IO services used to schedule work">m_service_pool</a>.push_back(service_ptr);
<a name="l00161"></a>00161         }
<a name="l00162"></a>00162 
<a name="l00163"></a>00163         <span class="comment">// schedule a work item for each service to make sure that it doesn&apos;t complete</span>
<a name="l00164"></a>00164         <span class="keywordflow">for</span> (service_pool_type::iterator i = <a class="code" href="classpion_1_1one__to__one__scheduler.html#a8b6ae075086a579e46ca08a89085c07a" title="pool of IO services used to schedule work">m_service_pool</a>.begin(); i != <a class="code" href="classpion_1_1one__to__one__scheduler.html#a8b6ae075086a579e46ca08a89085c07a" title="pool of IO services used to schedule work">m_service_pool</a>.end(); ++i) {
<a name="l00165"></a>00165             <a class="code" href="classpion_1_1scheduler.html#a8bda557ed5c95e2fbec96e14c793e844">keep_running</a>((*i)-&gt;first, (*i)-&gt;second);
<a name="l00166"></a>00166         }
<a name="l00167"></a>00167         
<a name="l00168"></a>00168         <span class="comment">// start multiple threads to handle async tasks</span>
<a name="l00169"></a>00169         <span class="keywordflow">for</span> (boost::uint32_t n = 0; n &lt; <a class="code" href="classpion_1_1scheduler.html#a0ecf6f549714b0e9e33fea80a11a073f" title="total number of worker threads in the pool">m_num_threads</a>; ++n) {
<a name="l00170"></a>00170             boost::shared_ptr&lt;boost::thread&gt; new_thread(<span class="keyword">new</span> boost::thread( boost::bind(&amp;<a class="code" href="classpion_1_1scheduler.html#a53cdc5fc1fb829de12cefd4183021d28" title="processes work passed to the asio service &amp;amp; handles uncaught exceptions">scheduler::process_service_work</a>,
<a name="l00171"></a>00171                                                                                        <span class="keyword">this</span>, boost::ref(<a class="code" href="classpion_1_1one__to__one__scheduler.html#a8b6ae075086a579e46ca08a89085c07a" title="pool of IO services used to schedule work">m_service_pool</a>[n]-&gt;first)) ));
<a name="l00172"></a>00172             <a class="code" href="classpion_1_1multi__thread__scheduler.html#ad2b984248e4b064faae3cc3c7e75d30e" title="pool of threads used to perform work">m_thread_pool</a>.push_back(new_thread);
<a name="l00173"></a>00173         }
<a name="l00174"></a>00174     }
<a name="l00175"></a>00175 }
<a name="l00176"></a>00176 
<a name="l00177"></a>00177     
<a name="l00178"></a>00178 }   <span class="comment">// end namespace pion</span>
</pre></div></div>
<hr size="1"/><address style="text-align: right;"><small>Generated on 16 Sep 2013 for pion by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
</body>
</html>