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  SPDLOG_TRACE("append object: {}", static_cast<void *>(this));
82  auto *obj_dstr = this->get_heap_ptr(sizeof(T));
83  new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj));
84 
85  if (std::is_class_v<T>) {
86  auto destructor = [](const void *x) {
87  static_cast<const T *>(x)->~T();
88  };
89  obj_dstr->destroy = destructor;
90  } else {
91  obj_dstr->destroy = nullptr;
92  }
93 
94  data_objects_.push(obj_dstr);
95  }
96 
103  template <typename T>
104  void AppendObject(T *obj) {
105  SPDLOG_TRACE("called: {}", static_cast<void *>(this));
106  auto *obj_dstr = this->get_heap_ptr(sizeof(T));
107  auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj));
108  if (std::is_class_v<T>) {
109  SPDLOG_TRACE("is class");
110  auto destructor = [](const void *x) {
111  static_cast<const T *>(x)->~T();
112  };
113  obj_dstr->destroy = destructor;
114  } else {
115  obj_dstr->destroy = nullptr;
116  }
117  data_objects_.push(std::move(obj_dstr));
118  }
119 
126  template <typename T>
127  T PopObject() {
128  SPDLOG_TRACE("pop object: {}", static_cast<void *>(this));
129  if (data_objects_.empty()) throw std::runtime_error("No object to pop");
130  auto *obj_dstr = data_objects_.top();
131  auto *heap_ptr = (T *)obj_dstr->p_obj;
132  auto obj = std::move(*(T *)(heap_ptr));
133  this->free_heap_ptr(obj_dstr);
134  data_objects_.pop();
135  return obj;
136  }
137 
142  ~DataObject();
143 
144  private:
145  std::stack<Destructor *> data_objects_;
146 
153  Destructor *get_heap_ptr(size_t bytes_size);
154 
160  void free_heap_ptr(Destructor *);
161  };
162 
167  Task();
168 
174  explicit Task(TaskCallback callback, DataObjectPtr data_object = nullptr);
175 
181  explicit Task(
182  TaskRunnable runnable,
183  TaskCallback callback = [](int, const std::shared_ptr<DataObject> &) {},
184  DataObjectPtr data = nullptr);
185 
190  virtual ~Task() override;
191 
196  virtual void Run();
197 
203  std::string GetUUID() const;
204 
205  signals:
210  void SignalTaskFinished();
211 
216  void SignalTaskPostFinishedDone();
217 
218  protected:
224  void SetFinishAfterRun(bool finish_after_run);
225 
231  void SetRTN(int rtn);
232 
233  private:
234  const std::string uuid_;
235  TaskCallback callback_;
236  TaskRunnable runnable_;
237  bool finish_after_run_ = true;
238  int rtn_ = 0;
239  QThread *callback_thread_ = nullptr;
240  DataObjectPtr data_object_ = nullptr;
241 
246  void before_finish_task();
247 
252  void init();
253 
258  virtual void run() override;
259 
265  static std::string generate_uuid();
266 };
267 } // namespace GpgFrontend::Thread
268 
269 #endif // GPGFRONTEND_TASK_H
Definition: TaskRunner.h:40
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:104
T PopObject()
Definition: Task.h:127
Definition: Task.h:45
Definition: CtxCheckTask.h:33