BIND 10 trac957, updated. 879663a28bd59692b3745f9e1851412a73872460 [trac957] Added new ChangeLog entry

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Jun 10 03:39:06 UTC 2011


The branch, trac957 has been updated
  discards  33e3357a5e6887b461b5a6cc5593f911e84df98a (commit)

This update discarded existing revisions and left the branch pointing at
a previous point in the repository history.

 * -- * -- N (879663a28bd59692b3745f9e1851412a73872460)
            \
             O -- O -- O (33e3357a5e6887b461b5a6cc5593f911e84df98a)

The removed revisions are not necessarilly gone - if another reference
still refers to them they will stay in the repository.

No new revisions were added by this update.

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