mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
refactor: make ReplyChannel inherit from gin::Wrappable (#49339)
* refactor: make ReplyChannel inherit from gin::Wrappable * chore: add kElectronReplyChannel to chore_add_electron_objects_to_wrappablepointertag.patch * fix: use gin::PerIsolateData::DisposeObserver * fix: lifetime issues * chore: rm perisolatedata hook in favor of prefinalizer --------- Co-authored-by: deepak1556 <hop2deep@gmail.com>
This commit is contained in:
@@ -4,42 +4,24 @@
|
||||
|
||||
#include "shell/common/gin_helper/reply_channel.h"
|
||||
|
||||
#include "base/debug/stack_trace.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/common/gin_converters/blink_converter.h"
|
||||
#include "shell/common/gin_helper/handle.h"
|
||||
#include "v8/include/cppgc/allocation.h"
|
||||
#include "v8/include/v8-cppgc.h"
|
||||
|
||||
namespace gin_helper::internal {
|
||||
|
||||
// static
|
||||
using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;
|
||||
gin_helper::Handle<ReplyChannel> ReplyChannel::Create(v8::Isolate* isolate,
|
||||
InvokeCallback callback) {
|
||||
return gin_helper::CreateHandle(isolate,
|
||||
new ReplyChannel(std::move(callback)));
|
||||
}
|
||||
const gin::WrapperInfo ReplyChannel::kWrapperInfo = {
|
||||
{gin::kEmbedderNativeGin},
|
||||
gin::kElectronReplyChannel};
|
||||
|
||||
gin::ObjectTemplateBuilder ReplyChannel::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin_helper::DeprecatedWrappable<
|
||||
ReplyChannel>::GetObjectTemplateBuilder(isolate)
|
||||
.SetMethod("sendReply", &ReplyChannel::SendReply);
|
||||
}
|
||||
ReplyChannel::ReplyChannel(v8::Isolate* isolate, InvokeCallback callback)
|
||||
: callback_{std::move(callback)} {}
|
||||
|
||||
const char* ReplyChannel::GetTypeName() {
|
||||
return "ReplyChannel";
|
||||
}
|
||||
|
||||
ReplyChannel::ReplyChannel(InvokeCallback callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
|
||||
ReplyChannel::~ReplyChannel() {
|
||||
if (callback_)
|
||||
SendError(electron::JavascriptEnvironment::GetIsolate(),
|
||||
std::move(callback_), "reply was never sent");
|
||||
}
|
||||
ReplyChannel::~ReplyChannel() = default;
|
||||
|
||||
// static
|
||||
void ReplyChannel::SendError(v8::Isolate* isolate,
|
||||
@@ -73,11 +55,43 @@ bool ReplyChannel::SendReplyImpl(v8::Isolate* isolate,
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
ReplyChannel* ReplyChannel::Create(v8::Isolate* isolate,
|
||||
InvokeCallback callback) {
|
||||
return cppgc::MakeGarbageCollected<ReplyChannel>(
|
||||
isolate->GetCppHeap()->GetAllocationHandle(), isolate,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
const gin::WrapperInfo* ReplyChannel::wrapper_info() const {
|
||||
return &kWrapperInfo;
|
||||
}
|
||||
|
||||
const char* ReplyChannel::GetHumanReadableName() const {
|
||||
return "Electron / ReplyChannel";
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder ReplyChannel::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
return gin::Wrappable<ReplyChannel>::GetObjectTemplateBuilder(isolate)
|
||||
.SetMethod("sendReply", &ReplyChannel::SendReply);
|
||||
}
|
||||
|
||||
bool ReplyChannel::SendReply(v8::Isolate* isolate, v8::Local<v8::Value> arg) {
|
||||
return SendReplyImpl(isolate, std::move(callback_), std::move(arg));
|
||||
}
|
||||
|
||||
gin::DeprecatedWrapperInfo ReplyChannel::kWrapperInfo = {
|
||||
gin::kEmbedderNativeGin};
|
||||
void ReplyChannel::EnsureReplySent() {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
if (callback_) {
|
||||
DCHECK(isolate);
|
||||
// Create a task since we cannot allocate on V8 heap during GC
|
||||
// which is needed by ReplyChannel::SendError implementation.
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&ReplyChannel::SendError, isolate, std::move(callback_),
|
||||
"reply was never sent"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gin_helper::internal
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "gin/wrappable.h"
|
||||
#include "shell/common/api/api.mojom.h"
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
#include "v8/include/cppgc/prefinalizer.h"
|
||||
|
||||
namespace gin_helper {
|
||||
template <typename T>
|
||||
@@ -28,27 +29,38 @@ namespace gin_helper::internal {
|
||||
// This object wraps the InvokeCallback so that if it gets GC'd by V8, we can
|
||||
// still call the callback and send an error. Not doing so causes a Mojo DCHECK,
|
||||
// since Mojo requires callbacks to be called before they are destroyed.
|
||||
class ReplyChannel : public gin_helper::DeprecatedWrappable<ReplyChannel> {
|
||||
class ReplyChannel : public gin::Wrappable<ReplyChannel> {
|
||||
CPPGC_USING_PRE_FINALIZER(ReplyChannel, EnsureReplySent);
|
||||
|
||||
public:
|
||||
using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;
|
||||
static gin_helper::Handle<ReplyChannel> Create(v8::Isolate* isolate,
|
||||
InvokeCallback callback);
|
||||
|
||||
static ReplyChannel* Create(v8::Isolate* isolate, InvokeCallback callback);
|
||||
|
||||
// Constructor is public only to satisfy cppgc::MakeGarbageCollected.
|
||||
// Callers should use Create() instead.
|
||||
explicit ReplyChannel(v8::Isolate* isolate, InvokeCallback callback);
|
||||
~ReplyChannel() override;
|
||||
|
||||
// disable copy
|
||||
ReplyChannel(const ReplyChannel&) = delete;
|
||||
ReplyChannel& operator=(const ReplyChannel&) = delete;
|
||||
|
||||
// gin_helper::Wrappable
|
||||
static gin::DeprecatedWrapperInfo kWrapperInfo;
|
||||
static const gin::WrapperInfo kWrapperInfo;
|
||||
const gin::WrapperInfo* wrapper_info() const override;
|
||||
const char* GetHumanReadableName() const override;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
// Invokes `callback` (if it's non-null) with `errmsg` as an arg.
|
||||
static void SendError(v8::Isolate* isolate,
|
||||
InvokeCallback callback,
|
||||
std::string_view errmsg);
|
||||
|
||||
private:
|
||||
explicit ReplyChannel(InvokeCallback callback);
|
||||
~ReplyChannel() override;
|
||||
void EnsureReplySent();
|
||||
|
||||
private:
|
||||
static bool SendReplyImpl(v8::Isolate* isolate,
|
||||
InvokeCallback callback,
|
||||
v8::Local<v8::Value> arg);
|
||||
|
||||
Reference in New Issue
Block a user