зеркало из https://github.com/microsoft/v8-jsi.git
Some inspector code cleanup (#17)
* Fix basic debugging support. Upgrade to V8 8.4 * Try a new way to install VS components * try different arguments for vs installer * try to collect logs for VSInstall failures * try to capture vslogs * syntax fix * add an update step * always download bootstrapper to update installer * Inspector cleanup; shutdown per-platform support (exp.) * Address some CR comments; update boost to 1.72 Co-authored-by: tudorm <tudorm@microsoft.com>
This commit is contained in:
Родитель
6e2d7b890c
Коммит
c7f427d85b
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"v8ref": "refs/branch-heads/8.4"
|
||||
}
|
|
@ -79,15 +79,15 @@ if ($PSVersionTable.Platform -and !$IsWindows) {
|
|||
#TODO (#2): Use the .gzip for Android / Linux builds
|
||||
# Verify the Boost installation
|
||||
if (-not (Test-Path "$env:BOOST_ROOT\boost\asio.hpp")) {
|
||||
if (-not (Test-Path (Join-Path $workpath "v8build/boost.1.71.0.0/lib/native/include/boost/asio.hpp"))) {
|
||||
if (-not (Test-Path (Join-Path $workpath "v8build/boost.1.72.0.0/lib/native/include/boost/asio.hpp"))) {
|
||||
Write-Host "Boost ASIO not found, downloading..."
|
||||
|
||||
$targetNugetExe = Join-Path $workpath "nuget.exe"
|
||||
Invoke-WebRequest "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile $targetNugetExe
|
||||
|
||||
& $targetNugetExe install -OutputDirectory (Join-Path $workpath "v8build") boost -Version 1.71.0
|
||||
& $targetNugetExe install -OutputDirectory (Join-Path $workpath "v8build") boost -Version 1.72.0
|
||||
}
|
||||
|
||||
$env:BOOST_ROOT = Join-Path $workpath "v8build/boost.1.71.0.0/lib/native/include"
|
||||
$env:BOOST_ROOT = Join-Path $workpath "v8build/boost.1.72.0.0/lib/native/include"
|
||||
Write-Host "##vso[task.setvariable variable=BOOST_ROOT;]$env:BOOST_ROOT"
|
||||
}
|
||||
|
|
|
@ -196,10 +196,10 @@ index 1cd402d8ba..c3c9df8fa1 100644
|
|||
} else {
|
||||
return EmbeddedTargetOs::kGeneric;
|
||||
diff --git a/src/torque/declaration-visitor.cc b/src/torque/declaration-visitor.cc
|
||||
index 6ec1b74df5..3fd90a1c8d 100644
|
||||
index 99b7bdddcd..8a227a614a 100644
|
||||
--- a/src/torque/declaration-visitor.cc
|
||||
+++ b/src/torque/declaration-visitor.cc
|
||||
@@ -371,7 +371,9 @@ Callable* DeclarationVisitor::Specialize(
|
||||
@@ -372,7 +372,9 @@ Callable* DeclarationVisitor::Specialize(
|
||||
}
|
||||
|
||||
void PredeclarationVisitor::ResolvePredeclarations() {
|
||||
|
@ -210,3 +210,20 @@ index 6ec1b74df5..3fd90a1c8d 100644
|
|||
if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) {
|
||||
CurrentScope::Scope scope_activator(alias->ParentScope());
|
||||
CurrentSourcePosition::Scope position_activator(alias->Position());
|
||||
diff --git a/src/utils/allocation.cc b/src/utils/allocation.cc
|
||||
index 12dfaf9572..b16b0b0020 100644
|
||||
--- a/src/utils/allocation.cc
|
||||
+++ b/src/utils/allocation.cc
|
||||
@@ -74,8 +74,10 @@ const int kAllocationTries = 2;
|
||||
} // namespace
|
||||
|
||||
v8::PageAllocator* GetPlatformPageAllocator() {
|
||||
- DCHECK_NOT_NULL(GetPageTableInitializer()->page_allocator());
|
||||
- return GetPageTableInitializer()->page_allocator();
|
||||
+ //DCHECK_NOT_NULL(GetPageTableInitializer()->page_allocator());
|
||||
+ //return GetPageTableInitializer()->page_allocator();
|
||||
+
|
||||
+ return V8::GetCurrentPlatform()->GetPageAllocator();
|
||||
}
|
||||
|
||||
v8::PageAllocator* SetPlatformPageAllocatorForTesting(
|
||||
|
|
|
@ -552,6 +552,7 @@ V8Runtime::V8Runtime(V8RuntimeArgs &&args) : args_(std::move(args)) {
|
|||
if (tls_isolate_usage_counter_++ > 0) {
|
||||
isolate_ = v8::Isolate::GetCurrent();
|
||||
} else {
|
||||
platform_holder_.addUsage();
|
||||
CreateNewIsolate();
|
||||
}
|
||||
|
||||
|
@ -581,10 +582,12 @@ V8Runtime::V8Runtime(V8RuntimeArgs &&args) : args_(std::move(args)) {
|
|||
}
|
||||
|
||||
V8Runtime::~V8Runtime() {
|
||||
// TODO: add check that destruction happens on the same thread id as construction
|
||||
#ifdef _WIN32
|
||||
if (inspector_agent_ && inspector_agent_->IsStarted()) {
|
||||
inspector_agent_->stop();
|
||||
}
|
||||
inspector_agent_.reset();
|
||||
#endif
|
||||
|
||||
host_object_constructor_.Reset();
|
||||
|
@ -596,12 +599,17 @@ V8Runtime::~V8Runtime() {
|
|||
}
|
||||
|
||||
if (--tls_isolate_usage_counter_ == 0) {
|
||||
IsolateData* isolate_data = reinterpret_cast<IsolateData *>(isolate_->GetData(ISOLATE_DATA_SLOT));
|
||||
delete isolate_data;
|
||||
|
||||
isolate_->SetData(v8runtime::ISOLATE_DATA_SLOT, nullptr);
|
||||
|
||||
isolate_->Exit();
|
||||
isolate_->Dispose();
|
||||
|
||||
delete create_params_.array_buffer_allocator;
|
||||
|
||||
platform_holder_.releaseUsage();
|
||||
}
|
||||
|
||||
// Note :: We never dispose V8 here. Is it required ?
|
||||
|
|
|
@ -90,10 +90,10 @@ class V8PlatformHolder {
|
|||
}
|
||||
|
||||
V8PlatformHolder() {
|
||||
}
|
||||
|
||||
void addUsage() {
|
||||
std::lock_guard<std::mutex> guard(mutex_s_);
|
||||
/*uint32_t current = use_count_s_;
|
||||
while (!use_count_s_.compare_exchange_weak(current, current + 1))
|
||||
;*/
|
||||
|
||||
if (use_count_s_++ == 0) {
|
||||
if (!platform_s_) {
|
||||
|
@ -107,17 +107,14 @@ while (!use_count_s_.compare_exchange_weak(current, current + 1))
|
|||
}
|
||||
}
|
||||
|
||||
~V8PlatformHolder() {
|
||||
void releaseUsage() {
|
||||
std::lock_guard<std::mutex> guard(mutex_s_);
|
||||
/*uint32_t current = use_count_s_;
|
||||
while (!use_count_s_.compare_exchange_weak(current, current - 1))
|
||||
;*/
|
||||
|
||||
if (--use_count_s_ == 0) {
|
||||
// We cannot shutdown the platform once created because V8 internally references bits of the platform from process-globals
|
||||
// This cannot be worked around, the design of V8 is not currently embedder-friendly
|
||||
//v8::V8::ShutdownPlatform();
|
||||
//platform_s_ = nullptr;
|
||||
v8::V8::ShutdownPlatform();
|
||||
platform_s_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,35 +79,7 @@ std::unique_ptr<v8_inspector::StringBuffer> Utf8ToStringView(
|
|||
|
||||
class V8NodeInspector;
|
||||
|
||||
class InspectorAgentDelegate : public inspector::SocketServerDelegate {
|
||||
public:
|
||||
InspectorAgentDelegate(
|
||||
AgentImpl *agent,
|
||||
const std::string &script_path,
|
||||
const std::string &script_name,
|
||||
bool wait);
|
||||
void AssignServer(InspectorSocketServer *server) override{};
|
||||
void StartSession(int session_id, const std::string &target_id) override;
|
||||
void MessageReceived(int session_id, const std::string &message) override;
|
||||
void EndSession(int session_id) override;
|
||||
std::vector<std::string> GetTargetIds() override;
|
||||
std::string GetTargetTitle(const std::string &id) override;
|
||||
std::string GetTargetUrl(const std::string &id) override;
|
||||
bool IsConnected() {
|
||||
return connected_;
|
||||
}
|
||||
|
||||
private:
|
||||
AgentImpl *agent_;
|
||||
bool connected_;
|
||||
int session_id_;
|
||||
const std::string script_name_;
|
||||
const std::string script_path_;
|
||||
const std::string target_id_;
|
||||
bool waiting_;
|
||||
};
|
||||
|
||||
class AgentImpl {
|
||||
class AgentImpl : public std::enable_shared_from_this<AgentImpl> {
|
||||
public:
|
||||
explicit AgentImpl(
|
||||
v8::Platform &platform,
|
||||
|
@ -162,8 +134,6 @@ class AgentImpl {
|
|||
|
||||
std::mutex state_m;
|
||||
|
||||
InspectorAgentDelegate *delegate_;
|
||||
|
||||
int port_;
|
||||
bool wait_;
|
||||
bool shutting_down_;
|
||||
|
@ -171,13 +141,13 @@ class AgentImpl {
|
|||
|
||||
bool waiting_for_frontend_ = true;
|
||||
|
||||
V8NodeInspector *inspector_;
|
||||
std::unique_ptr<V8NodeInspector> inspector_;
|
||||
v8::Isolate *isolate_;
|
||||
MessageQueue incoming_message_queue_;
|
||||
MessageQueue outgoing_message_queue_;
|
||||
bool dispatching_messages_;
|
||||
int session_id_;
|
||||
inspector::InspectorSocketServer *server_;
|
||||
std::unique_ptr<inspector::InspectorSocketServer> server_;
|
||||
|
||||
std::string script_name_;
|
||||
|
||||
|
@ -198,19 +168,19 @@ void InterruptCallback(v8::Isolate *, void *agent) {
|
|||
|
||||
class DispatchOnInspectorBackendTask : public v8::Task {
|
||||
public:
|
||||
explicit DispatchOnInspectorBackendTask(AgentImpl *agent) : agent_(agent) {}
|
||||
explicit DispatchOnInspectorBackendTask(AgentImpl& agent) : agent_(agent) {}
|
||||
|
||||
void Run() override {
|
||||
agent_->DispatchMessages();
|
||||
agent_.DispatchMessages();
|
||||
}
|
||||
|
||||
private:
|
||||
AgentImpl *agent_;
|
||||
AgentImpl& agent_;
|
||||
};
|
||||
|
||||
class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
|
||||
public:
|
||||
explicit ChannelImpl(AgentImpl *agent) : agent_(agent) {}
|
||||
explicit ChannelImpl(AgentImpl& agent) : agent_(agent) {}
|
||||
virtual ~ChannelImpl() {}
|
||||
|
||||
private:
|
||||
|
@ -229,30 +199,29 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
|
|||
|
||||
void sendMessageToFrontend(
|
||||
std::unique_ptr<v8_inspector::StringBuffer> message) {
|
||||
agent_->Write(agent_->session_id_, std::move(message));
|
||||
agent_.Write(agent_.session_id_, std::move(message));
|
||||
}
|
||||
|
||||
AgentImpl *const agent_;
|
||||
AgentImpl& agent_;
|
||||
};
|
||||
|
||||
using V8Inspector = v8_inspector::V8Inspector;
|
||||
|
||||
class V8NodeInspector : public v8_inspector::V8InspectorClient {
|
||||
public:
|
||||
V8NodeInspector(AgentImpl *agent)
|
||||
V8NodeInspector(AgentImpl& agent)
|
||||
: agent_(agent),
|
||||
waiting_for_resume_(false),
|
||||
running_nested_loop_(false),
|
||||
inspector_(V8Inspector::create(agent->isolate_, this)) {}
|
||||
inspector_(V8Inspector::create(agent.isolate_, this)) {}
|
||||
|
||||
void setupContext(
|
||||
v8::Local<v8::Context> context,
|
||||
const char *context_name /*must be null terminated*/) {
|
||||
v8_inspector::V8ContextInfo info(
|
||||
context, 1, Utf8ToStringView(context_name)->string());
|
||||
std::unique_ptr<v8_inspector::StringBuffer> name_buffer = Utf8ToStringView(context_name);
|
||||
v8_inspector::V8ContextInfo info(context, 1, name_buffer->string());
|
||||
|
||||
std::unique_ptr<v8_inspector::StringBuffer> aux_data_buffer;
|
||||
aux_data_buffer = Utf8ToStringView("{\"isDefault\":true}");
|
||||
std::unique_ptr<v8_inspector::StringBuffer> aux_data_buffer = Utf8ToStringView("{\"isDefault\":true}");
|
||||
info.auxData = aux_data_buffer->string();
|
||||
|
||||
inspector_->contextCreated(info);
|
||||
|
@ -264,8 +233,8 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient {
|
|||
return;
|
||||
running_nested_loop_ = true;
|
||||
while (waiting_for_resume_) {
|
||||
agent_->WaitForFrontendMessage();
|
||||
agent_->DispatchMessages();
|
||||
agent_.WaitForFrontendMessage();
|
||||
agent_.DispatchMessages();
|
||||
}
|
||||
waiting_for_resume_ = false;
|
||||
running_nested_loop_ = false;
|
||||
|
@ -293,8 +262,8 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient {
|
|||
void dispatchMessageFromFrontend(const v8_inspector::StringView &message) {
|
||||
std::string messagestr = StringViewToUtf8(message);
|
||||
|
||||
if (agent_->waiting_for_frontend_)
|
||||
agent_->waiting_for_frontend_ =
|
||||
if (agent_.waiting_for_frontend_)
|
||||
agent_.waiting_for_frontend_ =
|
||||
messagestr.find("Runtime.runIfWaitingForDebugger") !=
|
||||
std::string::npos;
|
||||
|
||||
|
@ -317,7 +286,7 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient {
|
|||
std::unique_ptr<v8_inspector::V8InspectorSession> session_;
|
||||
|
||||
private:
|
||||
AgentImpl *agent_;
|
||||
AgentImpl& agent_;
|
||||
v8::Platform *platform_;
|
||||
std::atomic<bool> waiting_for_resume_ {false};
|
||||
bool running_nested_loop_;
|
||||
|
@ -340,7 +309,7 @@ AgentImpl::AgentImpl(
|
|||
dispatching_messages_(false),
|
||||
session_id_(0),
|
||||
server_(nullptr) {
|
||||
inspector_ = new V8NodeInspector(this);
|
||||
inspector_ = std::make_unique<V8NodeInspector>(*this);
|
||||
inspector_->setupContext(context, context_name);
|
||||
}
|
||||
|
||||
|
@ -405,20 +374,21 @@ void InspectorWrapConsoleCall(const v8::FunctionCallbackInfo<v8::Value> &args) {
|
|||
}
|
||||
|
||||
void AgentImpl::Start() {
|
||||
std::thread([this]() {
|
||||
InspectorAgentDelegate delegate(this, "", script_name_, wait_);
|
||||
delegate_ = &delegate;
|
||||
|
||||
InspectorSocketServer server(
|
||||
std::unique_ptr<InspectorAgentDelegate>(&delegate), port_);
|
||||
server_ = &server;
|
||||
auto self(shared_from_this());
|
||||
std::thread([this, self]() {
|
||||
auto delegate = std::make_unique<InspectorAgentDelegate>(*this, "", script_name_, wait_);
|
||||
server_ = std::make_unique<InspectorSocketServer>(std::move(delegate), port_);
|
||||
|
||||
state_ = State::kAccepting;
|
||||
|
||||
// This loops
|
||||
if (!server.Start()) {
|
||||
if (!server_->Start()) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
server_->Stop();
|
||||
|
||||
server_.reset();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
@ -444,11 +414,14 @@ void AgentImpl::waitForDebugger() {
|
|||
}
|
||||
|
||||
void AgentImpl::Stop() {
|
||||
delete inspector_;
|
||||
if (server_) {
|
||||
server_->Stop();
|
||||
inspector_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool AgentImpl::IsConnected() {
|
||||
return delegate_ != nullptr && delegate_->IsConnected();
|
||||
return server_ && server_->IsConnected();
|
||||
}
|
||||
|
||||
bool AgentImpl::IsStarted() {
|
||||
|
@ -544,7 +517,7 @@ void AgentImpl::PostIncomingMessage(
|
|||
#else
|
||||
foregroundTaskRunner = platform_.GetForegroundTaskRunner(isolate_);
|
||||
#endif
|
||||
foregroundTaskRunner->PostTask(std::make_unique<DispatchOnInspectorBackendTask>(this));
|
||||
foregroundTaskRunner->PostTask(std::make_unique<DispatchOnInspectorBackendTask>(*this));
|
||||
isolate_->RequestInterrupt(InterruptCallback, this);
|
||||
}
|
||||
NotifyMessageReceived();
|
||||
|
@ -614,11 +587,14 @@ void AgentImpl::Write(
|
|||
SwapBehindLock(&outgoing_message_queue_, &outgoing_messages);
|
||||
for (const MessageQueue::value_type &outgoing : outgoing_messages) {
|
||||
v8_inspector::StringView view = outgoing.second->string();
|
||||
if (view.length() == 0) {
|
||||
server_->Stop();
|
||||
} else {
|
||||
server_->Send(
|
||||
outgoing.first, StringViewToUtf8(outgoing.second->string()));
|
||||
assert(server_);
|
||||
if (server_) {
|
||||
if (view.length() == 0) {
|
||||
server_->Stop();
|
||||
} else {
|
||||
server_->Send(
|
||||
outgoing.first, StringViewToUtf8(outgoing.second->string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -630,10 +606,9 @@ Agent::Agent(
|
|||
v8::Local<v8::Context> context,
|
||||
const char *context_name,
|
||||
int port)
|
||||
: impl(new AgentImpl(platform, isolate, context, context_name, port)) {}
|
||||
: impl(std::make_shared<AgentImpl>(platform, isolate, context, context_name, port)) {}
|
||||
|
||||
Agent::~Agent() {
|
||||
delete impl;
|
||||
}
|
||||
|
||||
void Agent::waitForDebugger() {
|
||||
|
@ -667,7 +642,7 @@ void Agent::FatalException(
|
|||
}
|
||||
|
||||
InspectorAgentDelegate::InspectorAgentDelegate(
|
||||
AgentImpl *agent,
|
||||
AgentImpl& agent,
|
||||
const std::string &script_path,
|
||||
const std::string &script_name,
|
||||
bool wait)
|
||||
|
@ -683,7 +658,7 @@ void InspectorAgentDelegate::StartSession(
|
|||
int session_id,
|
||||
const std::string & /*target_id*/) {
|
||||
connected_ = true;
|
||||
agent_->PostIncomingMessage(session_id, TAG_CONNECT);
|
||||
agent_.PostIncomingMessage(session_id, TAG_CONNECT);
|
||||
}
|
||||
|
||||
void InspectorAgentDelegate::MessageReceived(
|
||||
|
@ -697,15 +672,15 @@ void InspectorAgentDelegate::MessageReceived(
|
|||
if (message.find("\"Runtime.runIfWaitingForDebugger\"") !=
|
||||
std::string::npos) {
|
||||
waiting_ = false;
|
||||
agent_->ResumeStartup();
|
||||
agent_.ResumeStartup();
|
||||
}
|
||||
}
|
||||
agent_->PostIncomingMessage(session_id, message);
|
||||
agent_.PostIncomingMessage(session_id, message);
|
||||
}
|
||||
|
||||
void InspectorAgentDelegate::EndSession(int session_id) {
|
||||
connected_ = false;
|
||||
agent_->PostIncomingMessage(session_id, TAG_DISCONNECT);
|
||||
agent_.PostIncomingMessage(session_id, TAG_DISCONNECT);
|
||||
}
|
||||
|
||||
std::vector<std::string> InspectorAgentDelegate::GetTargetIds() {
|
||||
|
|
|
@ -45,7 +45,7 @@ class Agent {
|
|||
v8::Local<v8::Message> message);
|
||||
|
||||
private:
|
||||
AgentImpl *impl;
|
||||
std::shared_ptr<AgentImpl> impl;
|
||||
};
|
||||
|
||||
} // namespace inspector
|
||||
|
|
|
@ -62,12 +62,8 @@ constexpr ContainerOfHelper<Inner, Outer> ContainerOf(Inner Outer::*field,
|
|||
|
||||
namespace inspector {
|
||||
|
||||
class TcpHolder {
|
||||
class TcpHolder : public std::enable_shared_from_this<TcpHolder> {
|
||||
public:
|
||||
static void DisconnectAndDispose(TcpHolder* holder);
|
||||
using Pointer = DeleteFnPtr<TcpHolder, DisconnectAndDispose>;
|
||||
|
||||
static Pointer Accept(tcp_connection::pointer socket, InspectorSocket::DelegatePointer delegate);
|
||||
void SetHandler(ProtocolHandler* handler);
|
||||
int WriteRaw(const std::vector<char>& buffer/*, uv_write_cb write_cb*/);
|
||||
|
||||
|
@ -76,18 +72,15 @@ class TcpHolder {
|
|||
std::shared_ptr<tcp_connection> connection() { return connection_; };
|
||||
InspectorSocket::Delegate* delegate();
|
||||
|
||||
static void OnClosedCallback(void*data);
|
||||
TcpHolder(std::shared_ptr<tcp_connection> connection, std::unique_ptr<InspectorSocket::Delegate> delegate);
|
||||
~TcpHolder();
|
||||
|
||||
private:
|
||||
static void OnDataReceivedCb(std::vector<char>&, bool iseof, void*data);
|
||||
static void OnDataReceivedCb(std::vector<char>&, bool iseof, void*data);
|
||||
|
||||
|
||||
tcp_connection::pointer connection_;
|
||||
std::shared_ptr<tcp_connection> connection_;
|
||||
|
||||
explicit TcpHolder(std::shared_ptr<tcp_connection> connection, InspectorSocket::DelegatePointer delegate);
|
||||
~TcpHolder() = default;
|
||||
|
||||
const InspectorSocket::DelegatePointer delegate_;
|
||||
const std::unique_ptr<InspectorSocket::Delegate> delegate_;
|
||||
ProtocolHandler* handler_;
|
||||
std::vector<char> buffer_;
|
||||
};
|
||||
|
@ -95,7 +88,8 @@ class TcpHolder {
|
|||
|
||||
class ProtocolHandler {
|
||||
public:
|
||||
ProtocolHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp);
|
||||
ProtocolHandler(InspectorSocket* inspector, std::shared_ptr<TcpHolder>&& tcp);
|
||||
virtual ~ProtocolHandler() = default;
|
||||
|
||||
virtual void AcceptUpgrade(const std::string& accept_key) = 0;
|
||||
virtual void OnData(std::vector<char>* data) = 0;
|
||||
|
@ -108,15 +102,13 @@ class ProtocolHandler {
|
|||
InspectorSocket* inspector() {
|
||||
return inspector_;
|
||||
}
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~ProtocolHandler() = default;
|
||||
int WriteRaw(const std::vector<char>& buffer/*, uv_write_cb write_cb*/);
|
||||
InspectorSocket::Delegate* delegate();
|
||||
|
||||
InspectorSocket* const inspector_;
|
||||
TcpHolder::Pointer tcp_;
|
||||
std::shared_ptr<TcpHolder> tcp_;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
@ -336,11 +328,16 @@ static ws_decode_result decode_frame_hybi17(const std::vector<char>& buffer,
|
|||
// WS protocol
|
||||
class WsHandler : public ProtocolHandler {
|
||||
public:
|
||||
WsHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp)
|
||||
WsHandler(InspectorSocket* inspector, std::shared_ptr<TcpHolder> tcp)
|
||||
: ProtocolHandler(inspector, std::move(tcp)),
|
||||
OnCloseSent(&WsHandler::WaitForCloseReply),
|
||||
OnCloseRecieved(&WsHandler::CloseFrameReceived),
|
||||
dispose_(false) { }
|
||||
OnCloseRecieved(&WsHandler::CloseFrameReceived) { }
|
||||
|
||||
~WsHandler() {
|
||||
if (tcp_) {
|
||||
SendClose();
|
||||
}
|
||||
}
|
||||
|
||||
void AcceptUpgrade(const std::string& accept_key) override { }
|
||||
void CancelHandshake() override {}
|
||||
|
@ -350,10 +347,6 @@ class WsHandler : public ProtocolHandler {
|
|||
{
|
||||
tcp_.reset();
|
||||
}
|
||||
else if (dispose_)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void OnData(std::vector<char>* data) override {
|
||||
|
@ -373,16 +366,6 @@ class WsHandler : public ProtocolHandler {
|
|||
WriteRaw(output/*, WriteRequest::Cleanup*/);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Shutdown() override {
|
||||
if (tcp_) {
|
||||
dispose_ = true;
|
||||
SendClose();
|
||||
} else {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
using Callback = void (WsHandler::*)(void);
|
||||
|
||||
|
@ -433,7 +416,6 @@ class WsHandler : public ProtocolHandler {
|
|||
|
||||
Callback OnCloseSent;
|
||||
Callback OnCloseRecieved;
|
||||
bool dispose_;
|
||||
};
|
||||
|
||||
// HTTP protocol
|
||||
|
@ -453,7 +435,7 @@ class HttpEvent {
|
|||
|
||||
class HttpHandler : public ProtocolHandler {
|
||||
public:
|
||||
explicit HttpHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp)
|
||||
explicit HttpHandler(InspectorSocket* inspector, std::shared_ptr<TcpHolder>&& tcp)
|
||||
: ProtocolHandler(inspector, std::move(tcp)),
|
||||
parsing_value_(false) {
|
||||
llhttp_init(&parser_, HTTP_REQUEST, &parser_settings);
|
||||
|
@ -479,7 +461,7 @@ class HttpHandler : public ProtocolHandler {
|
|||
reply.insert(reply.end(), accept_ws_suffix,
|
||||
accept_ws_suffix + sizeof(accept_ws_suffix) - 1);
|
||||
if (WriteRaw(reply/*, WriteRequest::Cleanup*/) >= 0) {
|
||||
inspector_->SwitchProtocol(new WsHandler(inspector_, std::move(tcp_)));
|
||||
inspector_->SwitchProtocol(std::make_unique<WsHandler>(inspector_, std::move(tcp_)));
|
||||
} else {
|
||||
tcp_.reset();
|
||||
}
|
||||
|
@ -534,11 +516,6 @@ class HttpHandler : public ProtocolHandler {
|
|||
WriteRaw(data/*, WriteRequest::Cleanup*/);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Shutdown() override {
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
static void ThenCloseAndReportFailure(/*uv_write_t* req, */int status) {
|
||||
/*ProtocolHandler* handler = WriteRequest::from_write_req(req)->handler;
|
||||
|
@ -622,7 +599,7 @@ class HttpHandler : public ProtocolHandler {
|
|||
|
||||
// Any protocol
|
||||
ProtocolHandler::ProtocolHandler(InspectorSocket* inspector,
|
||||
TcpHolder::Pointer tcp)
|
||||
std::shared_ptr<TcpHolder>&& tcp)
|
||||
: inspector_(inspector), tcp_(std::move(tcp)) {
|
||||
CHECK_NOT_NULL(tcp_);
|
||||
tcp_->SetHandler(this);
|
||||
|
@ -643,25 +620,15 @@ std::string ProtocolHandler::GetHost() const {
|
|||
}
|
||||
|
||||
// RAII uv_tcp_t wrapper
|
||||
TcpHolder::TcpHolder(std::shared_ptr<tcp_connection> connection, InspectorSocket::DelegatePointer delegate)
|
||||
TcpHolder::TcpHolder(std::shared_ptr<tcp_connection> connection, std::unique_ptr<InspectorSocket::Delegate> delegate)
|
||||
: delegate_(std::move(delegate)),
|
||||
connection_(connection), handler_(nullptr) { }
|
||||
|
||||
/*static*/ void TcpHolder::OnClosedCallback(void*data) {
|
||||
TcpHolder* holder = reinterpret_cast<TcpHolder*>(data);
|
||||
delete holder;
|
||||
connection_(connection), handler_(nullptr) {
|
||||
connection_->registerReadCallback(TcpHolder::OnDataReceivedCb, this);
|
||||
connection_->read_loop_async();
|
||||
}
|
||||
|
||||
// static
|
||||
TcpHolder::Pointer TcpHolder::Accept(tcp_connection::pointer socket, InspectorSocket::DelegatePointer delegate) {
|
||||
TcpHolder* tcp = new TcpHolder(socket, std::move(delegate));
|
||||
|
||||
socket->registerCloseCallback(TcpHolder::OnClosedCallback, tcp);
|
||||
socket->registerReadCallback(TcpHolder::OnDataReceivedCb, tcp);
|
||||
socket->read_loop_async();
|
||||
|
||||
return TcpHolder::Pointer(tcp);
|
||||
|
||||
TcpHolder::~TcpHolder() {
|
||||
connection_->close();
|
||||
}
|
||||
|
||||
void TcpHolder::read_loop() {
|
||||
|
@ -705,27 +672,15 @@ void TcpHolder::OnDataReceivedCb(std::vector<char>& wiredata, bool iseof, void*d
|
|||
}
|
||||
}
|
||||
|
||||
/*static*/ void TcpHolder::DisconnectAndDispose(TcpHolder* holder) {
|
||||
holder->connection_->close();
|
||||
}
|
||||
|
||||
InspectorSocket::~InspectorSocket() = default;
|
||||
|
||||
// static
|
||||
void InspectorSocket::Shutdown(ProtocolHandler* handler) {
|
||||
handler->Shutdown();
|
||||
}
|
||||
std::unique_ptr<InspectorSocket> InspectorSocket::Accept(std::shared_ptr<tcp_connection> connection, std::unique_ptr<InspectorSocket::Delegate>&& delegate) {
|
||||
auto tcp = std::make_shared<TcpHolder>(std::move(connection), std::move(delegate));
|
||||
|
||||
// static
|
||||
InspectorSocket::Pointer InspectorSocket::Accept(std::shared_ptr<tcp_connection> connection, DelegatePointer delegate) {
|
||||
auto tcp = TcpHolder::Accept(connection, std::move(delegate));
|
||||
if (tcp) {
|
||||
InspectorSocket* inspector = new InspectorSocket();
|
||||
inspector->SwitchProtocol(new HttpHandler(inspector, std::move(tcp)));
|
||||
return InspectorSocket::Pointer(inspector);
|
||||
} else {
|
||||
return InspectorSocket::Pointer(nullptr);
|
||||
}
|
||||
auto inspector = std::make_unique<InspectorSocket>();
|
||||
inspector->SwitchProtocol(std::make_unique<HttpHandler>(inspector.get(), std::move(tcp)));
|
||||
return inspector;
|
||||
}
|
||||
|
||||
void InspectorSocket::AcceptUpgrade(const std::string& ws_key) {
|
||||
|
@ -740,8 +695,8 @@ std::string InspectorSocket::GetHost() {
|
|||
return protocol_handler_->GetHost();
|
||||
}
|
||||
|
||||
void InspectorSocket::SwitchProtocol(ProtocolHandler* handler) {
|
||||
protocol_handler_.reset(std::move(handler));
|
||||
void InspectorSocket::SwitchProtocol(std::unique_ptr<ProtocolHandler>&& handler) {
|
||||
protocol_handler_ = std::move(handler);
|
||||
}
|
||||
|
||||
void InspectorSocket::Write(const char* data, size_t len) {
|
||||
|
|
|
@ -3,20 +3,12 @@
|
|||
// This code is based on the old node inspector implementation. See LICENSE_NODE for Node.js' project license details
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "inspector_tcp.h"
|
||||
|
||||
template <typename T, void(*function)(T*)>
|
||||
struct FunctionDeleter {
|
||||
void operator()(T* pointer) const { function(pointer); }
|
||||
typedef std::unique_ptr<T, FunctionDeleter> Pointer;
|
||||
};
|
||||
|
||||
template <typename T, void(*function)(T*)>
|
||||
using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
|
||||
|
||||
namespace inspector {
|
||||
|
||||
class ProtocolHandler;
|
||||
|
@ -24,6 +16,9 @@ class ProtocolHandler;
|
|||
// HTTP Wrapper around a uv_tcp_t
|
||||
class InspectorSocket {
|
||||
public:
|
||||
InspectorSocket() = default;
|
||||
~InspectorSocket();
|
||||
|
||||
class Delegate {
|
||||
public:
|
||||
virtual void OnHttpGet(const std::string& host,
|
||||
|
@ -35,24 +30,16 @@ class InspectorSocket {
|
|||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
using DelegatePointer = std::unique_ptr<Delegate>;
|
||||
using Pointer = std::unique_ptr<InspectorSocket>;
|
||||
|
||||
static Pointer Accept(std::shared_ptr<tcp_connection> connection, DelegatePointer delegate);
|
||||
|
||||
~InspectorSocket();
|
||||
static std::unique_ptr<InspectorSocket> Accept(std::shared_ptr<tcp_connection> connection, std::unique_ptr<Delegate>&& delegate);
|
||||
|
||||
void AcceptUpgrade(const std::string& accept_key);
|
||||
void CancelHandshake();
|
||||
void Write(const char* data, size_t len);
|
||||
void SwitchProtocol(ProtocolHandler* handler);
|
||||
void SwitchProtocol(std::unique_ptr<ProtocolHandler>&& handler);
|
||||
std::string GetHost();
|
||||
|
||||
private:
|
||||
static void Shutdown(ProtocolHandler*);
|
||||
InspectorSocket() = default;
|
||||
|
||||
DeleteFnPtr<ProtocolHandler, Shutdown> protocol_handler_;
|
||||
std::unique_ptr<ProtocolHandler> protocol_handler_;
|
||||
|
||||
InspectorSocket(const InspectorSocket&) = delete;
|
||||
InspectorSocket& operator=(const InspectorSocket&) = delete;
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
ws_socket_.reset();
|
||||
}
|
||||
void Send(const std::string& message);
|
||||
void Own(InspectorSocket::Pointer ws_socket) {
|
||||
void Own(std::unique_ptr<InspectorSocket> ws_socket) {
|
||||
ws_socket_ = std::move(ws_socket);
|
||||
}
|
||||
int id() const { return id_; }
|
||||
|
@ -185,15 +185,14 @@ public:
|
|||
|
||||
private:
|
||||
const int id_;
|
||||
InspectorSocket::Pointer ws_socket_;
|
||||
std::unique_ptr<InspectorSocket> ws_socket_;
|
||||
const int server_port_;
|
||||
};
|
||||
|
||||
InspectorSocketServer::InspectorSocketServer(
|
||||
std::unique_ptr<SocketServerDelegate> delegate, int port, FILE* out)
|
||||
std::unique_ptr<InspectorAgentDelegate>&& delegate, int port, FILE* out)
|
||||
: delegate_(std::move(delegate)), port_(port),
|
||||
next_session_id_(0), out_(out) {
|
||||
delegate_->AssignServer(this);
|
||||
state_ = ServerState::kNew;
|
||||
}
|
||||
|
||||
|
@ -322,9 +321,9 @@ std::string InspectorSocketServer::GetFrontendURL(bool is_compat,
|
|||
}
|
||||
|
||||
bool InspectorSocketServer::Start() {
|
||||
tcp_server::pointer server = tcp_server::create(port_, InspectorSocketServer::SocketConnectedCallback, this);
|
||||
tcp_server_ = std::make_shared<tcp_server>(port_, InspectorSocketServer::SocketConnectedCallback, this);
|
||||
state_ = ServerState::kRunning;
|
||||
server->run();
|
||||
tcp_server_->run();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -332,11 +331,10 @@ void InspectorSocketServer::Stop() {
|
|||
if (state_ == ServerState::kStopped)
|
||||
return;
|
||||
CHECK_EQ(state_, ServerState::kRunning);
|
||||
|
||||
|
||||
state_ = ServerState::kStopped;
|
||||
|
||||
// TODODO
|
||||
// Stop the server.
|
||||
|
||||
tcp_server_->stop();
|
||||
|
||||
if (state_ == ServerState::kStopped) {
|
||||
delegate_.reset();
|
||||
|
@ -362,11 +360,9 @@ void InspectorSocketServer::Accept(std::shared_ptr<tcp_connection> connection, i
|
|||
std::unique_ptr<SocketSession> session(
|
||||
new SocketSession(this, next_session_id_++, server_port));
|
||||
|
||||
InspectorSocket::DelegatePointer delegate =
|
||||
InspectorSocket::DelegatePointer(
|
||||
new SocketSession::Delegate(this, session->id()));
|
||||
auto delegate = std::make_unique<SocketSession::Delegate>(this, session->id());
|
||||
|
||||
InspectorSocket::Pointer inspector =
|
||||
std::unique_ptr<InspectorSocket> inspector =
|
||||
InspectorSocket::Accept(connection, std::move(delegate));
|
||||
if (inspector) {
|
||||
session->Own(std::move(inspector));
|
||||
|
|
|
@ -16,16 +16,31 @@ class InspectorSocketServer;
|
|||
class SocketSession;
|
||||
class ServerSocket;
|
||||
|
||||
class SocketServerDelegate {
|
||||
public:
|
||||
virtual void AssignServer(InspectorSocketServer* server) = 0;
|
||||
virtual void StartSession(int session_id, const std::string& target_id) = 0;
|
||||
virtual void EndSession(int session_id) = 0;
|
||||
virtual void MessageReceived(int session_id, const std::string& message) = 0;
|
||||
virtual std::vector<std::string> GetTargetIds() = 0;
|
||||
virtual std::string GetTargetTitle(const std::string& id) = 0;
|
||||
virtual std::string GetTargetUrl(const std::string& id) = 0;
|
||||
virtual ~SocketServerDelegate() {}
|
||||
class InspectorAgentDelegate {
|
||||
public:
|
||||
InspectorAgentDelegate(
|
||||
AgentImpl& agent,
|
||||
const std::string &script_path,
|
||||
const std::string &script_name,
|
||||
bool wait);
|
||||
void StartSession(int session_id, const std::string &target_id);
|
||||
void MessageReceived(int session_id, const std::string &message);
|
||||
void EndSession(int session_id);
|
||||
std::vector<std::string> GetTargetIds();
|
||||
std::string GetTargetTitle(const std::string &id);
|
||||
std::string GetTargetUrl(const std::string &id);
|
||||
bool IsConnected() {
|
||||
return connected_;
|
||||
}
|
||||
|
||||
private:
|
||||
AgentImpl& agent_;
|
||||
bool connected_;
|
||||
int session_id_;
|
||||
const std::string script_name_;
|
||||
const std::string script_path_;
|
||||
const std::string target_id_;
|
||||
bool waiting_;
|
||||
};
|
||||
|
||||
// HTTP Server, writes messages requested as TransportActions, and responds
|
||||
|
@ -33,7 +48,7 @@ public:
|
|||
|
||||
class InspectorSocketServer {
|
||||
public:
|
||||
InspectorSocketServer(std::unique_ptr<SocketServerDelegate> delegate, int port,
|
||||
InspectorSocketServer(std::unique_ptr<InspectorAgentDelegate>&& delegate, int port,
|
||||
FILE* out = stderr);
|
||||
~InspectorSocketServer();
|
||||
|
||||
|
@ -53,6 +68,9 @@ public:
|
|||
void MessageReceived(int session_id, const std::string& message) {
|
||||
delegate_->MessageReceived(session_id, message);
|
||||
}
|
||||
bool IsConnected() {
|
||||
return delegate_->IsConnected();
|
||||
}
|
||||
SocketSession* Session(int session_id);
|
||||
//bool done() const {
|
||||
// return server_sockets_.empty() && connected_sessions_.empty();
|
||||
|
@ -69,9 +87,11 @@ private:
|
|||
bool TargetExists(const std::string& id);
|
||||
|
||||
enum class ServerState { kNew, kRunning, kStopping, kStopped };
|
||||
std::unique_ptr<SocketServerDelegate> delegate_;
|
||||
std::unique_ptr<InspectorAgentDelegate> delegate_;
|
||||
const std::string host_;
|
||||
int port_;
|
||||
|
||||
std::shared_ptr<tcp_server> tcp_server_;
|
||||
|
||||
int next_session_id_;
|
||||
FILE* out_;
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
|
||||
namespace inspector {
|
||||
|
||||
/*static*/ tcp_server::pointer tcp_server::create(int port, ConnectionCallback callback, void* data)
|
||||
{
|
||||
return pointer(new tcp_server(port, callback, data));
|
||||
}
|
||||
|
||||
tcp_server::tcp_server(int port, ConnectionCallback callback, void* data)
|
||||
: io_service_(), acceptor_(io_service_), socket_(io_service_), connectioncallback_(callback), callbackData_(data)
|
||||
{
|
||||
|
@ -30,25 +25,29 @@ void tcp_server::run() {
|
|||
io_service_.run();
|
||||
}
|
||||
|
||||
void tcp_server::stop() {
|
||||
boost::system::error_code ec;
|
||||
acceptor_.close(ec);
|
||||
socket_.close(ec);
|
||||
|
||||
io_service_.stop();
|
||||
}
|
||||
|
||||
void tcp_server::do_accept()
|
||||
{
|
||||
std::shared_ptr<tcp_server> self;
|
||||
acceptor_.async_accept(socket_,
|
||||
[this](boost::system::error_code ec)
|
||||
[this, self](boost::system::error_code ec)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
connectioncallback_(tcp_connection::create(std::move(socket_)), callbackData_);
|
||||
connectioncallback_(std::make_shared<tcp_connection>(std::move(socket_)), callbackData_);
|
||||
}
|
||||
|
||||
do_accept();
|
||||
});
|
||||
}
|
||||
|
||||
/*static*/ tcp_connection::pointer tcp_connection::create(boost::asio::ip::tcp::socket socket)
|
||||
{
|
||||
return pointer(new tcp_connection(std::move(socket)));
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& tcp_connection::socket()
|
||||
{
|
||||
return socket_;
|
||||
|
@ -84,7 +83,6 @@ void tcp_connection::read_loop_async() {
|
|||
}
|
||||
else
|
||||
{
|
||||
closecallback_(closeCallbackData_);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
@ -153,8 +151,6 @@ void tcp_connection::close() {
|
|||
socket_.close(ec);
|
||||
if (ec)
|
||||
std::abort();
|
||||
|
||||
closecallback_(closeCallbackData_);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,15 +13,9 @@ namespace inspector {
|
|||
class tcp_connection : public std::enable_shared_from_this<tcp_connection>
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<tcp_connection> pointer;
|
||||
|
||||
static pointer create(boost::asio::ip::tcp::socket socket);
|
||||
boost::asio::ip::tcp::socket& socket();
|
||||
|
||||
typedef void(*ReadCallback)(std::vector<char>&, bool iseof, void*data);
|
||||
typedef void(*CloseCallback)(void*data);
|
||||
|
||||
inline void registerCloseCallback(CloseCallback callback, void*data) { closecallback_ = callback; closeCallbackData_ = data; }
|
||||
inline void registerReadCallback(ReadCallback callback, void*data) { readcallback_ = callback; callbackData_ = data; }
|
||||
|
||||
void read_loop_async();
|
||||
|
@ -29,10 +23,10 @@ public:
|
|||
void do_write(bool cont);
|
||||
void close();
|
||||
|
||||
private:
|
||||
inline tcp_connection(boost::asio::ip::tcp::socket socket)
|
||||
: socket_(std::move(socket)) {}
|
||||
|
||||
private:
|
||||
int port_;
|
||||
|
||||
boost::asio::ip::tcp::socket socket_;
|
||||
|
@ -44,9 +38,6 @@ private:
|
|||
void* callbackData_;
|
||||
ReadCallback readcallback_;
|
||||
|
||||
void* closeCallbackData_;
|
||||
CloseCallback closecallback_;
|
||||
|
||||
std::mutex queueAccessMutex;
|
||||
std::queue<std::vector<char>> outQueue;
|
||||
|
||||
|
@ -56,14 +47,11 @@ private:
|
|||
|
||||
class tcp_server : public std::enable_shared_from_this<tcp_server> {
|
||||
public:
|
||||
typedef std::shared_ptr<tcp_server> pointer;
|
||||
typedef void(*ConnectionCallback)(std::shared_ptr<tcp_connection> connection, void* callbackData_);
|
||||
|
||||
void run();
|
||||
void stop();
|
||||
|
||||
static pointer create(int port, ConnectionCallback callback, void* data);
|
||||
|
||||
private:
|
||||
tcp_server(int port, ConnectionCallback callback, void* data);
|
||||
void do_accept();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче