8
8
#include < boost/bind.hpp>
9
9
#include < utility>
10
10
11
- CScheduler::CScheduler () : nThreadsServicingQueue(0 )
11
+ CScheduler::CScheduler () : nThreadsServicingQueue(0 ), stopRequested( false ), stopWhenEmpty( false )
12
12
{
13
13
}
14
14
@@ -29,32 +29,37 @@ void CScheduler::serviceQueue()
29
29
{
30
30
boost::unique_lock<boost::mutex> lock (newTaskMutex);
31
31
++nThreadsServicingQueue;
32
+ stopRequested = false ;
33
+ stopWhenEmpty = false ;
32
34
33
35
// newTaskMutex is locked throughout this loop EXCEPT
34
36
// when the thread is waiting or when the user's function
35
37
// is called.
36
- while (1 ) {
38
+ while (! shouldStop () ) {
37
39
try {
38
- while (taskQueue.empty ()) {
40
+ while (! shouldStop () && taskQueue.empty ()) {
39
41
// Wait until there is something to do.
40
42
newTaskScheduled.wait (lock);
41
43
}
42
- // Wait until either there is a new task, or until
43
- // the time of the first item on the queue:
44
+
45
+ // Wait until either there is a new task, or until
46
+ // the time of the first item on the queue:
44
47
45
48
// wait_until needs boost 1.50 or later; older versions have timed_wait:
46
49
#if BOOST_VERSION < 105000
47
- while (!taskQueue.empty () && newTaskScheduled.timed_wait (lock, toPosixTime (taskQueue.begin ()->first ))) {
50
+ while (!shouldStop () && !taskQueue.empty () &&
51
+ newTaskScheduled.timed_wait (lock, toPosixTime (taskQueue.begin ()->first ))) {
48
52
// Keep waiting until timeout
49
53
}
50
54
#else
51
- while (!taskQueue.empty () && newTaskScheduled.wait_until (lock, taskQueue.begin ()->first ) != boost::cv_status::timeout) {
55
+ while (!shouldStop () && !taskQueue.empty () &&
56
+ newTaskScheduled.wait_until (lock, taskQueue.begin ()->first ) != boost::cv_status::timeout) {
52
57
// Keep waiting until timeout
53
58
}
54
59
#endif
55
60
// If there are multiple threads, the queue can empty while we're waiting (another
56
61
// thread may service the task we were waiting on).
57
- if (taskQueue.empty ())
62
+ if (shouldStop () || taskQueue.empty ())
58
63
continue ;
59
64
60
65
Function f = taskQueue.begin ()->second ;
@@ -70,6 +75,19 @@ void CScheduler::serviceQueue()
70
75
throw ;
71
76
}
72
77
}
78
+ --nThreadsServicingQueue;
79
+ }
80
+
81
+ void CScheduler::stop (bool drain)
82
+ {
83
+ {
84
+ boost::unique_lock<boost::mutex> lock (newTaskMutex);
85
+ if (drain)
86
+ stopWhenEmpty = true ;
87
+ else
88
+ stopRequested = true ;
89
+ }
90
+ newTaskScheduled.notify_all ();
73
91
}
74
92
75
93
void CScheduler::schedule (CScheduler::Function f, boost::chrono::system_clock::time_point t)
@@ -96,3 +114,15 @@ void CScheduler::scheduleEvery(CScheduler::Function f, int64_t deltaSeconds)
96
114
{
97
115
scheduleFromNow (boost::bind (&Repeat, this , f, deltaSeconds), deltaSeconds);
98
116
}
117
+
118
+ size_t CScheduler::getQueueInfo (boost::chrono::system_clock::time_point &first,
119
+ boost::chrono::system_clock::time_point &last) const
120
+ {
121
+ boost::unique_lock<boost::mutex> lock (newTaskMutex);
122
+ size_t result = taskQueue.size ();
123
+ if (!taskQueue.empty ()) {
124
+ first = taskQueue.begin ()->first ;
125
+ last = taskQueue.rbegin ()->first ;
126
+ }
127
+ return result;
128
+ }
0 commit comments