Skip to content

Commit

Permalink
fix: support running webf mixed dedicated options.
Browse files Browse the repository at this point in the history
  • Loading branch information
andycall committed Nov 21, 2023
1 parent bc40b12 commit 47d0ef9
Show file tree
Hide file tree
Showing 29 changed files with 255 additions and 216 deletions.
52 changes: 17 additions & 35 deletions bridge/core/api/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,6 @@ static std::atomic<int64_t> unique_page_id{0};

namespace webf {

static void* initDartIsolateContextInternal(int8_t dedicated_thread, uint64_t* dart_methods, int32_t dart_methods_len) {
void* ptr = new webf::DartIsolateContext(dedicated_thread == 1, dart_methods, dart_methods_len);
return ptr;
}

static void* allocateNewPageInternal(void* dart_isolate_context, int32_t targetContextId) {
assert(dart_isolate_context != nullptr);
return static_cast<webf::DartIsolateContext*>(dart_isolate_context)->AddNewPage(targetContextId);
}

static void disposePageInternal(void* dart_isolate_context, void* page_) {
((webf::DartIsolateContext*)dart_isolate_context)->RemovePage(static_cast<WebFPage*>(page_));
}

static int8_t evaluateScriptsInternal(void* page_,
const char* code,
uint64_t code_len,
Expand Down Expand Up @@ -106,34 +92,30 @@ int64_t newPageId() {

using namespace webf;

void* initDartIsolateContext(int8_t dedicated_thread,
int64_t dart_port,
uint64_t* dart_methods,
int32_t dart_methods_len) {
auto dispatcher = std::make_unique<webf::multi_threading::Dispatcher>(dart_port, dedicated_thread);
void* initDartIsolateContext(int64_t dart_port, uint64_t* dart_methods, int32_t dart_methods_len) {
auto dispatcher = std::make_unique<webf::multi_threading::Dispatcher>(dart_port);

#if ENABLE_LOG
WEBF_LOG(VERBOSE) << "[Dart] allocateNewPageWrapper, targetContextId= " << targetContextId << std::endl;
#endif
auto* dart_isolate_context = new webf::DartIsolateContext(dedicated_thread == 1, dart_methods, dart_methods_len);
auto* dart_isolate_context = new webf::DartIsolateContext(dart_methods, dart_methods_len);
dart_isolate_context->SetDispatcher(std::move(dispatcher));
return dart_isolate_context;
}

void* allocateNewPage(void* ptr, int32_t targetContextId) {
void* allocateNewPage(int8_t dedicated_thread, void* ptr, int32_t targetContextId) {
#if ENABLE_LOG
WEBF_LOG(VERBOSE) << "[Dart] allocateNewPageWrapper, targetContextId= " << targetContextId << std::endl;
#endif
auto* dart_isolate_context = (webf::DartIsolateContext*)ptr;
// return dart_isolate_context->dispatcher()->PostToJsSync(targetContextId, webf::allocateNewPageInternal, ptr,
// targetContextId);
assert(dart_isolate_context != nullptr);
return static_cast<webf::DartIsolateContext*>(dart_isolate_context)->AddNewPage(targetContextId);
return static_cast<webf::DartIsolateContext*>(dart_isolate_context)
->AddNewPage(dedicated_thread == 1, targetContextId);
}

void disposePage(void* ptr, void* page_) {
void disposePage(int8_t dedicated_thread, void* ptr, void* page_) {
auto* dart_isolate_context = (webf::DartIsolateContext*)ptr;
((webf::DartIsolateContext*)dart_isolate_context)->RemovePage(static_cast<WebFPage*>(page_));
((webf::DartIsolateContext*)dart_isolate_context)->RemovePage(dedicated_thread == 1, static_cast<WebFPage*>(page_));
}

int8_t evaluateScripts(void* page_,
Expand All @@ -147,9 +129,9 @@ int8_t evaluateScripts(void* page_,
WEBF_LOG(VERBOSE) << "[Dart] evaluateScriptsWrapper call" << std::endl;
#endif
auto page = reinterpret_cast<webf::WebFPage*>(page_);
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJs(page->contextId, evaluateScriptsInternal,
page_, code, code_len, parsed_bytecodes,
bytecode_len, bundleFilename, startLine);
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJs(
page->is_dedicated(), page->contextId, evaluateScriptsInternal, page_, code, code_len, parsed_bytecodes,
bytecode_len, bundleFilename, startLine);
return 1;
}

Expand All @@ -162,8 +144,8 @@ int8_t evaluateQuickjsByteCode(void* page_, uint8_t* bytes, int32_t byteLen) {
uint8_t* bytes_copy = (uint8_t*)malloc(byteLen * sizeof(uint8_t));
memcpy(bytes_copy, bytes, byteLen * sizeof(uint8_t));
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJsAndCallback(
page->contextId, evaluateQuickjsByteCodeInternal, [bytes_copy]() mutable { free(bytes_copy); }, page_, bytes_copy,
byteLen);
page->is_dedicated(), page->contextId, evaluateQuickjsByteCodeInternal,
[bytes_copy]() mutable { free(bytes_copy); }, page_, bytes_copy, byteLen);
return 1;
}

Expand All @@ -172,8 +154,8 @@ void parseHTML(void* page_, const char* code, int32_t length) {
WEBF_LOG(VERBOSE) << "[Dart] parseHTMLWrapper call" << std::endl;
#endif
auto page = reinterpret_cast<webf::WebFPage*>(page_);
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJs(page->contextId, parseHTMLInternal, page_,
code, length);
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJs(page->is_dedicated(), page->contextId,
parseHTMLInternal, page_, code, length);
}

void registerPluginByteCode(uint8_t* bytes, int32_t length, const char* pluginName) {
Expand Down Expand Up @@ -211,8 +193,8 @@ webf::NativeValue* invokeModuleEvent(void* page_,
void* event,
webf::NativeValue* extra) {
auto page = reinterpret_cast<webf::WebFPage*>(page_);
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJs(page->contextId, invokeModuleEventInternal,
page_, module, eventType, event, extra);
page->GetExecutingContext()->dartIsolateContext()->dispatcher()->PostToJs(
page->is_dedicated(), page->contextId, invokeModuleEventInternal, page_, module, eventType, event, extra);
}

void dispatchUITask(void* page_, void* context, void* callback) {
Expand Down
4 changes: 4 additions & 0 deletions bridge/core/binding_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static void HandleCallFromDartSideWrapper(NativeBindingObject* binding_object,
NativeValue* argv,
Dart_Handle dart_object) {
binding_object->binding_target_->GetDispatcher()->PostToJsSync(
binding_object->binding_target_->GetExecutingContext()->is_dedicated(),
binding_object->binding_target_->contextId(),
webf::NativeBindingObject::HandleCallFromDartSide, binding_object, return_value, method, argc, argv, dart_object);
}
Expand Down Expand Up @@ -96,6 +97,7 @@ NativeValue BindingObject::InvokeBindingMethod(const AtomicString& method,
NativeValue native_method =
NativeValueConverter<NativeTypeString>::ToNativeValue(GetExecutingContext()->ctx(), method);
GetDispatcher()->PostToDartSync(
GetExecutingContext()->is_dedicated(),
[&](int32_t contextId, const NativeBindingObject* binding_object, NativeValue* return_value, NativeValue* method,
int32_t argc, const NativeValue* argv) {
if (binding_object_->invoke_bindings_methods_from_native == nullptr) {
Expand Down Expand Up @@ -124,6 +126,7 @@ NativeValue BindingObject::InvokeBindingMethod(BindingMethodCallOperations bindi
NativeValue return_value = Native_NewNull();
NativeValue native_method = NativeValueConverter<NativeTypeInt64>::ToNativeValue(binding_method_call_operation);
GetDispatcher()->PostToDartSync(
GetExecutingContext()->is_dedicated(),
[&](int32_t contextId, const NativeBindingObject* binding_object, NativeValue* return_value, NativeValue* method,
int32_t argc, const NativeValue* argv) {
if (binding_object_->invoke_bindings_methods_from_native == nullptr) {
Expand Down Expand Up @@ -230,6 +233,7 @@ static void HandleAnonymousAsyncCalledFromDartWrapper(void* ptr,
const char* errmsg) {
auto* promise_context = static_cast<BindingObjectPromiseContext*>(ptr);
promise_context->context->dartIsolateContext()->dispatcher()->PostToJs(
promise_context->context->is_dedicated(),
contextId,
webf::BindingObject::HandleAnonymousAsyncCalledFromDart, promise_context, native_value, contextId, errmsg);
}
Expand Down
66 changes: 38 additions & 28 deletions bridge/core/dart_isolate_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,12 @@ void DartIsolateContext::FinalizeJSRuntime() {
is_name_installed_ = false;
}

DartIsolateContext::DartIsolateContext(bool dedicated_thread, const uint64_t* dart_methods, int32_t dart_methods_length)
DartIsolateContext::DartIsolateContext(const uint64_t* dart_methods, int32_t dart_methods_length)
: is_valid_(true),
dedicated_thread_(dedicated_thread),
running_thread_(std::this_thread::get_id()),
dart_method_ptr_(std::make_unique<DartMethodPointer>(this, dart_methods, dart_methods_length)) {
is_valid_ = true;

if (!dedicated_thread_) {
InitializeJSRuntime();
}
InitializeJSRuntime();
}

JSRuntime* DartIsolateContext::runtime() {
Expand All @@ -101,33 +97,47 @@ JSRuntime* DartIsolateContext::runtime() {
DartIsolateContext::~DartIsolateContext() {
is_valid_ = false;
running_isolates_--;
dispatcher_.reset();
pages_in_ui_thread_.clear();
assert(running_isolates_ == 0);
FinalizeJSRuntime();
}

if (dedicated_thread_) {
dispatcher_.reset();
void* DartIsolateContext::AddNewPage(bool is_dedicated, int32_t new_page_context_id) {
if (is_dedicated) {
dispatcher_->AllocateNewJSThread(new_page_context_id);
auto* page = dispatcher_->PostToJsSync(
true, new_page_context_id,
[](DartIsolateContext* dart_isolate_context, int32_t page_context_id) -> void* {
InitializeJSRuntime();
return new webf::WebFPage(dart_isolate_context, true, page_context_id, nullptr);
},
this, new_page_context_id);
dispatcher_->SetOpaqueForJSThread(new_page_context_id, page, [](void* p) {
delete static_cast<webf::WebFPage*>(p);
DartIsolateContext::FinalizeJSRuntime();
});
return page;
} else {
assert(running_isolates_ == 0);
FinalizeJSRuntime();
auto page = std::make_unique<webf::WebFPage>(this, false, new_page_context_id, nullptr);
void* p = page.get();
pages_in_ui_thread_.emplace(std::move(page));
return p;
}
}

void* DartIsolateContext::AddNewPage(int32_t new_page_context_id) {
dispatcher_->AllocateNewJSThread(new_page_context_id);

auto* page = dispatcher_->PostToJsSync(new_page_context_id, [](DartIsolateContext* dart_isolate_context, int32_t page_context_id) -> void* {
InitializeJSRuntime();
return new webf::WebFPage(dart_isolate_context, page_context_id, nullptr);
}, this, new_page_context_id);
dispatcher_->SetOpaqueForJSThread(new_page_context_id, page, [](void* p) {
delete static_cast<webf::WebFPage*>(p);
DartIsolateContext::FinalizeJSRuntime();
});

return page;
}

void DartIsolateContext::RemovePage(const webf::WebFPage* page) {
int32_t page_context_id = page->contextId;
dispatcher_->KillJSThread(page_context_id);
void DartIsolateContext::RemovePage(bool is_dedicated, const webf::WebFPage* page) {
if (is_dedicated) {
int32_t page_context_id = page->contextId;
dispatcher_->KillJSThread(page_context_id);
} else {
for (auto it = pages_in_ui_thread_.begin(); it != pages_in_ui_thread_.end(); ++it) {
if (it->get() == page) {
pages_in_ui_thread_.erase(it);
break;
}
}
}
}

thread_local std::unique_ptr<DartContextData> DartIsolateContext::data_ {};
Expand Down
8 changes: 4 additions & 4 deletions bridge/core/dart_isolate_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void DeleteDartWire(DartWireContext* wire);
// DartIsolateContext has a 1:1 correspondence with a dart isolates.
class DartIsolateContext {
public:
explicit DartIsolateContext(bool dedicated_thread, const uint64_t* dart_methods, int32_t dart_methods_length);
explicit DartIsolateContext(const uint64_t* dart_methods, int32_t dart_methods_length);

JSRuntime* runtime();
FORCE_INLINE bool valid() { return is_valid_; }
Expand All @@ -43,8 +43,8 @@ class DartIsolateContext {

const std::unique_ptr<DartContextData>& EnsureData() const;

void* AddNewPage(int32_t new_page_context_id);
void RemovePage(const WebFPage* page);
void* AddNewPage(bool is_dedicated, int32_t new_page_context_id);
void RemovePage(bool is_dedicated, const WebFPage* page);

~DartIsolateContext();

Expand All @@ -56,7 +56,7 @@ class DartIsolateContext {
int is_valid_{false};
std::thread::id running_thread_;
static thread_local std::unique_ptr<DartContextData> data_;
bool dedicated_thread_;
std::set<std::unique_ptr<WebFPage>> pages_in_ui_thread_;
std::unique_ptr<multi_threading::Dispatcher> dispatcher_ = nullptr;
// Dart methods ptr should keep alive when ExecutingContext is disposing.
const std::unique_ptr<DartMethodPointer> dart_method_ptr_ = nullptr;
Expand Down
Loading

0 comments on commit 47d0ef9

Please sign in to comment.