BIND 10 trac957, updated. 029040fd0b37cbee843c19fa08a3bc7c8144dc57 Revert "[trac957] revert the fix"

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Jun 10 01:47:12 UTC 2011


The branch, trac957 has been updated
       via  029040fd0b37cbee843c19fa08a3bc7c8144dc57 (commit)
      from  33e3357a5e6887b461b5a6cc5593f911e84df98a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 029040fd0b37cbee843c19fa08a3bc7c8144dc57
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date:   Fri Jun 10 10:43:35 2011 +0900

    Revert "[trac957] revert the fix"
    
    This reverts commit 33e3357a5e6887b461b5a6cc5593f911e84df98a.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                          |    6 +++++
 src/lib/asiolink/interval_timer.cc |   41 +++++++++++++++++++++---------------
 src/lib/asiolink/interval_timer.h  |   10 +++-----
 3 files changed, 34 insertions(+), 23 deletions(-)

-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index e44caa2..905d887 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+TBD.	[bug]           y-aharen
+	Fixed a bug an instance of IntervalTimerImpl may be destructed 
+	while deadline_timer is holding the handler. This fix addresses
+	occasional failure of IntervalTimerTest.destructIntervalTimer.
+	(Trac #957, git TBD)
+
 243.	[func]*		feng
 	Add optional hmac algorithm SHA224/384/812.
 	(Trac#782,git 77d792c9d7c1a3f95d3e6a8b721ac79002cd7db1).
diff --git a/src/lib/asiolink/interval_timer.cc b/src/lib/asiolink/interval_timer.cc
index 0ed06eb..2830a3b 100644
--- a/src/lib/asiolink/interval_timer.cc
+++ b/src/lib/asiolink/interval_timer.cc
@@ -19,6 +19,8 @@
 #include <netinet/in.h>
 
 #include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <exceptions/exceptions.h>
 
@@ -29,7 +31,11 @@
 namespace isc {
 namespace asiolink {
 
-class IntervalTimerImpl {
+/// This class uses shared_from_this in its methods. It must live inside
+/// a shared_ptr.
+class IntervalTimerImpl :
+    public boost::enable_shared_from_this<IntervalTimerImpl>
+{
 private:
     // prohibit copy
     IntervalTimerImpl(const IntervalTimerImpl& source);
@@ -81,42 +87,43 @@ IntervalTimerImpl::setup(const IntervalTimer::Callback& cbfunc,
     // At this point the timer is not running yet and will not expire.
     // After calling IOService::run(), the timer will expire.
     update();
-    return;
 }
 
 void
 IntervalTimerImpl::update() {
-    if (interval_ == 0) {
-        // timer has been canceled.  Do nothing.
-        return;
-    }
     try {
         // Update expire time to (current time + interval_).
         timer_.expires_from_now(boost::posix_time::millisec(interval_));
+        // Reset timer.
+        timer_.async_wait(boost::bind(&IntervalTimerImpl::callback,
+                                      shared_from_this(),
+                                      asio::placeholders::error));
     } catch (const asio::system_error& e) {
         isc_throw(isc::Unexpected, "Failed to update timer");
+    } catch (const boost::bad_weak_ptr& e) {
+        isc_throw(isc::Unexpected, "Failed to update timer");
     }
-    // Reset timer.
-    timer_.async_wait(boost::bind(&IntervalTimerImpl::callback, this, _1));
 }
 
 void
-IntervalTimerImpl::callback(const asio::error_code& cancelled) {
-    // Do not call cbfunc_ in case the timer was cancelled.
-    // The timer will be canelled in the destructor of asio::deadline_timer.
-    if (!cancelled) {
-        cbfunc_();
+IntervalTimerImpl::callback(const asio::error_code& ec) {
+    if (interval_ == 0 || ec) {
+        // timer has been canceled. Do nothing.
+    } else {
         // Set next expire time.
         update();
+        // Invoke the call back function.
+        cbfunc_();
     }
 }
 
-IntervalTimer::IntervalTimer(IOService& io_service) {
-    impl_ = new IntervalTimerImpl(io_service);
-}
+IntervalTimer::IntervalTimer(IOService& io_service) :
+    impl_(new IntervalTimerImpl(io_service))
+{}
 
 IntervalTimer::~IntervalTimer() {
-    delete impl_;
+    // Cancel the timer to make sure cbfunc_() will not be called any more.
+    cancel();
 }
 
 void
diff --git a/src/lib/asiolink/interval_timer.h b/src/lib/asiolink/interval_timer.h
index 8de16cb..57ec1c3 100644
--- a/src/lib/asiolink/interval_timer.h
+++ b/src/lib/asiolink/interval_timer.h
@@ -16,6 +16,7 @@
 #define __ASIOLINK_INTERVAL_TIMER_H 1
 
 #include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <asiolink/io_service.h>
 
@@ -42,9 +43,6 @@ class IntervalTimerImpl;
 /// The call back function will not be called if the instance of this class is
 /// destroyed before the timer is expired.
 ///
-/// Note: Destruction of an instance of this class while call back is pending
-/// causes throwing an exception from \c IOService.
-///
 /// Sample code:
 /// \code
 ///  void function_to_call_back() {
@@ -100,12 +98,12 @@ public:
     /// \param interval Interval in milliseconds (greater than 0)
     ///
     /// Note: IntervalTimer will not pass \c asio::error_code to
-    /// call back function. In case the timer is cancelled, the function
+    /// call back function. In case the timer is canceled, the function
     /// will not be called.
     ///
     /// \throw isc::InvalidParameter cbfunc is empty
     /// \throw isc::BadValue interval is less than or equal to 0
-    /// \throw isc::Unexpected ASIO library error
+    /// \throw isc::Unexpected internal runtime error
     void setup(const Callback& cbfunc, const long interval);
 
     /// Cancel the timer.
@@ -127,7 +125,7 @@ public:
     long getInterval() const;
 
 private:
-    IntervalTimerImpl* impl_;
+    boost::shared_ptr<IntervalTimerImpl> impl_;
 };
 
 } // namespace asiolink




More information about the bind10-changes mailing list