* 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:
tudorms 2020-06-30 22:32:55 -07:00 коммит произвёл Julio C. Rocha
Родитель 6e2d7b890c
Коммит c7f427d85b
13 изменённых файлов: 182 добавлений и 243 удалений

Просмотреть файл

@ -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();