blob: cd4b42844f58e3a11009811d4e5e8037462ab0c7 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
//
// Created by Darin on 23/05/2018.
//
#include "weex_task_queue.h"
#include <unistd.h>
#include "android/jsengine/task/impl/native_timer_task.h"
#include "android/jsengine/bridge/script/script_bridge_in_multi_process.h"
#include "android/jsengine/bridge/script/core_side_in_multi_process.h"
#include "android/jsengine/object/weex_env.h"
#include "android/jsengine/weex_jsc_utils.h"
void WeexTaskQueue::run(WeexTask *task) {
if(task == nullptr || WeexEnv::getEnv()->is_app_crashed()) {
return;
}
task->timeCalculator->set_task_name(task->taskName());
task->timeCalculator->taskStart();
task->run(weexRuntime);
task->timeCalculator->taskEnd();
delete task;
}
WeexTaskQueue::~WeexTaskQueue() {
delete this->weexRuntime;
weexRuntime = nullptr;
}
int WeexTaskQueue::addTask(WeexTask *task) {
return _addTask(task, false);
}
WeexTask *WeexTaskQueue::getTask() {
WeexTask *task = nullptr;
while (task == nullptr) {
threadLocker.lock();
while (taskQueue_.empty() || !isInitOk) {
threadLocker.wait();
}
if (taskQueue_.empty()) {
threadLocker.unlock();
continue;
}
if(WeexEnv::getEnv()->is_app_crashed()) {
threadLocker.unlock();
return nullptr;
}
assert(!taskQueue_.empty());
task = taskQueue_.front();
taskQueue_.pop_front();
threadLocker.unlock();
}
return task;
}
int WeexTaskQueue::addTimerTask(String id, uint32_t function, int taskId, WeexGlobalObject* global_object, bool one_shot) {
WeexTask *task = new NativeTimerTask(id, function,taskId, one_shot);
task->set_global_object(global_object);
return _addTask(
task,
false);
}
void WeexTaskQueue::removeTimer(int taskId) {
threadLocker.lock();
if (taskQueue_.empty()) {
threadLocker.unlock();
return;
} else {
for (std::deque<WeexTask *>::iterator it = taskQueue_.begin(); it < taskQueue_.end(); ++it) {
auto reference = *it;
if (reference->taskId == taskId) {
NativeTimerTask* timer_task = static_cast<NativeTimerTask*>(reference);
taskQueue_.erase(it);
delete (timer_task);
}
}
}
threadLocker.unlock();
threadLocker.signal();
}
void WeexTaskQueue::start() {
while (true) {
auto pTask = getTask();
if (pTask == nullptr)
continue;
run(pTask);
}
}
static void *startThread(void *td) {
auto *self = static_cast<WeexTaskQueue *>(td);
self->isInitOk = true;
if (self->weexRuntime == nullptr) {
self->weexRuntime = new WeexRuntime(new TimerQueue(self),WeexEnv::getEnv()->scriptBridge(), self->isMultiProgress);
// init IpcClient in Js Thread
// if (self->isMultiProgress) {
// auto *client = new WeexIPCClient(WeexEnv::getEnv()->getIpcClientFd());
// static_cast<weex::bridge::js::CoreSideInMultiProcess *>(weex::bridge::js::ScriptBridgeInMultiProcess::Instance()->core_side())->set_ipc_client(
// client);
// }
}
auto pTask = self->getTask();
self->run(pTask);
self->start();
return NULL;
}
void WeexTaskQueue::init() {
pthread_t thread;
LOGE("start weex queue init");
pthread_create(&thread, nullptr, startThread, this);
pthread_setname_np(thread, "WeexTaskQueueThread");
}
int WeexTaskQueue::_addTask(WeexTask *task, bool front) {
threadLocker.lock();
if (front) {
taskQueue_.push_front(task);
} else {
taskQueue_.push_back(task);
}
int size = taskQueue_.size();
threadLocker.unlock();
threadLocker.signal();
return size;
}
WeexTaskQueue::WeexTaskQueue(bool isMultiProgress) : weexRuntime(nullptr) {
this->isMultiProgress = isMultiProgress;
this->weexRuntime = nullptr;
}
void WeexTaskQueue::removeAllTask(String id) {
threadLocker.lock();
if (taskQueue_.empty()) {
threadLocker.unlock();
return;
} else {
for (std::deque<WeexTask *>::iterator it = taskQueue_.begin(); it < taskQueue_.end(); ++it) {
auto reference = *it;
if (reference->instanceId == id) {
taskQueue_.erase(it);
delete (reference);
reference = nullptr;
}
}
}
threadLocker.unlock();
threadLocker.signal();
}