1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Timer.3 - Binding arguments to a handler</title> 5<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../boost_asio.html" title="Boost.Asio"> 8<link rel="up" href="../tutorial.html" title="Tutorial"> 9<link rel="prev" href="tuttimer2/src.html" title="Source listing for Timer.2"> 10<link rel="next" href="tuttimer3/src.html" title="Source listing for Timer.3"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td> 15<td align="center"><a href="../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="tuttimer2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="boost_asio.tutorial.tuttimer3"></a><a class="link" href="tuttimer3.html" title="Timer.3 - Binding arguments to a handler">Timer.3 - Binding arguments 28 to a handler</a> 29</h3></div></div></div> 30<p> 31 In this tutorial we will modify the program from tutorial Timer.2 so that 32 the timer fires once a second. This will show how to pass additional parameters 33 to your handler function. 34 </p> 35<pre class="programlisting">#include <iostream> 36#include <boost/asio.hpp> 37#include <boost/bind/bind.hpp> 38</pre> 39<p> 40 To implement a repeating timer using asio you need to change the timer's 41 expiry time in your callback function, and to then start a new asynchronous 42 wait. Obviously this means that the callback function will need to be able 43 to access the timer object. To this end we add two new parameters to the 44 <code class="computeroutput">print</code> function: 45 </p> 46<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 47<li class="listitem"> 48 A pointer to a timer object. 49 </li> 50<li class="listitem"> 51 A counter so that we can stop the program when the timer fires for the 52 sixth time. 53 </li> 54</ul></div> 55<pre class="programlisting">void print(const boost::system::error_code& /*e*/, 56 boost::asio::steady_timer* t, int* count) 57{ 58</pre> 59<p> 60 As mentioned above, this tutorial program uses a counter to stop running 61 when the timer fires for the sixth time. However you will observe that there 62 is no explicit call to ask the io_context to stop. Recall that in tutorial 63 Timer.2 we learnt that the <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a> 64 function completes when there is no more "work" to do. By not starting 65 a new asynchronous wait on the timer when <code class="computeroutput">count</code> reaches 5, the 66 io_context will run out of work and stop running. 67 </p> 68<pre class="programlisting"> if (*count < 5) 69 { 70 std::cout << *count << std::endl; 71 ++(*count); 72</pre> 73<p> 74 Next we move the expiry time for the timer along by one second from the previous 75 expiry time. By calculating the new expiry time relative to the old, we can 76 ensure that the timer does not drift away from the whole-second mark due 77 to any delays in processing the handler. 78 </p> 79<pre class="programlisting"> t->expires_at(t->expiry() + boost::asio::chrono::seconds(1)); 80</pre> 81<p> 82 Then we start a new asynchronous wait on the timer. As you can see, the boost::bind() 83 function is used to associate the extra parameters with your callback handler. 84 The <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a> 85 function expects a handler function (or function object) with the signature 86 <code class="computeroutput">void(const boost::system::error_code&)</code>. Binding the additional 87 parameters converts your <code class="computeroutput">print</code> function into a function object 88 that matches the signature correctly. 89 </p> 90<p> 91 See the <a href="http://www.boost.org/libs/bind/bind.html" target="_top">Boost.Bind 92 documentation</a> for more information on how to use boost::bind(). 93 </p> 94<p> 95 In this example, the boost::asio::placeholders::error argument to boost::bind() 96 is a named placeholder for the error object passed to the handler. When initiating 97 the asynchronous operation, and if using boost::bind(), you must specify 98 only the arguments that match the handler's parameter list. In tutorial Timer.4 99 you will see that this placeholder may be elided if the parameter is not 100 needed by the callback handler. 101 </p> 102<pre class="programlisting"> t->async_wait(boost::bind(print, 103 boost::asio::placeholders::error, t, count)); 104 } 105} 106 107int main() 108{ 109 boost::asio::io_context io; 110</pre> 111<p> 112 A new <code class="computeroutput">count</code> variable is added so that we can stop the program 113 when the timer fires for the sixth time. 114 </p> 115<pre class="programlisting"> int count = 0; 116 boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1)); 117</pre> 118<p> 119 As in Step 4, when making the call to <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a> 120 from <code class="computeroutput">main</code> we bind the additional parameters needed for the 121 <code class="computeroutput">print</code> function. 122 </p> 123<pre class="programlisting"> t.async_wait(boost::bind(print, 124 boost::asio::placeholders::error, &t, &count)); 125 126 io.run(); 127</pre> 128<p> 129 Finally, just to prove that the <code class="computeroutput">count</code> variable was being used 130 in the <code class="computeroutput">print</code> handler function, we will print out its new value. 131 </p> 132<pre class="programlisting"> std::cout << "Final count is " << count << std::endl; 133 134 return 0; 135} 136</pre> 137<p> 138 See the <a class="link" href="tuttimer3/src.html" title="Source listing for Timer.3">full source listing</a> 139 </p> 140<p> 141 Return to the <a class="link" href="../tutorial.html" title="Tutorial">tutorial index</a> 142 </p> 143<p> 144 Previous: <a class="link" href="tuttimer2.html" title="Timer.2 - Using a timer asynchronously">Timer.2 - Using a 145 timer asynchronously</a> 146 </p> 147<p> 148 Next: <a class="link" href="tuttimer4.html" title="Timer.4 - Using a member function as a handler">Timer.4 - Using a member 149 function as a handler</a> 150 </p> 151</div> 152<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 153<td align="left"></td> 154<td align="right"><div class="copyright-footer">Copyright © 2003-2020 Christopher M. 155 Kohlhoff<p> 156 Distributed under the Boost Software License, Version 1.0. (See accompanying 157 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) 158 </p> 159</div></td> 160</tr></table> 161<hr> 162<div class="spirit-nav"> 163<a accesskey="p" href="tuttimer2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a> 164</div> 165</body> 166</html> 167