Skip to content

Commit 1ccd033

Browse files
authored
fix: RunOnMainThreadCallback & PostFrameCallback (#1721)
* fix: RunOnMainThreadCallback & PostFrameCallback * fix: remove allocation * fix: RunOnMainThreadCallback callback * chore: bump alpha * fix: PostFrameCallback * chore: bump
1 parent 0c601ae commit 1ccd033

File tree

5 files changed

+110
-55
lines changed

5 files changed

+110
-55
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@nativescript/android",
33
"description": "NativeScript Runtime for Android",
4-
"version": "8.2.4",
4+
"version": "8.3.1",
55
"repository": {
66
"type": "git",
77
"url": "https://github.com/NativeScript/android-runtime.git"

test-app/runtime/src/main/cpp/CallbackHandlers.cpp

+44-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "CallbackHandlers.h"
2-
#include "NativeScriptAssert.h"
32
#include "MetadataNode.h"
43
#include "Util.h"
54
#include "V8GlobalHelpers.h"
@@ -8,7 +7,6 @@
87
#include "JsArgToArrayConverter.h"
98
#include "ArgConverter.h"
109
#include "v8-profiler.h"
11-
#include "NativeScriptException.h"
1210
#include <iostream>
1311
#include <sstream>
1412
#include <fstream>
@@ -20,7 +18,6 @@
2018
#include <unistd.h>
2119
#include <dlfcn.h>
2220

23-
2421
using namespace v8;
2522
using namespace std;
2623
using namespace tns;
@@ -670,55 +667,59 @@ void CallbackHandlers::RunOnMainThreadCallback(const FunctionCallbackInfo<v8::Va
670667
Isolate::Scope isolate_scope(isolate);
671668
HandleScope handle_scope(isolate);
672669

673-
674670
Local<Context> context = isolate->GetCurrentContext();
675671

676-
uint32_t key = ++count_;
672+
uint64_t key = ++count_;
677673
Local<v8::Function> callback = args[0].As<v8::Function>();
678-
CacheEntry entry(isolate, new Persistent<v8::Function>(isolate, callback));
679-
cache_.emplace(key, entry);
680-
auto key_str = std::to_string(key);
681-
write(Runtime::GetWriter(), key_str.c_str(), 1);
674+
CacheEntry entry(isolate, callback, context);
675+
cache_.emplace(key, std::move(entry));
676+
auto value = Callback(key);
677+
auto size = sizeof(Callback);
678+
auto wrote = write(Runtime::GetWriter(),&value , size);
682679
}
683680

684681
int CallbackHandlers::RunOnMainThreadFdCallback(int fd, int events, void *data) {
685-
std::string buf;
686-
read(fd, &buf, 1);
682+
struct Callback value;
683+
auto size = sizeof(Callback);
684+
ssize_t nr = read(fd, &value, sizeof(value));
687685

688-
auto key = std::stoi(buf);
686+
auto key = value.id_;
689687

690688
auto it = cache_.find(key);
691689
if (it == cache_.end()) {
692690
return 1;
693691
}
694692

695693
Isolate *isolate = it->second.isolate_;
696-
Persistent<v8::Function> *poCallback = it->second.callback_;
697694
v8::Locker locker(isolate);
698695
Isolate::Scope isolate_scope(isolate);
699696
HandleScope handle_scope(isolate);
700-
auto context = v8::Context::New(isolate);
697+
auto context = it->second.context_.Get(isolate);
701698
Context::Scope context_scope(context);
702-
Local<v8::Function> cb = poCallback->Get(isolate);
699+
Local<v8::Function> cb = it->second.callback_.Get(isolate);
703700
Local<Value> result;
704701

705-
if (!cb->Call(context, context->Global(), 0, nullptr).ToLocal(&result)) {
706-
assert(false);
702+
v8::TryCatch tc(isolate);
703+
704+
if (!cb->Call(context, context->Global(), 0, nullptr).ToLocal(&result)) {}
705+
706+
if(tc.HasCaught()){
707+
throw NativeScriptException(tc);
707708
}
708709

709710
RemoveKey(key);
711+
710712
return 1;
711713
}
712714

713-
void CallbackHandlers::RemoveKey(const uint32_t key) {
715+
void CallbackHandlers::RemoveKey(const uint64_t key) {
714716
auto it = cache_.find(key);
715717
if (it == cache_.end()) {
716718
return;
717719
}
718720

719-
Persistent<v8::Function> *poCallback = it->second.callback_;
720-
poCallback->Reset();
721-
delete poCallback;
721+
it->second.callback_.Reset();
722+
it->second.context_.Reset();
722723
cache_.erase(it);
723724
}
724725

@@ -1584,12 +1585,16 @@ void CallbackHandlers::TerminateWorkerThread(Isolate *isolate) {
15841585
void CallbackHandlers::RemoveIsolateEntries(v8::Isolate *isolate) {
15851586
for (auto &item: cache_) {
15861587
if (item.second.isolate_ == isolate) {
1588+
item.second.callback_.Reset();
1589+
item.second.context_.Reset();
15871590
cache_.erase(item.first);
15881591
}
15891592
}
15901593

15911594
for (auto &item: frameCallbackCache_) {
15921595
if (item.second.isolate_ == isolate) {
1596+
item.second.callback_.Reset();
1597+
item.second.context_.Reset();
15931598
frameCallbackCache_.erase(item.first);
15941599
}
15951600
}
@@ -1632,7 +1637,7 @@ void CallbackHandlers::PostFrameCallback(const FunctionCallbackInfo<v8::Value> &
16321637
v8::Locker locker(isolate);
16331638
Isolate::Scope isolate_scope(isolate);
16341639
HandleScope handle_scope(isolate);
1635-
auto context = Context::New(isolate);
1640+
auto context = isolate->GetCurrentContext();
16361641
Context::Scope context_scope(context);
16371642

16381643
auto func = args[0].As<Function>();
@@ -1651,27 +1656,33 @@ void CallbackHandlers::PostFrameCallback(const FunctionCallbackInfo<v8::Value> &
16511656
}
16521657
}
16531658

1654-
Local<v8::Function> callback = args[0].As<v8::Function>();
1659+
Local<v8::Function> callback = func;
16551660
uint64_t key = ++frameCallbackCount_;
16561661

16571662
V8SetPrivateValue(isolate, func, idKey, v8::Number::New(isolate, (double) key));
16581663

1659-
FrameCallbackCacheEntry entry (isolate, new Persistent<v8::Function>(isolate, callback));
1664+
FrameCallbackCacheEntry entry (isolate, callback, context);
16601665
entry.id = key;
1661-
frameCallbackCache_.emplace(key, entry);
16621666

16631667
auto finalCallback = [](const v8::WeakCallbackInfo<FrameCallbackCacheEntry> &data) {
16641668
auto value = data.GetParameter();
16651669
for (auto &item: frameCallbackCache_) {
16661670
if (item.second.id == value->id) {
1667-
cache_.erase(item.first);
1671+
item.second.context_.Reset();
1672+
item.second.callback_.Reset();
1673+
frameCallbackCache_.erase(item.first);
16681674
break;
16691675
}
16701676
}
16711677
};
1672-
entry.callback_->SetWeak(&entry, finalCallback, v8::WeakCallbackType::kFinalizer);
16731678

1674-
PostCallback(args, &entry, context);
1679+
entry.callback_.SetWeak(&entry, finalCallback, v8::WeakCallbackType::kFinalizer);
1680+
1681+
frameCallbackCache_.emplace(key, std::move(entry));
1682+
1683+
auto val = frameCallbackCache_.find(key);
1684+
1685+
PostCallback(args, &val->second, context);
16751686
}
16761687
}
16771688

@@ -1685,7 +1696,7 @@ void CallbackHandlers::RemoveFrameCallback(const FunctionCallbackInfo<v8::Value>
16851696
v8::Locker locker(isolate);
16861697
Isolate::Scope isolate_scope(isolate);
16871698
HandleScope handle_scope(isolate);
1688-
auto context = Context::New(isolate);
1699+
auto context = isolate->GetCurrentContext();
16891700
Context::Scope context_scope(context);
16901701

16911702
auto func = args[0].As<Function>();
@@ -1745,12 +1756,12 @@ void CallbackHandlers::InitChoreographer() {
17451756
}
17461757

17471758

1748-
robin_hood::unordered_map<uint32_t, CallbackHandlers::CacheEntry> CallbackHandlers::cache_;
1759+
robin_hood::unordered_map<uint64_t, CallbackHandlers::CacheEntry> CallbackHandlers::cache_;
17491760

17501761
robin_hood::unordered_map<uint64_t, CallbackHandlers::FrameCallbackCacheEntry> CallbackHandlers::frameCallbackCache_;
17511762

1752-
_Atomic uint32_t CallbackHandlers::count_ = 0;
1753-
_Atomic uint64_t CallbackHandlers::frameCallbackCount_ = 0;
1763+
std::atomic_int64_t CallbackHandlers::count_ = {0};
1764+
std::atomic_uint64_t CallbackHandlers::frameCallbackCount_ = {0};
17541765

17551766

17561767
int CallbackHandlers::nextWorkerId = 0;
@@ -1770,4 +1781,4 @@ jmethodID CallbackHandlers::INIT_WORKER_METHOD_ID = nullptr;
17701781

17711782
NumericCasts CallbackHandlers::castFunctions;
17721783
ArrayElementAccessor CallbackHandlers::arrayElementAccessor;
1773-
FieldAccessor CallbackHandlers::fieldAccessor;
1784+
FieldAccessor CallbackHandlers::fieldAccessor;

test-app/runtime/src/main/cpp/CallbackHandlers.h

+37-17
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#include "ObjectManager.h"
1616
#include "include/v8.h"
1717
#include "robin_hood.h"
18+
#include <errno.h>
19+
#include "NativeScriptAssert.h"
20+
#include "NativeScriptException.h"
1821

1922
namespace tns {
2023
class CallbackHandlers {
@@ -281,34 +284,48 @@ namespace tns {
281284
jobject _runtime;
282285
};
283286

284-
static void RemoveKey(const uint32_t key);
287+
static void RemoveKey(const uint64_t key);
288+
289+
static std::atomic_int64_t count_;
290+
291+
292+
struct Callback {
293+
Callback(){}
294+
Callback(uint64_t id)
295+
: id_(id){
296+
}
297+
uint64_t id_;
298+
};
285299

286-
static _Atomic uint32_t count_;
287300

288301
struct CacheEntry {
289-
CacheEntry(v8::Isolate* isolate, v8::Persistent<v8::Function>* callback)
302+
CacheEntry(v8::Isolate* isolate, v8::Local<v8::Function> callback, v8::Local<v8::Context> context)
290303
: isolate_(isolate),
291-
callback_(callback) {
304+
callback_(isolate, callback),
305+
context_(isolate, context){
292306
}
293307

294308
v8::Isolate* isolate_;
295-
v8::Persistent<v8::Function>* callback_;
296-
309+
v8::Global<v8::Function> callback_;
310+
v8::Global<v8::Context> context_;
297311
};
298312

299-
static robin_hood::unordered_map<uint32_t, CacheEntry> cache_;
313+
static robin_hood::unordered_map<uint64_t, CacheEntry> cache_;
300314

301315

302-
static _Atomic uint64_t frameCallbackCount_;
316+
static std::atomic_uint64_t frameCallbackCount_;
303317

304318
struct FrameCallbackCacheEntry {
305-
FrameCallbackCacheEntry(v8::Isolate *isolate, v8::Persistent<v8::Function> *callback)
319+
FrameCallbackCacheEntry(v8::Isolate *isolate, v8::Local<v8::Function> callback, v8::Local<v8::Context> context)
306320
: isolate_(isolate),
307-
callback_(callback) {
321+
callback_(isolate,callback),
322+
context_(isolate, context)
323+
{
308324
}
309325

310326
v8::Isolate *isolate_;
311-
v8::Persistent<v8::Function> *callback_;
327+
v8::Global<v8::Function> callback_;
328+
v8::Global<v8::Context> context_;
312329
bool removed;
313330
uint64_t id;
314331

@@ -328,22 +345,25 @@ namespace tns {
328345
}
329346
v8::Isolate *isolate = entry->isolate_;
330347

331-
v8::Persistent<v8::Function> *poCallback = entry->callback_;
332-
333348
v8::Locker locker(isolate);
334349
v8::Isolate::Scope isolate_scope(isolate);
335350
v8::HandleScope handle_scope(isolate);
336-
auto context = v8::Context::New(isolate);
351+
auto context = entry->context_.Get(isolate);
337352
v8::Context::Scope context_scope(context);
338353

339-
340-
v8::Local<v8::Function> cb = poCallback->Get(isolate);
354+
v8::Local<v8::Function> cb = entry->callback_.Get(isolate);
341355
v8::Local<v8::Value> result;
342356

343357
v8::Local<v8::Value> args[1] = {v8::Number::New(isolate, ts)};
344358

359+
v8::TryCatch tc(isolate);
360+
345361
if (!cb->Call(context, context->Global(), 1, args).ToLocal(&result)) {
346-
assert(false);
362+
// TODO
363+
}
364+
365+
if(tc.HasCaught()){
366+
throw NativeScriptException(tc);
347367
}
348368

349369
}

test-app/runtime/src/main/cpp/Runtime.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <snapshot_blob.h>
3232
#include "IsolateDisposer.h"
3333
#include <unistd.h>
34+
#include <thread>
35+
#include "File.h"
3436

3537
#ifdef APPLICATION_IN_DEBUG
3638
#include "JsV8InspectorClient.h"
@@ -650,11 +652,25 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native
650652
*/
651653
if (!s_mainThreadInitialized) {
652654
m_isMainThread = true;
653-
pipe(m_mainLooper_fd);
655+
pipe2(m_mainLooper_fd, O_NONBLOCK | O_CLOEXEC);
654656
m_mainLooper = ALooper_forThread();
655-
ALooper_acquire(m_mainLooper);
656657

657-
ALooper_addFd(m_mainLooper, m_mainLooper_fd[0], 0, ALOOPER_EVENT_INPUT, CallbackHandlers::RunOnMainThreadFdCallback, nullptr);
658+
ALooper_acquire(m_mainLooper);
659+
660+
// try using 2MB
661+
int ret = fcntl(m_mainLooper_fd[1], F_SETPIPE_SZ, 2 * (1024 * 1024));
662+
663+
// try using 1MB
664+
if (ret != 0) {
665+
ret = fcntl(m_mainLooper_fd[1], F_SETPIPE_SZ, 1 * (1024 * 1024));
666+
}
667+
668+
// try using 512KB
669+
if (ret != 0) {
670+
ret = fcntl(m_mainLooper_fd[1], F_SETPIPE_SZ, (512 * 1024));
671+
}
672+
673+
ALooper_addFd(m_mainLooper, m_mainLooper_fd[0], ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT, CallbackHandlers::RunOnMainThreadFdCallback, nullptr);
658674

659675
Local<FunctionTemplate> workerFuncTemplate = FunctionTemplate::New(isolate, CallbackHandlers::NewThreadCallback);
660676
Local<ObjectTemplate> prototype = workerFuncTemplate->PrototypeTemplate();
@@ -851,6 +867,10 @@ int Runtime::GetWriter(){
851867
return m_mainLooper_fd[1];
852868
}
853869

870+
int Runtime::GetReader(){
871+
return m_mainLooper_fd[0];
872+
}
873+
854874
JavaVM* Runtime::s_jvm = nullptr;
855875
jmethodID Runtime::GET_USED_MEMORY_METHOD_ID = nullptr;
856876
map<int, Runtime*> Runtime::s_id2RuntimeCache;
@@ -860,4 +880,3 @@ v8::Platform* Runtime::platform = nullptr;
860880
int Runtime::m_androidVersion = Runtime::GetAndroidVersion();
861881
ALooper* Runtime::m_mainLooper = nullptr;
862882
int Runtime::m_mainLooper_fd[2];
863-

test-app/runtime/src/main/cpp/Runtime.h

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "File.h"
1414
#include <mutex>
1515
#include <android/looper.h>
16+
#include <fcntl.h>
1617

1718
namespace tns {
1819
class Runtime {
@@ -71,6 +72,10 @@ class Runtime {
7172
std::string ReadFileText(const std::string& filePath);
7273

7374
static int GetWriter();
75+
static int GetReader();
76+
static ALooper* GetMainLooper() {
77+
return m_mainLooper;
78+
}
7479

7580
private:
7681
Runtime(JNIEnv* env, jobject runtime, int id);

0 commit comments

Comments
 (0)