diff --git a/config.json b/config.json index cadef81..573a79e 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,4 @@ { - "version": "0.3.0", + "version": "0.3.1", "v8ref": "refs/branch-heads/8.4" } \ No newline at end of file diff --git a/scripts/fetch_code.ps1 b/scripts/fetch_code.ps1 index c85367d..db1f077 100644 --- a/scripts/fetch_code.ps1 +++ b/scripts/fetch_code.ps1 @@ -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" } diff --git a/scripts/patch/src.diff b/scripts/patch/src.diff index 3547f32..f54161f 100644 --- a/scripts/patch/src.diff +++ b/scripts/patch/src.diff @@ -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( diff --git a/src/V8JsiRuntime.cpp b/src/V8JsiRuntime.cpp index 87a0e8e..6d677da 100644 --- a/src/V8JsiRuntime.cpp +++ b/src/V8JsiRuntime.cpp @@ -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(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 ? diff --git a/src/V8JsiRuntime_impl.h b/src/V8JsiRuntime_impl.h index 0c70f5b..d45bbad 100644 --- a/src/V8JsiRuntime_impl.h +++ b/src/V8JsiRuntime_impl.h @@ -90,10 +90,10 @@ class V8PlatformHolder { } V8PlatformHolder() { + } + + void addUsage() { std::lock_guard 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 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; } } diff --git a/src/inspector/inspector_agent.cpp b/src/inspector/inspector_agent.cpp index cf177af..038e82f 100644 --- a/src/inspector/inspector_agent.cpp +++ b/src/inspector/inspector_agent.cpp @@ -79,35 +79,7 @@ std::unique_ptr 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 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 { 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 inspector_; v8::Isolate *isolate_; MessageQueue incoming_message_queue_; MessageQueue outgoing_message_queue_; bool dispatching_messages_; int session_id_; - inspector::InspectorSocketServer *server_; + std::unique_ptr 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 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 context, const char *context_name /*must be null terminated*/) { - v8_inspector::V8ContextInfo info( - context, 1, Utf8ToStringView(context_name)->string()); + std::unique_ptr name_buffer = Utf8ToStringView(context_name); + v8_inspector::V8ContextInfo info(context, 1, name_buffer->string()); - std::unique_ptr aux_data_buffer; - aux_data_buffer = Utf8ToStringView("{\"isDefault\":true}"); + std::unique_ptr 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 session_; private: - AgentImpl *agent_; + AgentImpl& agent_; v8::Platform *platform_; std::atomic 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(*this); inspector_->setupContext(context, context_name); } @@ -405,20 +374,21 @@ void InspectorWrapConsoleCall(const v8::FunctionCallbackInfo &args) { } void AgentImpl::Start() { - std::thread([this]() { - InspectorAgentDelegate delegate(this, "", script_name_, wait_); - delegate_ = &delegate; - - InspectorSocketServer server( - std::unique_ptr(&delegate), port_); - server_ = &server; + auto self(shared_from_this()); + std::thread([this, self]() { + auto delegate = std::make_unique(*this, "", script_name_, wait_); + server_ = std::make_unique(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(this)); + foregroundTaskRunner->PostTask(std::make_unique(*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 context, const char *context_name, int port) - : impl(new AgentImpl(platform, isolate, context, context_name, port)) {} + : impl(std::make_shared(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 InspectorAgentDelegate::GetTargetIds() { diff --git a/src/inspector/inspector_agent.h b/src/inspector/inspector_agent.h index 364cebc..52100da 100644 --- a/src/inspector/inspector_agent.h +++ b/src/inspector/inspector_agent.h @@ -45,7 +45,7 @@ class Agent { v8::Local message); private: - AgentImpl *impl; + std::shared_ptr impl; }; } // namespace inspector diff --git a/src/inspector/inspector_socket.cpp b/src/inspector/inspector_socket.cpp index 0af7974..d6a5d9b 100644 --- a/src/inspector/inspector_socket.cpp +++ b/src/inspector/inspector_socket.cpp @@ -62,12 +62,8 @@ constexpr ContainerOfHelper ContainerOf(Inner Outer::*field, namespace inspector { -class TcpHolder { +class TcpHolder : public std::enable_shared_from_this { public: - static void DisconnectAndDispose(TcpHolder* holder); - using Pointer = DeleteFnPtr; - - static Pointer Accept(tcp_connection::pointer socket, InspectorSocket::DelegatePointer delegate); void SetHandler(ProtocolHandler* handler); int WriteRaw(const std::vector& buffer/*, uv_write_cb write_cb*/); @@ -76,18 +72,15 @@ class TcpHolder { std::shared_ptr connection() { return connection_; }; InspectorSocket::Delegate* delegate(); - static void OnClosedCallback(void*data); + TcpHolder(std::shared_ptr connection, std::unique_ptr delegate); + ~TcpHolder(); private: - static void OnDataReceivedCb(std::vector&, bool iseof, void*data); + static void OnDataReceivedCb(std::vector&, bool iseof, void*data); - - tcp_connection::pointer connection_; + std::shared_ptr connection_; - explicit TcpHolder(std::shared_ptr connection, InspectorSocket::DelegatePointer delegate); - ~TcpHolder() = default; - - const InspectorSocket::DelegatePointer delegate_; + const std::unique_ptr delegate_; ProtocolHandler* handler_; std::vector buffer_; }; @@ -95,7 +88,8 @@ class TcpHolder { class ProtocolHandler { public: - ProtocolHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp); + ProtocolHandler(InspectorSocket* inspector, std::shared_ptr&& tcp); + virtual ~ProtocolHandler() = default; virtual void AcceptUpgrade(const std::string& accept_key) = 0; virtual void OnData(std::vector* 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& buffer/*, uv_write_cb write_cb*/); InspectorSocket::Delegate* delegate(); InspectorSocket* const inspector_; - TcpHolder::Pointer tcp_; + std::shared_ptr tcp_; }; namespace { @@ -336,11 +328,16 @@ static ws_decode_result decode_frame_hybi17(const std::vector& buffer, // WS protocol class WsHandler : public ProtocolHandler { public: - WsHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp) + WsHandler(InspectorSocket* inspector, std::shared_ptr 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* 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&& 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(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&& 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 connection, InspectorSocket::DelegatePointer delegate) +TcpHolder::TcpHolder(std::shared_ptr connection, std::unique_ptr delegate) : delegate_(std::move(delegate)), - connection_(connection), handler_(nullptr) { } - -/*static*/ void TcpHolder::OnClosedCallback(void*data) { - TcpHolder* holder = reinterpret_cast(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& 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::Accept(std::shared_ptr connection, std::unique_ptr&& delegate) { + auto tcp = std::make_shared(std::move(connection), std::move(delegate)); -// static -InspectorSocket::Pointer InspectorSocket::Accept(std::shared_ptr 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(); + inspector->SwitchProtocol(std::make_unique(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&& handler) { + protocol_handler_ = std::move(handler); } void InspectorSocket::Write(const char* data, size_t len) { diff --git a/src/inspector/inspector_socket.h b/src/inspector/inspector_socket.h index ca33795..2e2409e 100644 --- a/src/inspector/inspector_socket.h +++ b/src/inspector/inspector_socket.h @@ -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 #include #include #include "inspector_tcp.h" -template -struct FunctionDeleter { - void operator()(T* pointer) const { function(pointer); } - typedef std::unique_ptr Pointer; -}; - -template -using DeleteFnPtr = typename FunctionDeleter::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; - using Pointer = std::unique_ptr; - - static Pointer Accept(std::shared_ptr connection, DelegatePointer delegate); - - ~InspectorSocket(); + static std::unique_ptr Accept(std::shared_ptr connection, std::unique_ptr&& 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&& handler); std::string GetHost(); private: - static void Shutdown(ProtocolHandler*); - InspectorSocket() = default; - - DeleteFnPtr protocol_handler_; + std::unique_ptr protocol_handler_; InspectorSocket(const InspectorSocket&) = delete; InspectorSocket& operator=(const InspectorSocket&) = delete; diff --git a/src/inspector/inspector_socket_server.cpp b/src/inspector/inspector_socket_server.cpp index 5caafec..d3efa17 100644 --- a/src/inspector/inspector_socket_server.cpp +++ b/src/inspector/inspector_socket_server.cpp @@ -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 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 ws_socket_; const int server_port_; }; InspectorSocketServer::InspectorSocketServer( - std::unique_ptr delegate, int port, FILE* out) + std::unique_ptr&& 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(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 connection, i std::unique_ptr 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(this, session->id()); - InspectorSocket::Pointer inspector = + std::unique_ptr inspector = InspectorSocket::Accept(connection, std::move(delegate)); if (inspector) { session->Own(std::move(inspector)); diff --git a/src/inspector/inspector_socket_server.h b/src/inspector/inspector_socket_server.h index a5b6612..4c34d82 100644 --- a/src/inspector/inspector_socket_server.h +++ b/src/inspector/inspector_socket_server.h @@ -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 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 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 delegate, int port, + InspectorSocketServer(std::unique_ptr&& 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 delegate_; + std::unique_ptr delegate_; const std::string host_; int port_; + + std::shared_ptr tcp_server_; int next_session_id_; FILE* out_; diff --git a/src/inspector/inspector_tcp.cpp b/src/inspector/inspector_tcp.cpp index c2b208d..4ba0d32 100644 --- a/src/inspector/inspector_tcp.cpp +++ b/src/inspector/inspector_tcp.cpp @@ -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 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(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_); } } \ No newline at end of file diff --git a/src/inspector/inspector_tcp.h b/src/inspector/inspector_tcp.h index ef38ed1..2dcbbeb 100644 --- a/src/inspector/inspector_tcp.h +++ b/src/inspector/inspector_tcp.h @@ -13,15 +13,9 @@ namespace inspector { class tcp_connection : public std::enable_shared_from_this { public: - typedef std::shared_ptr pointer; - - static pointer create(boost::asio::ip::tcp::socket socket); boost::asio::ip::tcp::socket& socket(); typedef void(*ReadCallback)(std::vector&, 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> outQueue; @@ -56,14 +47,11 @@ private: class tcp_server : public std::enable_shared_from_this { public: - typedef std::shared_ptr pointer; typedef void(*ConnectionCallback)(std::shared_ptr 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();