| /** |
| * 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; |
| } |