Author: dreiss
Date: Thu Jun 4 00:32:57 2009
New Revision: 781630
URL: http://svn.apache.org/viewvc?rev=781630&view=rev
Log:
THRIFT-469. cpp: Fix a bug in TimerManager::add
The old code didn't notify waiters when the inserted task's timeout
was less than the current timeout because it didn't check the task map
to find the lowest timeout until after the new task was inserted.
Modified:
incubator/thrift/trunk/lib/cpp/src/concurrency/TimerManager.cpp
incubator/thrift/trunk/lib/cpp/src/concurrency/test/TimerManagerTests.h
Modified: incubator/thrift/trunk/lib/cpp/src/concurrency/TimerManager.cpp
URL:
http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/cpp/src/concurrency/TimerManager.cpp?rev=781630&r1=781629&r2=781630&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/cpp/src/concurrency/TimerManager.cpp (original)
+++ incubator/thrift/trunk/lib/cpp/src/concurrency/TimerManager.cpp Thu Jun 4
00:32:57 2009
@@ -239,13 +239,18 @@
throw IllegalStateException();
}
+ // If the task map is empty, we will kick the dispatcher for sure.
Otherwise, we kick him
+ // if the expiration time is shorter than the current value. Need to test
before we insert,
+ // because the new task might insert at the front.
+ bool notifyRequired = (taskCount_ == 0) ? true : timeout <
taskMap_.begin()->first;
+
taskCount_++;
taskMap_.insert(std::pair<int64_t, shared_ptr<Task> >(timeout,
shared_ptr<Task>(new Task(task))));
// If the task map was empty, or if we have an expiration that is earlier
// than any previously seen, kick the dispatcher so it can update its
// timeout
- if (taskCount_ == 1 || timeout < taskMap_.begin()->first) {
+ if (notifyRequired) {
monitor_.notify();
}
}
Modified:
incubator/thrift/trunk/lib/cpp/src/concurrency/test/TimerManagerTests.h
URL:
http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/cpp/src/concurrency/test/TimerManagerTests.h?rev=781630&r1=781629&r2=781630&view=diff
==============================================================================
--- incubator/thrift/trunk/lib/cpp/src/concurrency/test/TimerManagerTests.h
(original)
+++ incubator/thrift/trunk/lib/cpp/src/concurrency/test/TimerManagerTests.h Thu
Jun 4 00:32:57 2009
@@ -106,13 +106,26 @@
assert(timerManager.state() == TimerManager::STARTED);
- shared_ptr<TimerManagerTests::Task> task =
shared_ptr<TimerManagerTests::Task>(new TimerManagerTests::Task(_monitor,
timeout));
+ // Don't create task yet, because its constructor sets the expected
completion time, and we
+ // need to delay between inserting the two tasks into the run queue.
+ shared_ptr<TimerManagerTests::Task> task;
{
Synchronized s(_monitor);
timerManager.add(orphanTask, 10 * timeout);
+ try {
+ // Wait for 1 second in order to give timerManager a chance to start
sleeping in response
+ // to adding orphanTask. We need to do this so we can verify that
adding the second task
+ // kicks the dispatcher out of the current wait and starts the new 1
second wait.
+ _monitor.wait (1000);
+ assert (0 == "ERROR: This wait should time out. TimerManager
dispatcher may have a problem.");
+ } catch (TimedOutException &ex) {
+ }
+
+ task.reset (new TimerManagerTests::Task(_monitor, timeout));
+
timerManager.add(task, timeout);
_monitor.wait();