blob: 72ba5aa090ac4e2b51357f420c672e724ba832ee [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 2019/1/8.
//
#include "base/android/log_utils.h"
#include "android/jsengine/object/weex_env.h"
#include "back_to_weex_core_queue.h"
#include "third_party/IPC/Buffering/IPCBuffer.h"
static void *startThread(void *td) {
auto *self = static_cast<BackToWeexCoreQueue *>(td);
WeexEnv::getEnv()->initIPC();
self->isInitOk = true;
self->start();
return NULL;
}
int BackToWeexCoreQueue::addTask(BackToWeexCoreQueue::IPCTask *task) {
threadLocker.lock();
taskQueue_.push_back(task);
int size = taskQueue_.size();
threadLocker.unlock();
threadLocker.signal();
return size;
}
void BackToWeexCoreQueue::init() {
pthread_t thread;
pthread_create(&thread, nullptr, startThread, this);
pthread_setname_np(thread, "BackToWeexCoreQueue");
}
void BackToWeexCoreQueue::start() {
while (!m_stop) {
BackToWeexCoreQueue::IPCTask *task = getTask();
if (task == nullptr) {
continue;
}
task->run();
delete task;
}
}
BackToWeexCoreQueue::IPCTask *BackToWeexCoreQueue::getTask() {
BackToWeexCoreQueue::IPCTask *task = nullptr;
while (task == nullptr) {
threadLocker.lock();
while (taskQueue_.empty() || !isInitOk) {
threadLocker.wait();
}
if (taskQueue_.empty()) {
threadLocker.unlock();
continue;
}
assert(!taskQueue_.empty());
task = taskQueue_.front();
taskQueue_.pop_front();
threadLocker.unlock();
}
return task;
}
void BackToWeexCoreQueue::stop() {
m_stop = true;
}
void BackToWeexCoreQueue::IPCTask::run() {
if (params.empty())
return;
std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());;
serializer->setMsg(static_cast<uint32_t>(this->m_type));
std::vector<BackToWeexCoreQueue::IPCArgs *>::iterator it;
it = params.begin();
while (it != params.end()) {
IPCArgs *&reference = *it;
serializer->add(reference->m_str, reference->m_length);
delete reference;
it++;
}
std::unique_ptr<IPCBuffer> buffer = serializer->finish();
std::unique_ptr<IPCResult> result = WeexEnv::getEnv()->m_ipc_client_->getSender()->send(
buffer.get());
if (m_future != nullptr) {
m_future->setResult(result);
}
}
void BackToWeexCoreQueue::IPCTask::addParams(const char *str, size_t len) {
IPCArgs *x = new BackToWeexCoreQueue::IPCArgs(str, len);
this->params.push_back(x);
}
void BackToWeexCoreQueue::IPCTask::set_future(BackToWeexCoreQueue::Future *m_feature) {
IPCTask::m_future = m_feature;
}
BackToWeexCoreQueue::IPCTask::~IPCTask() {
}
void BackToWeexCoreQueue::Future::setResult(std::unique_ptr<IPCResult> &result) {
thread_locker_.lock();
has_result_ = true;
result_ = std::move(result);
thread_locker_.unlock();
thread_locker_.signal();
}
std::unique_ptr<IPCResult> BackToWeexCoreQueue::Future::waitResult() {
thread_locker_.lock();
while (!has_result_) {
thread_locker_.wait();
}
thread_locker_.unlock();
return std::move(result_);
}
BackToWeexCoreQueue::IPCArgs::IPCArgs(const char *str, size_t len) {
char *ret = nullptr;
size_t strLen = 0;
if (str != nullptr) {
strLen = len == 0 ? strlen(str) : len;
ret = new char[strLen + 1];
memcpy(ret, str, static_cast<size_t>(strLen));
ret[strLen] = '\0';
}
this->m_str = ret;
this->m_length = strLen;
}