refactor: Clean up the implementation of the registerStreamProtocol (#11357)
* Use weak pointer to avoid race condition * Use DeleteSoon to delete pointer across threads * Simplify EventSubscriber * No need to manually mange V8 convertions * Fix cpplint warning We should update cpplint for this, but let's do it in other PR. * Move UI thread operations to EventSubscriber * Less and more assertions Some methods are now private so no more need to assert threads. * Fix cpplint warnings * No longer needs the EventEmitted * EventSubscriber => StreamSubscriber * Reduce the copies when passing data * Fix cpplint warnings
This commit is contained in:
parent
3805c5f538
commit
d3ae541397
9 changed files with 314 additions and 373 deletions
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
@ -13,6 +15,22 @@ namespace internal {
|
|||
namespace {
|
||||
|
||||
struct TranslaterHolder {
|
||||
explicit TranslaterHolder(v8::Isolate* isolate)
|
||||
: handle(isolate, v8::External::New(isolate, this)) {
|
||||
handle.SetWeak(this, &GC, v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
~TranslaterHolder() {
|
||||
if (!handle.IsEmpty()) {
|
||||
handle.ClearWeak();
|
||||
handle.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
static void GC(const v8::WeakCallbackInfo<TranslaterHolder>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
v8::Global<v8::External> handle;
|
||||
Translater translater;
|
||||
};
|
||||
|
||||
|
@ -22,20 +40,27 @@ v8::Persistent<v8::FunctionTemplate> g_call_translater;
|
|||
void CallTranslater(v8::Local<v8::External> external,
|
||||
v8::Local<v8::Object> state,
|
||||
mate::Arguments* args) {
|
||||
// Whether the callback should only be called for once.
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
bool one_time = state->Has(mate::StringToSymbol(isolate, "oneTime"));
|
||||
|
||||
// Check if the callback has already been called.
|
||||
v8::Local<v8::String> called_symbol = mate::StringToSymbol(isolate, "called");
|
||||
if (state->Has(called_symbol)) {
|
||||
args->ThrowError("callback can only be called for once");
|
||||
return;
|
||||
} else {
|
||||
state->Set(called_symbol, v8::Boolean::New(isolate, true));
|
||||
if (one_time) {
|
||||
auto called_symbol = mate::StringToSymbol(isolate, "called");
|
||||
if (state->Has(called_symbol)) {
|
||||
args->ThrowError("callback can only be called for once");
|
||||
return;
|
||||
} else {
|
||||
state->Set(called_symbol, v8::Boolean::New(isolate, true));
|
||||
}
|
||||
}
|
||||
|
||||
TranslaterHolder* holder = static_cast<TranslaterHolder*>(external->Value());
|
||||
holder->translater.Run(args);
|
||||
delete holder;
|
||||
|
||||
// Free immediately for one-time callback.
|
||||
if (one_time)
|
||||
delete holder;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -90,8 +115,7 @@ v8::Local<v8::Function> SafeV8Function::NewHandle(v8::Isolate* isolate) const {
|
|||
}
|
||||
|
||||
v8::Local<v8::Value> CreateFunctionFromTranslater(
|
||||
v8::Isolate* isolate,
|
||||
const Translater& translater) {
|
||||
v8::Isolate* isolate, const Translater& translater, bool one_time) {
|
||||
// The FunctionTemplate is cached.
|
||||
if (g_call_translater.IsEmpty())
|
||||
g_call_translater.Reset(isolate, mate::CreateFunctionTemplate(
|
||||
|
@ -99,11 +123,16 @@ v8::Local<v8::Value> CreateFunctionFromTranslater(
|
|||
|
||||
v8::Local<v8::FunctionTemplate> call_translater =
|
||||
v8::Local<v8::FunctionTemplate>::New(isolate, g_call_translater);
|
||||
auto* holder = new TranslaterHolder;
|
||||
auto* holder = new TranslaterHolder(isolate);
|
||||
holder->translater = translater;
|
||||
return BindFunctionWith(
|
||||
isolate, isolate->GetCurrentContext(), call_translater->GetFunction(),
|
||||
v8::External::New(isolate, holder), v8::Object::New(isolate));
|
||||
Dictionary state = mate::Dictionary::CreateEmpty(isolate);
|
||||
if (one_time)
|
||||
state.Set("oneTime", true);
|
||||
return BindFunctionWith(isolate,
|
||||
isolate->GetCurrentContext(),
|
||||
call_translater->GetFunction(),
|
||||
holder->handle.Get(isolate),
|
||||
state.GetHandle());
|
||||
}
|
||||
|
||||
// func.bind(func, arg1).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue