Boost C++ Libraries: Ticket #3504: deadline_timer (based on UTC time) is not suitable for communication timeouts https://svn.boost.org/trac10/ticket/3504 <p> If you use the deadline_timer to make a polling every 10th second, it will be heavely affected if someone adjust the system clock with date command, or if the time is adjusted automaticly by NTP. </p> <p> Uses as this should use a timer that cannot make jumps like that. </p> <p> I solved this by making a new time_traits called monotone_time. It uses <a class="missing wiki">GetTickCount</a>() for windows and clock_gettime(CLOCK_MONOTONIC, ...) for linux. See attachment. </p> <p> To use it your timer must be a monotone_timer instead of a deadline_timer. You can use both types of timers in you application. </p> <p> I hope this can be a part of a future release of boost::asio </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3504 Trac 1.4.3 Bjarne Laursen <bla@…> Fri, 02 Oct 2009 07:39:22 GMT attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">monotone_timer.hpp</span> </li> </ul> <p> monotone_timer.hpp </p> Ticket Pau Garcia i Quiles <pgquiles@…> Mon, 23 Nov 2009 12:50:27 GMT version changed; cc set https://svn.boost.org/trac10/ticket/3504#comment:1 https://svn.boost.org/trac10/ticket/3504#comment:1 <ul> <li><strong>cc</strong> <span class="trac-author">pgquiles@…</span> added </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.38.0</span> → <span class="trac-field-new">Boost 1.41.0</span> </li> </ul> <p> I can confirm Asio timers are broken if you set the date back/forward. The timer does not need to fire any fast, you can fire the timer just once a day and it will fail if you do this: </p> <ol><li>Let's say the time now is 2009-11-23 13:45:20 </li><li>Start timer with deadline in 1 hour. Asio watches the system and will fire the timer at 2009-11-23 14:45:20. </li><li>Set date back 1 day: 2009-11-22 13:45:20 </li><li>Timer never fires </li></ol><p> While Bjarne's solution is good, the #ifdef for Linux is not. It should not check for Linux but for platforms where clock_gettime is available, which is done with "#if defined(_POSIX_TIMERS) &amp;&amp; ( _POSIX_TIMERS &gt; 0 ) &amp;&amp; defined(_POSIX_MONOTONIC_CLOCK)". </p> <p> I've fixed Bjarne's code and uploaded the attachment. </p> <p> In addition to that, on Linux with glibc &gt;= 2.11, linking with librt is required. Linux with glibc &lt;= 2.9 does not need linking with librt but it does not do any harm, either. FreeBSD and Mac OS X do not need linking with librt. </p> Ticket Pau Garcia i Quiles <pgquiles@…> Mon, 23 Nov 2009 12:52:18 GMT attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">monotone_timer.hpp-PROPER_IFDEF</span> </li> </ul> <p> Fix #ifdef for Unix platforms </p> Ticket victor Wed, 30 Dec 2009 08:41:13 GMT attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">monotone_timer.2.hpp</span> </li> </ul> <p> discard mutex on windows </p> Ticket victor Wed, 30 Dec 2009 08:45:02 GMT <link>https://svn.boost.org/trac10/ticket/3504#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:2</guid> <description> <p> There is static mutex in function 'now' on windows. If there r lots of connection which own monotone_timer, ther will be execute one by one because this static mutex. I fixed the code and unploaded the attachment </p> </description> <category>Ticket</category> </item> <item> <dc:creator>chris_kohlhoff</dc:creator> <pubDate>Tue, 12 Jan 2010 22:17:44 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/3504#comment:3 https://svn.boost.org/trac10/ticket/3504#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> I agree with the need for a monotonic timer. However, I consider the provision of a monotonic clock to be out of scope for asio. The date_time library might be better. Alternatively, once c++0x library implementations are available we may use those. Once a monotonic clock is available I will look at adding a monotonic_timer to asio. </p> Ticket anonymous Wed, 13 Jan 2010 08:43:46 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/3504#comment:4 https://svn.boost.org/trac10/ticket/3504#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">wontfix</span> </li> </ul> <p> Let me disagree. Timers are implemented in asio, not in date_time. Even if only for coherence (other timers are implemented in asio not in date_time), it makes no sense at all to implement the monotonic timer in date_time instead of asio. Please, reconsider your position. </p> Ticket chris_kohlhoff Wed, 13 Jan 2010 11:48:53 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3504#comment:5 https://svn.boost.org/trac10/ticket/3504#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> Let me restate: </p> <ul><li>Yes, a monotonic_timer would be a good addition to asio. Asio is the right place for this. </li></ul><ul><li>A monotonic clock is a prerequisite for a monotonic_timer. </li></ul><ul><li>The provision of a monotonic <strong>clock</strong> is <strong>out of scope</strong> for asio as far as I'm concerned. By clock, I mean the monotonic equivalent of boost::posix_time::microsec_clock::universal_time(). </li></ul><p> I hope that makes it clear. </p> Ticket anonymous Thu, 28 Jan 2010 21:54:33 GMT <link>https://svn.boost.org/trac10/ticket/3504#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:2" title="Comment 2">victor</a>: </p> <blockquote class="citation"> <p> There is static mutex in function 'now' on windows. If there r lots of connection which own monotone_timer, ther will be execute one by one because this static mutex. I fixed the code and unploaded the attachment </p> </blockquote> <p> this version uses _ftime instead of <a class="missing wiki">GetTickCount</a> for windows. The original problem seems to return using any system time function other than <a class="missing wiki">GetTickCount</a> ??? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 15 Mar 2010 02:52:03 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">monotone_timer.hpp-NO_MUTEX</span> </li> </ul> <p> Removed need for mutex while maintaining monotonic functionality </p> Ticket anonymous Mon, 15 Mar 2010 06:10:52 GMT <link>https://svn.boost.org/trac10/ticket/3504#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:7</guid> <description> <p> I've looked into the QueryPerformanceXXXXX functions and it seems they may not be as accurate as I would like. While the <a class="missing wiki">GetTickCount</a> version requires a mutex it may be better to suffer a possible small performance hit in order to maintain accuracy. </p> <p> If anyone has any up to date knowledge of any issues with the QueryPerformanceXXXXX functions I would appreciate it. </p> </description> <category>Ticket</category> </item> <item> <author>simon.reye@…</author> <pubDate>Mon, 15 Mar 2010 22:28:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:8</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:7" title="Comment 7">anonymous</a>: </p> <blockquote class="citation"> <p> I've looked into the QueryPerformanceXXXXX functions and it seems they may not be as accurate as I would like. While the <a class="missing wiki">GetTickCount</a> version requires a mutex it may be better to suffer a possible small performance hit in order to maintain accuracy. </p> <p> If anyone has any up to date knowledge of any issues with the QueryPerformanceXXXXX functions I would appreciate it. </p> </blockquote> <p> In the past they have been a problem, especially on multi-core processors but MSDN assures us that <a class="missing wiki">QueryPerformanceFrequency</a> will not change once the system has started. </p> <p> <a class="ext-link" href="http://msdn.microsoft.com/en-us/library/ms644905%28VS.85%29.aspx"><span class="icon">​</span>http://msdn.microsoft.com/en-us/library/ms644905%28VS.85%29.aspx</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 18 Aug 2010 01:36:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:9</guid> <description> <p> I'm confused as to why this is "wontfix". As it stands, any change in the system time completely screws up any system relying on the deadline timer. If not for the files and ideas presented here I would have been lost. </p> <p> You cannot use the system time for timers. </p> </description> <category>Ticket</category> </item> <item> <author>kjohnson@…</author> <pubDate>Thu, 25 Nov 2010 21:16:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:10</guid> <description> <p> I may be wrong, but I think the attached file "monotone_timer.hpp-NO_MUTEX" suffers from really bad roll over issues. Multiplying a rolling monotonic timer by a constant (1000000000/frequency.<a class="missing wiki">QuadPart</a> on line 80) doesn't produce a valid monotonic nanosecond count. </p> <p> I've attached the version I'm trying which keeps times and durations in terms of the performance counter (monotone_timer_better_rollover.cpp/.hpp). </p> <p> You use it as: <a class="missing wiki">TimerImpl</a> m_Timer; m_Timer.expires_from_now(TimerTraits::milliseconds_to_duration(milliseconds_delay)); </p> <p> I agree that this is a really big issue. I was hoping when we started using boost that we would be spending out time writing our application, not spending hours trying to get a basic timer working reliably. </p> <p> I also think the documentation should be changed. The example provided (e.g. <a href="http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/timers/tick_count_timer.cpp">http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/timers/tick_count_timer.cpp</a>) is *WRONG* and doesn't work as expected. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 25 Nov 2010 21:17:15 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">monotone_timer_better_rollover.cpp</span> </li> </ul> Ticket anonymous Thu, 25 Nov 2010 21:17:27 GMT attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">monotone_timer_better_rollover.hpp</span> </li> </ul> Ticket Niklas Angare <li51ckf02@…> Fri, 27 May 2011 16:56:48 GMT <link>https://svn.boost.org/trac10/ticket/3504#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:11</guid> <description> <p> I'd like to resubmit this feature request now that boost::chrono::steady_clock is available on the release branch. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Fri, 01 Jul 2011 12:15:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:12</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:10" title="Comment 10">kjohnson@…</a>: </p> <blockquote class="citation"> <p> I may be wrong, but I think the attached file "monotone_timer.hpp-NO_MUTEX" suffers from really bad roll over issues. Multiplying a rolling monotonic timer by a constant (1000000000/frequency.<a class="missing wiki">QuadPart</a> on line 80) doesn't produce a valid monotonic nanosecond count. </p> <p> I've attached the version I'm trying which keeps times and durations in terms of the performance counter (monotone_timer_better_rollover.cpp/.hpp). </p> <p> You use it as: <a class="missing wiki">TimerImpl</a> m_Timer; m_Timer.expires_from_now(TimerTraits::milliseconds_to_duration(milliseconds_delay)); </p> </blockquote> <p> Your attached code uses a header named CheckedInt64.h, could you add this as well please? </p> </description> <category>Ticket</category> </item> <item> <author>Leonid Evdokimov <leon@…></author> <pubDate>Wed, 13 Jul 2011 11:38:57 GMT</pubDate> <title>cc changed https://svn.boost.org/trac10/ticket/3504#comment:13 https://svn.boost.org/trac10/ticket/3504#comment:13 <ul> <li><strong>cc</strong> <span class="trac-author">leon@…</span> added </li> </ul> Ticket kjohnson@… Thu, 14 Jul 2011 01:36:42 GMT <link>https://svn.boost.org/trac10/ticket/3504#comment:14 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:14</guid> <description> <p> It is just a class that performs 64-bit arithmetic with overflow checking. This is internal code that I would require permission to release - honestly I can't be bothered doing this. You can just replace it with normal 64-bit arithmetic if you want. </p> <p> e.g. </p> <p> boost::posix_time::time_duration TimerTraits::to_posix_duration( </p> <blockquote> <p> const TimerTraits::duration_type&amp; d) </p> </blockquote> <p> { </p> <blockquote> <p> return boost::posix_time::milliseconds(d.ticks_ * 1000 / performance_freq_); </p> </blockquote> <p> } </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:12" title="Comment 12">anonymous</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:10" title="Comment 10">kjohnson@…</a>: </p> <blockquote class="citation"> <p> I may be wrong, but I think the attached file "monotone_timer.hpp-NO_MUTEX" suffers from really bad roll over issues. Multiplying a rolling monotonic timer by a constant (1000000000/frequency.<a class="missing wiki">QuadPart</a> on line 80) doesn't produce a valid monotonic nanosecond count. </p> <p> I've attached the version I'm trying which keeps times and durations in terms of the performance counter (monotone_timer_better_rollover.cpp/.hpp). </p> <p> You use it as: <a class="missing wiki">TimerImpl</a> m_Timer; m_Timer.expires_from_now(TimerTraits::milliseconds_to_duration(milliseconds_delay)); </p> </blockquote> <p> Your attached code uses a header named CheckedInt64.h, could you add this as well please? </p> </blockquote> </description> <category>Ticket</category> </item> <item> <author>Aaron_Wright@…</author> <pubDate>Wed, 02 Nov 2011 22:12:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:15 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:15</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:10" title="Comment 10">kjohnson@…</a>: </p> <blockquote class="citation"> <p> I may be wrong, but I think the attached file "monotone_timer.hpp-NO_MUTEX" suffers from really bad roll over issues. Multiplying a rolling monotonic timer by a constant (1000000000/frequency.<a class="missing wiki">QuadPart</a> on line 80) doesn't produce a valid monotonic nanosecond count. </p> </blockquote> <p> I'm investigating an issue I've had where timers have stopped firing. I used an implementation just like "monotone_timer.hpp-NO_MUTEX", and I was wanting to narrow down the cause of my problem. </p> <p> Would it be possible to get a little more detail about why that equation doesn't "produce a valid monotonic nanosecond count"? I would really appreciate it. </p> </description> <category>Ticket</category> </item> <item> <author>kjohnson@…</author> <pubDate>Tue, 08 Nov 2011 03:50:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:16 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:16</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:15" title="Comment 15">Aaron_Wright@…</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3504#comment:10" title="Comment 10">kjohnson@…</a>: </p> <blockquote class="citation"> <p> I may be wrong, but I think the attached file "monotone_timer.hpp-NO_MUTEX" suffers from really bad roll over issues. Multiplying a rolling monotonic timer by a constant (1000000000/frequency.<a class="missing wiki">QuadPart</a> on line 80) doesn't produce a valid monotonic nanosecond count. </p> </blockquote> <p> I'm investigating an issue I've had where timers have stopped firing. I used an implementation just like "monotone_timer.hpp-NO_MUTEX", and I was wanting to narrow down the cause of my problem. </p> <p> Would it be possible to get a little more detail about why that equation doesn't "produce a valid monotonic nanosecond count"? I would really appreciate it. </p> </blockquote> <p> I was wrong - it doesn't. </p> <p> It is always true that: </p> <p> ((count+n)*ns_over_freq) - (count*ns_over_freq) = (n*ns_over_freq) </p> <p> in the ring of unsigned 64-bit numbers - i.e. monotonic steps in the count always produce monotonic steps in the output - it just wraps around more often. </p> <p> I was obviously a bit confused and frustrated that day. </p> <p> I did warn you :) </p> <p> There were a couple of fixes in 1.45 that you may be interested in. </p> <p> <a class="ext-link" href="https://svn.boost.org/trac/boost/ticket/4568"><span class="icon">​</span>https://svn.boost.org/trac/boost/ticket/4568</a> </p> <p> <a class="ext-link" href="https://svn.boost.org/trac/boost/ticket/4745"><span class="icon">​</span>https://svn.boost.org/trac/boost/ticket/4745</a> </p> <p> I've moved off this now and probably can't help anymore. </p> </description> <category>Ticket</category> </item> <item> <author>bwhite@…</author> <pubDate>Tue, 24 Jan 2012 18:05:37 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3504 https://svn.boost.org/trac10/ticket/3504 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">MonotonicDeadlineTimer.h</span> </li> </ul> <p> monotonic_deadline_timer using boost::chrono::steady_clock </p> Ticket bwhite@… Tue, 24 Jan 2012 18:13:53 GMT <link>https://svn.boost.org/trac10/ticket/3504#comment:17 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:17</guid> <description> <p> I've attached a header file that I recently implemented in our product that was suffering the same issue described in this thread. It provides a ready-to-use boost::asio::monotonic_deadline_timer class that is powered by the boost::chrono::steady_clock. So far in our testing adjusting the system clock forward or back no longer impacts when the timer fires. When you ask for, say, 10 seconds you always get 10 seconds. Hopefully this or something similar will appear in a future Boost version. Enjoy! </p> </description> <category>Ticket</category> </item> <item> <author>Luc Moreault <lmoreault@…></author> <pubDate>Fri, 04 May 2012 15:48:23 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3504#comment:18 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3504#comment:18</guid> <description> <p> Any new plans to fix this or have a monotonic_dealine_timer officially included in Boost? </p> <p> Also, I noticed a similar behavior using this_thread::sleep() </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Smithe687</dc:creator> <pubDate>Sat, 24 Dec 2016 06:11:34 GMT</pubDate> <title>status, severity, type, component, version, milestone changed; resolution deleted https://svn.boost.org/trac10/ticket/3504#comment:19 https://svn.boost.org/trac10/ticket/3504#comment:19 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>severity</strong> <span class="trac-field-old">Problem</span> → <span class="trac-field-new">Not Applicable</span> </li> <li><strong>type</strong> <span class="trac-field-old">Feature Requests</span> → <span class="trac-field-new">Library Submissions</span> </li> <li><strong>component</strong> <span class="trac-field-old">asio</span> → <span class="trac-field-new">xpressive</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.41.0</span> → <span class="trac-field-new">Boost.Build-M3</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">Boost 1.41.0</span> → <span class="trac-field-new">Website 1.X</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">wontfix</span> </li> </ul> <p> Hello! Do you use Twitter? I'd like to follow you if that would be okay. I'm undoubtedly enjoying your blog and look forward to new posts. dfcdefcffabedadc </p> Ticket Niklas Angare <li51ckf02@…> Tue, 27 Dec 2016 13:39:31 GMT type, version, component, severity, milestone changed https://svn.boost.org/trac10/ticket/3504#comment:20 https://svn.boost.org/trac10/ticket/3504#comment:20 <ul> <li><strong>type</strong> <span class="trac-field-old">Library Submissions</span> → <span class="trac-field-new">Feature Requests</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost.Build-M3</span> → <span class="trac-field-new">Boost 1.41.0</span> </li> <li><strong>component</strong> <span class="trac-field-old">xpressive</span> → <span class="trac-field-new">asio</span> </li> <li><strong>severity</strong> <span class="trac-field-old">Not Applicable</span> → <span class="trac-field-new">Problem</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">Website 1.X</span> → <span class="trac-field-new">To Be Determined</span> </li> </ul> <p> Undid vandalism. I would like to take this opportunity to reiterate my request that deadline_timer be based on boost::chrono::steady_clock. </p> Ticket