GpgFrontend Project
A Free, Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free OpenPGP(pgp) Crypto Tool.
Task.h
1 
29 #ifndef GPGFRONTEND_TASK_H
30 #define GPGFRONTEND_TASK_H
31 
32 #include <functional>
33 #include <memory>
34 #include <stack>
35 #include <string>
36 #include <type_traits>
37 #include <utility>
38 
39 #include "core/GpgFrontendCore.h"
40 
41 namespace GpgFrontend::Thread {
42 
43 class TaskRunner;
44 
45 class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
46  Q_OBJECT
47  public:
48  class DataObject;
49  using DataObjectPtr = std::shared_ptr<DataObject>;
50  using TaskRunnable = std::function<int(DataObjectPtr)>;
51  using TaskCallback = std::function<void(int, DataObjectPtr)>;
52 
53  friend class TaskRunner;
54 
59  class GPGFRONTEND_CORE_EXPORT DataObject {
60  public:
61  struct Destructor {
62  const void *p_obj;
63  void (*destroy)(const void *);
64  };
65 
71  size_t GetObjectSize();
72 
79  template <typename T>
80  void AppendObject(T &&obj) {
81  DLOG(TRACE) << "called:" << this;
82  auto *obj_dstr = this->get_heap_ptr(sizeof(T));
83  auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(obj));
84  if (std::is_class_v<T>) {
85  auto destructor = [](const void *x) {
86  static_cast<const T *>(x)->~T();
87  };
88  obj_dstr->destroy = destructor;
89  } else {
90  obj_dstr->destroy = nullptr;
91  }
92  data_objects_.push(std::move(obj_dstr));
93  }
94 
101  template <typename T>
102  void AppendObject(T *obj) {
103  DLOG(TRACE) << "called:" << this;
104  auto *obj_dstr = this->get_heap_ptr(sizeof(T));
105  auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj));
106  if (std::is_class_v<T>) {
107  LOG(TRACE) << "is class";
108  auto destructor = [](const void *x) {
109  static_cast<const T *>(x)->~T();
110  };
111  obj_dstr->destroy = destructor;
112  } else {
113  obj_dstr->destroy = nullptr;
114  }
115  data_objects_.push(std::move(obj_dstr));
116  }
117 
124  template <typename T>
125  T PopObject() {
126  DLOG(TRACE) << "called:" << this;
127  if (data_objects_.empty()) throw std::runtime_error("No object to pop");
128  auto *obj_dstr = data_objects_.top();
129  auto *heap_ptr = (T *)obj_dstr->p_obj;
130  auto obj = std::move(*(T *)(heap_ptr));
131  this->free_heap_ptr(obj_dstr);
132  data_objects_.pop();
133  return obj;
134  }
135 
140  ~DataObject();
141 
142  private:
143  std::stack<Destructor *> data_objects_;
144 
151  Destructor *get_heap_ptr(size_t bytes_size);
152 
158  void free_heap_ptr(Destructor *);
159  };
160 
165  Task();
166 
172  Task(TaskCallback callback, DataObjectPtr data_object = nullptr);
173 
179  Task(
180  TaskRunnable runnable,
181  TaskCallback callback = [](int, std::shared_ptr<DataObject>) {},
182  DataObjectPtr data = nullptr);
183 
188  virtual ~Task() override;
189 
194  virtual void Run();
195 
201  std::string GetUUID() const;
202 
203  signals:
208  void SignalTaskFinished();
209 
214  void SignalTaskPostFinishedDone();
215 
216  protected:
222  void SetFinishAfterRun(bool finish_after_run);
223 
229  void SetRTN(int rtn);
230 
231  private:
232  const std::string uuid_;
233  TaskCallback callback_;
234  TaskRunnable runnable_;
235  bool finish_after_run_ = true;
236  int rtn_ = 0;
237  QThread *callback_thread_ = nullptr;
238  DataObjectPtr data_object_ = nullptr;
239 
244  void before_finish_task();
245 
250  void init();
251 
256  virtual void run() override;
257 
263  static std::string generate_uuid();
264 };
265 } // namespace GpgFrontend::Thread
266 
267 #endif // GPGFRONTEND_TASK_H
Definition: TaskRunner.h:39
DataObject to be passed to the callback function.
Definition: Task.h:59
void AppendObject(T &&obj)
Definition: Task.h:80
void AppendObject(T *obj)
Definition: Task.h:102
T PopObject()
Definition: Task.h:125
Definition: Task.h:45
Definition: CtxCheckTask.h:33