source: SMSSender/lib/datatypes/src/stask.h @ 240:936dde048c4e

Last change on this file since 240:936dde048c4e was 240:936dde048c4e, checked in by Sämy Zehnder <saemy.zehnder@…>, 7 years ago
  • Using Qt::DirectConnection? for all slots on STask to ensure liveness of the STask* parameter.
File size: 6.7 KB
Line 
1/*
2 smssender - A frontend for fast and easy SMS sending over different gateways.
3 Copyright (C) 2007-2012, gorrión. See http://smssender.gorrion.ch
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef STASK_H_
20#define STASK_H_
21
22#include <QMutex>
23#include <QObject>
24#include <QPointer>
25#include <QString>
26#include <QThread>
27#include <QWaitCondition>
28
29#include "datatypes_global.h"
30
31#include "exceptions/eexception.h"
32
33typedef struct {
34    uint    uid;
35    QString nmespace;
36} SUIdNamespaceIdent;
37inline bool operator==(const SUIdNamespaceIdent& a, const SUIdNamespaceIdent& b) { return (a.uid == b.uid) && (a.nmespace == b.nmespace); }
38inline bool operator<(const SUIdNamespaceIdent& a, const SUIdNamespaceIdent& b) { return (a.nmespace + QString::number(a.uid)) < (b.nmespace + QString::number(b.uid)); }
39
40class DATATYPES_SHARED_EXPORT STask : public QObject {
41    Q_OBJECT
42
43    friend class STaskManager; // sigDoStart()
44
45public:
46    enum Property {
47        pTitle,
48        pDetails,
49        pProgress,
50        pStatus
51    };
52
53    enum Status {
54        sWaiting  = 0x00,
55        sRunning  = 0x01,
56        sFinished = 0x02,
57
58        LastStatus = sFinished
59    };
60
61    enum Result {
62        rSuccess,
63        rError,
64        rCancelled
65    };
66
67public:
68    STask(uint UID, const QString& nmespace);
69    ~STask();
70
71    uint    uid() const;
72    QString nmespace() const;
73
74    virtual QString title() const;
75    virtual QString details() const;
76    virtual uint    progress() const;
77    virtual uint    status() const;
78    virtual QString statusStr() const;
79    virtual STask::Result taskResult() const;
80    virtual uint    specialResult() const;
81
82    STask*   parent() const;
83    bool     hasParent() const;
84    bool     isSubtaskOf(STask* parent) const;
85
86    void     lockRessource(int ressourceId, QString nmespace = "", QMutex::RecursionMode mode = QMutex::Recursive);
87    void     unlockRessource(int ressourceId, QString nmespace = "");
88
89    void     addBlockingTask(uint uid, QString nmespace = "");
90    void     addBlockingTask(const SUIdNamespaceIdent& taskIdent);
91    void     setBlockingTasks(const QList<SUIdNamespaceIdent>& tasks);
92    void     addBlockingTask(STask* task);
93    void     setSelfBlocking(bool selfBlocking);
94    void     removeBlockingTask(uint uid, QString nmespace = "");
95    void     removeBlockingTask(const SUIdNamespaceIdent& taskIdent);
96    void     removeBlockingTask(STask* task);
97
98    QList<SUIdNamespaceIdent> blockingTaskIdents() const;
99    QList<QPointer<STask> >   blockingTaskInstances() const;
100
101    void    enqueueAfter(STask* other, bool onlyIfSuccessful = false);
102
103    void    setTitle(const QString& title);
104    void    setDetails(const QString& details);
105    void    setProgress(uint progress);
106    void    setTaskResult(STask::Result taskResult);
107    void    setSpecialResult(uint result);
108
109    void    setParentTask(STask* parent);
110
111    bool    isStarted() const;
112    bool    isRunning() const;
113    bool    isCancelled() const;
114    bool    isFinished() const;
115
116    bool              hadException() const;
117    const EException& exception() const;
118
119public slots:
120    void start();
121    void cancel();
122
123signals:
124    void changed(STask* task, STask::Property property); // Always use Qt::DirectConnection when connecting!
125
126    void started(STask* task); // Always use Qt::DirectConnection when connecting!
127    void cancelled(STask* task); // Always use Qt::DirectConnection when connecting!
128    void exceptionOccured(STask* task); // Always use Qt::DirectConnection when connecting!
129    void finished(STask* task); // Always use Qt::DirectConnection when connecting!
130
131protected:
132    QMutex&      dataMutex() const;
133
134    void         setStatus(uint status);
135    virtual void setException(const EException& e);
136    virtual void setException(const QSharedPointer<EException>& e);
137
138    void         startSubTask(STask* task, bool waitFor);
139
140    void         waitFor(STask* other);
141    void         waitFor(QList<STask*> others);
142    void         waitFor(QList<QPointer<STask> > others);
143
144    void         setStarted();
145
146    virtual void doStart();
147    virtual void doTheWork() =0;
148    void         safeDoTheWork();
149
150    void         haltIfCancelRequested();
151
152    QString      taskIdent();
153    QDebug       sDebug();
154
155    virtual EException* inheritSubtaskException(const EException& exception);
156
157protected slots:
158    void         setFinished();
159
160private slots:
161    void         onSigStart();
162    void         onSubTaskFinished(STask* subTask);
163    void         onSubTaskExceptionOccured(STask* subTask);
164
165signals: // private
166    void _sigDoStart();
167
168private slots:
169    void waitForTaskFinished(STask* task);
170    void startIfSuccessful(STask* task);
171
172private:
173    mutable QMutex  dataMutex_;
174
175    uint    uid_;
176    QString nmespace_;
177
178    QList<SUIdNamespaceIdent> blockingTaskIdents_;
179    QList<QPointer<STask> >   blockingTaskInstances_;
180    QString         title_;
181    QString         details_;
182    uint            progress_;
183    uint            status_;
184    STask::Result   taskResult_;
185    uint            specialResult_;
186
187    QPointer<STask> parent_;
188
189    QList<QPointer<STask> > waitingFor_;
190    mutable QMutex waitForMutex_;
191    QWaitCondition waitForWaitCondition_;
192
193    QList<QPointer<STask> > subTasks_;
194
195    bool started_;
196    bool cancelled_;
197    bool finished_;
198    bool autoHaltOnCancelRequested_;
199
200    QSharedPointer<EException> exception_;
201};
202
203
204class DATATYPES_SHARED_EXPORT SThreadedTask : public STask {
205    Q_OBJECT
206
207public:
208    SThreadedTask(uint UID, const QString& nmespace);
209    ~SThreadedTask();
210
211protected:
212    void doStart();
213
214private slots:
215    void threadStarted();
216
217private:
218    QThread* thread_;
219};
220
221
222class DATATYPES_SHARED_EXPORT SAsynchroneousTask : public STask {
223    Q_OBJECT
224
225public:
226    SAsynchroneousTask(uint UID, const QString& nmespace);
227
228protected:
229    void doStart();
230
231    void doTheWork();
232    virtual void startTheWork() =0;
233};
234
235/**
236 * Exception which gets thrown when calling SThread::haltIfCancelRequested().
237 */
238class DATATYPES_SHARED_EXPORT EAbortException : public EException {
239public:
240    EAbortException();
241
242public: /* EException */
243    virtual void raise();
244    EAbortException* createClonedInstance() const throw();
245};
246
247
248#endif /* STASK_H_ */
Note: See TracBrowser for help on using the repository browser.