10 WppGuard WppTaskQueue::_taskQueueGuard;
11 WppGuard WppTaskQueue::_handleTaskGuard;
12 WppTaskQueue WppTaskQueue::_instance;
17 WppTaskQueue::~WppTaskQueue() {
29 _taskQueueGuard.lock();
33 WPP_LOGE(
TAG_WPP_TASK,
"Can't add task becouse task id is WPP_ERR_TASK_ID, looks like all task ids are busy.");
34 _taskQueueGuard.unlock();
38 TaskInfo *newTask =
new TaskInfo;
41 newTask->delaySec = delaySec;
42 newTask->nextCallTime = WppPlatform::getTime() + newTask->delaySec;
45 newTask->state = IDLE;
47 _instance._tasks.push_back(newTask);
48 _taskQueueGuard.unlock();
56 _taskQueueGuard.lock();
60 WPP_LOGE(
TAG_WPP_TASK,
"Can't add task becouse task id is WPP_ERR_TASK_ID, looks like all task ids are busy.");
61 _taskQueueGuard.unlock();
65 TaskInfo *newTask =
new TaskInfo;
68 newTask->delaySec = delaySec;
69 newTask->nextCallTime = WppPlatform::getTime() + newTask->delaySec;
70 newTask->ctx =
new uint8_t[size];
71 memcpy(newTask->ctx, ctx, size);
72 newTask->ctxSize = size;
73 newTask->state = IDLE;
75 _instance._tasks.push_back(newTask);
76 _taskQueueGuard.unlock();
81 size_t WppTaskQueue::getTaskCnt() {
82 return _instance._tasks.size();
86 _taskQueueGuard.lock();
88 auto task = std::find_if(_instance._tasks.begin(), _instance._tasks.end(), [
id](TaskInfo *task) { return task->id == id; });
89 bool isExist = task != _instance._tasks.end();
91 _taskQueueGuard.unlock();
96 _taskQueueGuard.lock();
98 auto task = std::find_if(_instance._tasks.begin(), _instance._tasks.end(), [
id](TaskInfo *task) { return task->id == id; });
99 if (task == _instance._tasks.end()) {
100 _taskQueueGuard.unlock();
103 bool isIdle = (*task)->state & IDLE;
105 _taskQueueGuard.unlock();
110 _taskQueueGuard.lock();
112 auto task = std::find_if(_instance._tasks.begin(), _instance._tasks.end(), [
id](TaskInfo *task) { return task->id == id; });
113 if (task == _instance._tasks.end()) {
114 _taskQueueGuard.unlock();
117 bool isExecuting = (*task)->state & EXECUTING;
119 _taskQueueGuard.unlock();
123 bool WppTaskQueue::isTaskShouldBeDeleted(
task_id_t id) {
124 _taskQueueGuard.lock();
126 auto task = std::find_if(_instance._tasks.begin(), _instance._tasks.end(), [
id](TaskInfo *task) { return task->id == id; });
127 if (task == _instance._tasks.end()) {
128 _taskQueueGuard.unlock();
131 bool isShouldBeDeleted = (*task)->state & SHOULD_BE_DELETED;
133 _taskQueueGuard.unlock();
134 return isShouldBeDeleted;
138 _taskQueueGuard.lock();
140 auto task = std::find_if(_instance._tasks.begin(), _instance._tasks.end(), [
id](TaskInfo *task) { return task->id == id; });
141 if (task == _instance._tasks.end()) {
142 _taskQueueGuard.unlock();
145 (*task)->state = (TaskState)((*task)->state | SHOULD_BE_DELETED);
147 _taskQueueGuard.unlock();
150 void WppTaskQueue::requestToRemoveEachTask() {
151 _taskQueueGuard.lock();
152 for (
auto task : _instance._tasks) task->state = (TaskState)(task->state | SHOULD_BE_DELETED);
153 _taskQueueGuard.unlock();
156 void WppTaskQueue::hardReset() {
157 _handleTaskGuard.lock();
158 _taskQueueGuard.lock();
160 for (
auto task : _instance._tasks) {
161 if (task->ctxSize > 0) {
162 delete[] (uint8_t *)(task->ctx);
167 _instance._tasks.clear();
169 _handleTaskGuard.unlock();
170 _taskQueueGuard.unlock();
173 time_t WppTaskQueue::handleEachTask(
WppClient& client) {
174 _handleTaskGuard.lock();
176 _taskQueueGuard.lock();
179 std::list<TaskInfo *> tasksCopy = _instance._tasks;
180 _taskQueueGuard.unlock();
182 for (
auto task : tasksCopy) {
184 _taskQueueGuard.lock();
185 if (task->state & SHOULD_BE_DELETED || task->nextCallTime > WppPlatform::getTime()) {
186 _instance._taskQueueGuard.unlock();
189 task->state = EXECUTING;
190 _taskQueueGuard.unlock();
195 bool isFinished = task->task(client, task->ctx);
198 _taskQueueGuard.lock();
199 if (isFinished || task->state & SHOULD_BE_DELETED) {
200 task->state = SHOULD_BE_DELETED;
203 task->nextCallTime = WppPlatform::getTime() + task->delaySec;
205 _taskQueueGuard.unlock();
208 _instance.deleteFinishedTasks();
209 time_t nextCallInterval = _instance.updateNextCallTimeForTasks();
210 _handleTaskGuard.unlock();
211 return nextCallInterval;
214 void WppTaskQueue::deleteFinishedTasks() {
215 _taskQueueGuard.lock();
216 for (
auto task = _tasks.begin(); task != _tasks.end();) {
217 if (((*task)->state & SHOULD_BE_DELETED) == 0) {
221 if ((*task)->ctxSize > 0) {
222 delete[] (uint8_t *)((*task)->ctx);
223 (*task)->ctxSize = 0;
226 task = _tasks.erase(task);
228 _taskQueueGuard.unlock();
232 time_t WppTaskQueue::updateNextCallTimeForTasks() {
233 _taskQueueGuard.lock();
235 for (
auto task: _tasks) {
236 time_t taskCallInterval = std::max(task->nextCallTime - WppPlatform::getTime(), (time_t)0);
237 if (taskCallInterval < nextCallInterval) nextCallInterval = taskCallInterval;
239 _taskQueueGuard.unlock();
240 return nextCallInterval;
243 WppTaskQueue::task_id_t WppTaskQueue::getNextTaskId() {
244 task_id_t baseId = _nextTaskId;
249 newId = _nextTaskId++;
251 auto task = std::find_if(_instance._tasks.begin(), _instance._tasks.end(), [newId](TaskInfo *task) { return task->id == newId; });
252 isExist = task != _instance._tasks.end();
253 }
while (isExist && baseId != _nextTaskId);
#define WPP_LOGE(TAG, FMT,...)
#define WPP_TASK_MAX_DELAY_S
#define WPP_TASK_MIN_DELAY_S
Represents a client interface for Wpp library.
std::function< bool(WppClient &, void *)> task_t
The WppConnection class represents a connection interface for the Wpp library.