diff --git a/framework/android/connector/driver/js/src/main/cpp/src/convert_utils.cc b/framework/android/connector/driver/js/src/main/cpp/src/convert_utils.cc index 46615e04cf6..4a164ec0a31 100644 --- a/framework/android/connector/driver/js/src/main/cpp/src/convert_utils.cc +++ b/framework/android/connector/driver/js/src/main/cpp/src/convert_utils.cc @@ -205,6 +205,7 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, j_env->DeleteLocalRef(method_name_str); j_env->DeleteLocalRef(call_id_str); auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); return std::make_tuple(true, "", true); @@ -219,7 +220,9 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, if (!std::get<0>(to_array_tuple)) { return std::make_tuple(false, std::get<1>(to_array_tuple), false); } - auto ref = std::make_shared(j_env, std::get<2>(to_array_tuple)); + auto j_obj = std::get<2>(to_array_tuple); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); return std::make_tuple(true, "", true); @@ -234,7 +237,9 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, if (!std::get<0>(to_map_tuple)) { return std::make_tuple(false, std::get<1>(to_map_tuple), false); } - auto ref = std::make_shared(j_env, std::get<2>(to_map_tuple)); + auto j_obj = std::get<2>(to_map_tuple); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); return std::make_tuple(true, "", true); @@ -246,8 +251,9 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, if (!ctx->GetValueBoolean(value, &b)) { return std::make_tuple(false, "value must be boolean", false); } - auto ref = std::make_shared(j_env, - j_env->NewObject(boolean_clazz, boolean_constructor, b)); + auto j_obj = j_env->NewObject(boolean_clazz, boolean_constructor, b); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); return std::make_tuple(true, "", true); @@ -263,8 +269,9 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, } else { return std::make_tuple(false, "value must be string", false); } - - auto ref = std::make_shared(j_env, j_env->NewStringUTF(str.c_str())); + auto j_obj = j_env->NewStringUTF(str.c_str()); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); return std::make_tuple(true, "", true); @@ -277,8 +284,10 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, if (!ctx->GetValueNumber(value, &num)) { return std::make_tuple(true, "value must be int", false); } - auto ref = std::make_shared(j_env, j_env->NewObject( - integer_clazz, integer_constructor, num)); + auto j_obj = j_env->NewObject( + integer_clazz, integer_constructor, num); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); } else { @@ -288,13 +297,17 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, } if (type == kDoubleObject) { - auto ref = std::make_shared(j_env, j_env->NewObject( - double_clazz, double_constructor, num)); + auto j_obj = j_env->NewObject( + double_clazz, double_constructor, num); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); } else if (type == kFloatObject) { - auto ref = std::make_shared(j_env, j_env->NewObject( - float_clazz, float_constructor, static_cast(num))); + auto j_obj = j_env->NewObject( + float_clazz, float_constructor, static_cast(num)); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); } else if (type == kLongObject) { @@ -302,8 +315,10 @@ ConvertUtils::HandleObjectType(const std::shared_ptr& ctx, if (!footstone::numeric_cast(num, jlong_value)) { return std::make_tuple(true, "value out of jlong boundary", false); } - auto ref = std::make_shared(j_env, j_env->NewObject( - long_clazz, long_constructor, jlong_value)); + auto j_obj = j_env->NewObject( + long_clazz, long_constructor, jlong_value); + auto ref = std::make_shared(j_env, j_obj); + j_env->DeleteLocalRef(j_obj); global_refs.push_back(ref); j_args.l = ref->GetObj(); } else { diff --git a/modules/footstone/include/footstone/cv_driver.h b/modules/footstone/include/footstone/cv_driver.h index e79621c421b..de6a1698290 100644 --- a/modules/footstone/include/footstone/cv_driver.h +++ b/modules/footstone/include/footstone/cv_driver.h @@ -35,13 +35,12 @@ class CVDriver: public Driver { virtual ~CVDriver() = default; virtual void Notify() override; - virtual void WaitFor(const TimeDelta& delta) override; + virtual void WaitFor(const TimeDelta& delta, std::unique_lock& lock) override; virtual void Start() override; virtual void Terminate() override; private: std::condition_variable cv_; - std::mutex mutex_; }; } diff --git a/modules/footstone/include/footstone/driver.h b/modules/footstone/include/footstone/driver.h index 81417dbe2c9..c18869e6741 100644 --- a/modules/footstone/include/footstone/driver.h +++ b/modules/footstone/include/footstone/driver.h @@ -23,7 +23,7 @@ #pragma once #include - +#include #include "footstone/time_delta.h" namespace footstone { @@ -35,7 +35,8 @@ class Driver { virtual ~Driver() = default; virtual void Notify() = 0; - virtual void WaitFor(const TimeDelta& delta) = 0; + std::mutex& Mutex() { return mutex_; } + virtual void WaitFor(const TimeDelta& delta, std::unique_lock& lock) = 0; virtual void Start() = 0; virtual void Terminate() = 0; @@ -60,6 +61,8 @@ class Driver { * */ bool is_exit_immediately_; + + std::mutex mutex_; }; } diff --git a/modules/footstone/include/footstone/platform/adr/looper_driver.h b/modules/footstone/include/footstone/platform/adr/looper_driver.h index 213dd9c3042..e6f4e5053dc 100644 --- a/modules/footstone/include/footstone/platform/adr/looper_driver.h +++ b/modules/footstone/include/footstone/platform/adr/looper_driver.h @@ -36,7 +36,7 @@ class LooperDriver: public Driver { virtual ~LooperDriver(); virtual void Notify() override; - virtual void WaitFor(const TimeDelta& delta) override; + virtual void WaitFor(const TimeDelta& delta, std::unique_lock& lock) override; virtual void Start() override; virtual void Terminate() override; diff --git a/modules/footstone/include/footstone/platform/ios/looper_driver.h b/modules/footstone/include/footstone/platform/ios/looper_driver.h index 1ec849a044f..1e07e2c90e8 100644 --- a/modules/footstone/include/footstone/platform/ios/looper_driver.h +++ b/modules/footstone/include/footstone/platform/ios/looper_driver.h @@ -35,10 +35,10 @@ class LooperDriver: public Driver { virtual ~LooperDriver(); virtual void Notify() override; - virtual void WaitFor(const TimeDelta& delta) override; + virtual void WaitFor(const TimeDelta& delta, std::unique_lock& lock) override; virtual void Start() override; virtual void Terminate() override; - + void OnTimerFire(CFRunLoopTimerRef timer); private: diff --git a/modules/footstone/include/footstone/task_runner.h b/modules/footstone/include/footstone/task_runner.h index 356d87b36d2..b83a124ecff 100644 --- a/modules/footstone/include/footstone/task_runner.h +++ b/modules/footstone/include/footstone/task_runner.h @@ -122,6 +122,8 @@ class TaskRunner { std::unique_ptr PopIdleTask(); std::unique_ptr GetTopDelayTask(); std::unique_ptr GetNext(); + bool HasTask(); + bool HasMoreUrgentTask(TimeDelta min_wait_time, TimePoint now); std::queue> task_queue_; std::mutex queue_mutex_; diff --git a/modules/footstone/include/footstone/worker.h b/modules/footstone/include/footstone/worker.h index 31134f8b3b9..a4df43c9da0 100644 --- a/modules/footstone/include/footstone/worker.h +++ b/modules/footstone/include/footstone/worker.h @@ -102,6 +102,9 @@ class Worker { void BalanceNoLock(); void SortNoLock(); + bool HasTask(); + bool HasMoreUrgentTask(TimeDelta min_wait_time, TimePoint now); + int32_t WorkerKeyCreate(uint32_t task_runner_id, const std::function& destruct); bool WorkerKeyDelete(uint32_t task_runner_id, int32_t key); bool WorkerSetSpecific(uint32_t task_runner_id, int32_t key, void *p); diff --git a/modules/footstone/src/cv_driver.cc b/modules/footstone/src/cv_driver.cc index 7356c419aa7..ff180f7100e 100644 --- a/modules/footstone/src/cv_driver.cc +++ b/modules/footstone/src/cv_driver.cc @@ -24,12 +24,11 @@ namespace footstone { inline namespace runner { void CVDriver::Notify() { + std::unique_lock lock(mutex_); cv_.notify_one(); } -void CVDriver::WaitFor(const TimeDelta& delta) { - std::unique_lock lock(mutex_); - +void CVDriver::WaitFor(const TimeDelta& delta, std::unique_lock& lock) { if (delta != TimeDelta::Max() && delta >= TimeDelta::Zero()) { cv_.wait_for(lock, std::chrono::nanoseconds(delta.ToNanoseconds())); } else { diff --git a/modules/footstone/src/platform/adr/looper_driver.cc b/modules/footstone/src/platform/adr/looper_driver.cc index 22ea02c9daa..96a3b371122 100644 --- a/modules/footstone/src/platform/adr/looper_driver.cc +++ b/modules/footstone/src/platform/adr/looper_driver.cc @@ -57,7 +57,7 @@ void LooperDriver::Notify() { timerfd_settime(fd_, TFD_TIMER_ABSTIME, &spec, nullptr); } -void LooperDriver::WaitFor(const TimeDelta& delta) { +void LooperDriver::WaitFor(const TimeDelta& delta, std::unique_lock& lock) { auto nano_secs = delta.ToNanoseconds(); if (nano_secs < 1) { nano_secs = 1; diff --git a/modules/footstone/src/platform/ios/looper_driver.cc b/modules/footstone/src/platform/ios/looper_driver.cc index b817da01eac..eac5e0d0bcb 100644 --- a/modules/footstone/src/platform/ios/looper_driver.cc +++ b/modules/footstone/src/platform/ios/looper_driver.cc @@ -56,7 +56,7 @@ void LooperDriver::Notify() { CFAbsoluteTimeGetCurrent()); } -void LooperDriver::WaitFor(const TimeDelta& delta) { +void LooperDriver::WaitFor(const TimeDelta& delta, std::unique_lock& lock) { CFRunLoopTimerSetNextFireDate( delayed_wake_timer_, CFAbsoluteTimeGetCurrent() + delta.ToSecondsF()); diff --git a/modules/footstone/src/task_runner.cc b/modules/footstone/src/task_runner.cc index b8a60590a26..108ca7a6340 100644 --- a/modules/footstone/src/task_runner.cc +++ b/modules/footstone/src/task_runner.cc @@ -266,5 +266,53 @@ void TaskRunner::RunnerDestroySpecifics() { return worker->WorkerDestroySpecific(task_runner_id); } +bool TaskRunner::HasTask() { + { + std::lock_guard lock(queue_mutex_); + if (!task_queue_.empty()) { + return true; + } + } + { + std::lock_guard lock(delay_mutex_); + if (!delayed_task_queue_.empty()) { + return true; + } + } + { + std::lock_guard lock(idle_mutex_); + if (!idle_task_queue_.empty()) { + return true; + } + } + return false; +} + +bool TaskRunner::HasMoreUrgentTask(TimeDelta min_wait_time, TimePoint now) { + { + std::lock_guard lock(queue_mutex_); + if (!task_queue_.empty()) { + return true; + } + } + { + std::lock_guard lock(idle_mutex_); + if (!idle_task_queue_.empty()) { + return true; + } + } + { + std::lock_guard lock(delay_mutex_); + if (!delayed_task_queue_.empty()) { + const DelayedEntry& delayed_task = delayed_task_queue_.top(); + if(delayed_task.first - now < min_wait_time) { + return true; + } + } + } + + return false; +} + } // namespace runner } // namespace footstone diff --git a/modules/footstone/src/worker.cc b/modules/footstone/src/worker.cc index b6b8e5fd9e3..d82b036db61 100644 --- a/modules/footstone/src/worker.cc +++ b/modules/footstone/src/worker.cc @@ -402,10 +402,20 @@ std::unique_ptr Worker::GetNextTask() { })); return wrapper_idle_task; } + std::unique_lock lock(driver_->Mutex()); if (driver_->IsTerminated()) { return nullptr; } - driver_->WaitFor(min_wait_time_); + if (min_wait_time_ == TimeDelta::Max()) { + if (HasTask()) { + return nullptr; + } + } else { + if (HasMoreUrgentTask(min_wait_time_, now)) { + return nullptr; + } + } + driver_->WaitFor(min_wait_time_, lock); return nullptr; } @@ -532,5 +542,63 @@ void Worker::UpdateSpecific(uint32_t task_runner_id, specific_map_[task_runner_id] = array; // insert or update } +bool Worker::HasTask() { + bool has_found = false; + for (auto &group : running_group_list_) { + for (auto &runner : group) { + if (runner->HasTask()) { + has_found = true; + break; + } + } + if (has_found) { + break; + } + } + if (!has_found) { + for (auto &group : pending_group_list_) { + for (auto &runner : group) { + if (runner->HasTask()) { + has_found = true; + break; + } + } + if (has_found) { + break; + } + } + } + return has_found; +} + +bool Worker::HasMoreUrgentTask(TimeDelta min_wait_time, TimePoint now) { + bool has_found = false; + for (auto &group : running_group_list_) { + for (auto &runner : group) { + if (runner->HasMoreUrgentTask(min_wait_time, now)) { + has_found = true; + break; + } + } + if (has_found) { + break; + } + } + if (!has_found) { + for (auto &group : pending_group_list_) { + for (auto &runner : group) { + if (runner->HasMoreUrgentTask(min_wait_time, now)) { + has_found = true; + break; + } + } + if (has_found) { + break; + } + } + } + return has_found; +} + } // namespace runner } // namespace footstone