views:

277

answers:

1

There is a line in the 3rd tutorial on Boost asio that shows how to renew a timer and yet prevent there from being drift. The line is the following:

 t->expires_at(t->expires_at() + boost::posix_time::seconds(1));

Maybe it's me but I wasn't able to find documentation on the 2nd usage of expires_at(), with no parameters. expires_at(x) sets the new expiration, cancelling any pending completion handlers. So presumably expires_at() does what, return time of the last expiry? So by adding one second, if there should be some number of ms, say n ms, then it will in essence be "subtracted" from the next expiry since the time is being accounted for? What happens then if the time it takes to perform this handler is greater than 1 second in this example? Does it fire immediately?

+1  A: 

expires_at() return the time when it is set to timeout. So this will move the timeout to 1 second later.

When you set the time with expires_at(x) you will get a return of 0 if it already invoked due to time already passed. If return is bigger then 0 it indicates number of cancels that were made.

jpyllman
Not sure I understand your first sentence. expires_at() returns a posix time (in this case posix). but in this line of code it's being executed *within* the completion handler, so the expiration is in the past (just happened a split moment ago). So if I understand the effect is that you are adding time in the past with 1 second, thereby accounting for the time you're taking *now* to do the completion handler (whatever code preceded this line). That is how drift is avoided right? Otherwise you're adding 1 second + the time it took to execute the code preceeding this line?
ApplePieIsGood
This will add 1 second to the time it was supposed to invoke the handler. So if you have a delay for some reason before coming into the handler it is less then one second before it would invoke the handler again. Or in the special case it will just put it on the queue because it should have been handled already, cause it took to long to reach this code. If you think it is a big risk 1s is to small you should maybe use expires_from_now(x) instead to set 1s from now.
jpyllman