16
16
***************************************************************************/
17
17
18
18
#include " qgstaskmanager.h"
19
- #include < QMutex >
19
+ #include < QtConcurrentRun >
20
20
21
21
22
22
//
26
26
QgsTask::QgsTask ( const QString &name )
27
27
: QObject()
28
28
, mDescription( name )
29
- , mStatus( Running )
29
+ , mStatus( Queued )
30
30
, mProgress( 0.0 )
31
+ , mShouldTerminate( false )
31
32
{}
32
33
34
+ void QgsTask::start ()
35
+ {
36
+ mStatus = Running;
37
+ emit statusChanged ( Running );
38
+ emit begun ();
39
+ run ();
40
+ }
41
+
42
+ void QgsTask::terminate ()
43
+ {
44
+ mShouldTerminate = true ;
45
+ }
46
+
33
47
void QgsTask::setProgress ( double progress )
34
48
{
35
49
mProgress = progress;
@@ -74,28 +88,33 @@ QgsTaskManager::QgsTaskManager( QObject* parent )
74
88
75
89
QgsTaskManager::~QgsTaskManager ()
76
90
{
77
- QMap< long , QgsTask* >::const_iterator it = mTasks .constBegin ();
91
+ // first tell all tasks to cancel
92
+ terminateAll ();
93
+
94
+ // then clean them up, including waiting for them to terminate
95
+ QMap< long , TaskInfo >::const_iterator it = mTasks .constBegin ();
78
96
for ( ; it != mTasks .constEnd (); ++it )
79
97
{
80
- cleanupAndDeleteTask ( it.value () );
98
+ cleanupAndDeleteTask ( it.value (). task );
81
99
}
82
100
}
83
101
84
102
long QgsTaskManager::addTask ( QgsTask* task )
85
103
{
86
- static QMutex sAddMutex ( QMutex::Recursive );
87
- QMutexLocker locker ( &sAddMutex );
88
-
89
104
mTasks .insert ( mNextTaskId , task );
105
+
90
106
connect ( task, SIGNAL ( progressChanged ( double ) ), this , SLOT ( taskProgressChanged ( double ) ) );
91
107
connect ( task, SIGNAL ( statusChanged ( int ) ), this , SLOT ( taskStatusChanged ( int ) ) );
108
+
109
+ mTasks [ mNextTaskId ].future = QtConcurrent::run ( task, &QgsTask::start );
110
+
92
111
emit taskAdded ( mNextTaskId );
93
112
return mNextTaskId ++;
94
113
}
95
114
96
115
bool QgsTaskManager::deleteTask ( long id )
97
116
{
98
- QgsTask* task = mTasks .value ( id );
117
+ QgsTask* task = mTasks .value ( id ). task ;
99
118
return deleteTask ( task );
100
119
}
101
120
@@ -107,9 +126,9 @@ bool QgsTaskManager::deleteTask( QgsTask *task )
107
126
bool result = cleanupAndDeleteTask ( task );
108
127
109
128
// remove from internal task list
110
- for ( QMap< long , QgsTask* >::iterator it = mTasks .begin (); it != mTasks .end (); )
129
+ for ( QMap< long , TaskInfo >::iterator it = mTasks .begin (); it != mTasks .end (); )
111
130
{
112
- if ( it.value () == task )
131
+ if ( it.value (). task == task )
113
132
it = mTasks .erase ( it );
114
133
else
115
134
++it;
@@ -120,28 +139,46 @@ bool QgsTaskManager::deleteTask( QgsTask *task )
120
139
121
140
QgsTask*QgsTaskManager::task ( long id ) const
122
141
{
123
- return mTasks .value ( id );
142
+ return mTasks .value ( id ). task ;
124
143
}
125
144
126
145
QList<QgsTask*> QgsTaskManager::tasks () const
127
146
{
128
- return mTasks .values ();
147
+ QList< QgsTask* > list;
148
+ for ( QMap< long , TaskInfo >::const_iterator it = mTasks .constBegin (); it != mTasks .constEnd (); ++it )
149
+ {
150
+ list << it.value ().task ;
151
+ }
152
+ return list;
129
153
}
130
154
131
155
long QgsTaskManager::taskId ( QgsTask *task ) const
132
156
{
133
157
if ( !task )
134
158
return -1 ;
135
159
136
- QMap< long , QgsTask* >::const_iterator it = mTasks .constBegin ();
160
+ QMap< long , TaskInfo >::const_iterator it = mTasks .constBegin ();
137
161
for ( ; it != mTasks .constEnd (); ++it )
138
162
{
139
- if ( it.value () == task )
163
+ if ( it.value (). task == task )
140
164
return it.key ();
141
165
}
142
166
return -1 ;
143
167
}
144
168
169
+ void QgsTaskManager::terminateAll ()
170
+ {
171
+ QMap< long , TaskInfo >::iterator it = mTasks .begin ();
172
+ for ( ; it != mTasks .end (); ++it )
173
+ {
174
+ QgsTask* task = it.value ().task ;
175
+ if ( task->isActive () )
176
+ {
177
+ task->terminate ();
178
+ }
179
+ }
180
+ }
181
+
145
182
void QgsTaskManager::taskProgressChanged ( double progress )
146
183
{
147
184
QgsTask* task = qobject_cast< QgsTask* >( sender () );
@@ -174,6 +211,17 @@ bool QgsTaskManager::cleanupAndDeleteTask( QgsTask *task )
174
211
if ( task->isActive () )
175
212
task->terminate ();
176
213
214
+ // wait for task to terminate
215
+ QMap< long , TaskInfo >::iterator it = mTasks .begin ();
216
+ for ( ; it != mTasks .end (); ++it )
217
+ {
218
+ if ( it.value ().task == task )
219
+ {
220
+ it.value ().future .waitForFinished ();
221
+ break ;
222
+ }
223
+ }
224
+
177
225
emit taskAboutToBeDeleted ( taskId ( task ) );
178
226
179
227
task->deleteLater ();
0 commit comments