DevTools: migrate protocol dispatcher off RefPtr.
BUG=580337
Review URL: https://codereview.chromium.org/1752213003
Cr-Original-Commit-Position: refs/heads/master@{#378696}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 56a35fcc3bc960b6373ab1c5769901c70bc2d400
diff --git a/Dispatcher_cpp.template b/Dispatcher_cpp.template
index 0dbad39..7c3535c 100644
--- a/Dispatcher_cpp.template
+++ b/Dispatcher_cpp.template
@@ -8,6 +8,7 @@
#include "platform/inspector_protocol/FrontendChannel.h"
#include "platform/inspector_protocol/Parser.h"
+#include "wtf/HashSet.h"
#include "wtf/text/CString.h"
namespace blink {
@@ -15,6 +16,18 @@
using protocol::Maybe;
+class DispatcherImpl;
+
+class DispatcherImplWeakPtr {
+public:
+ DispatcherImplWeakPtr(DispatcherImpl* dispatcher) : m_dispatcher(dispatcher) { }
+ ~DispatcherImplWeakPtr();
+ DispatcherImpl* get() { return m_dispatcher; }
+ void dispose() { m_dispatcher = nullptr; }
+private:
+ DispatcherImpl* m_dispatcher;
+};
+
class DispatcherImpl : public Dispatcher {
public:
DispatcherImpl(FrontendChannel* frontendChannel)
@@ -40,19 +53,36 @@
m_commonErrors.insert(ServerError, -32000);
}
- virtual void clearFrontend() { m_frontendChannel = 0; }
+ ~DispatcherImpl() { clearFrontend(); }
+
+ virtual void clearFrontend()
+ {
+ m_frontendChannel = nullptr;
+ for (auto& weak : m_weakPtrs)
+ weak->dispose();
+ m_weakPtrs.clear();
+ }
+
+ PassOwnPtr<DispatcherImplWeakPtr> weakPtr()
+ {
+ OwnPtr<DispatcherImplWeakPtr> weak = adoptPtr(new DispatcherImplWeakPtr(this));
+ m_weakPtrs.add(weak.get());
+ return weak.release();
+ }
+
virtual void dispatch(int sessionId, const String& message);
virtual void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String& errorMessage, ErrorSupport* errors) const;
using Dispatcher::reportProtocolError;
void sendResponse(int sessionId, int callId, const ErrorString& invocationError, ErrorSupport* errors, PassOwnPtr<protocol::DictionaryValue> result);
- bool isActive() { return m_frontendChannel; }
{% for domain in api.domains %}
virtual void registerAgent({{domain.domain}}CommandHandler* agent) { ASSERT(!m_{{domain.domain | lower}}Agent); m_{{domain.domain | lower}}Agent = agent; }
{% endfor %}
private:
+ friend class CallbackBase;
+ friend class DispatcherImplWeakPtr;
using CallHandler = void (DispatcherImpl::*)(int sessionId, int callId, PassOwnPtr<DictionaryValue> messageObject, ErrorSupport* errors);
using DispatchMap = HashMap<String, CallHandler>;
@@ -84,8 +114,15 @@
DispatchMap m_dispatchMap;
Vector<int> m_commonErrors;
+ HashSet<DispatcherImplWeakPtr*> m_weakPtrs;
};
+DispatcherImplWeakPtr::~DispatcherImplWeakPtr()
+{
+ if (m_dispatcher)
+ m_dispatcher->m_weakPtrs.remove(this);
+}
+
const char DispatcherImpl::InvalidParamsFormatString[] = "Some arguments of method '%s' can't be processed";
{% for domain in api.domains %}
{% for command in domain.commands %}
@@ -93,7 +130,7 @@
{% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
{% if "async" in command %}
-Dispatcher::{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback::{{command.name | to_title_case}}Callback(PassRefPtr<DispatcherImpl> backendImpl, int sessionId, int id) : CallbackBase(backendImpl, sessionId, id) { }
+Dispatcher::{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback::{{command.name | to_title_case}}Callback(PassOwnPtr<DispatcherImplWeakPtr> backendImpl, int sessionId, int id) : CallbackBase(backendImpl, sessionId, id) { }
void Dispatcher::{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback::sendSuccess(
{%- for parameter in command.returns -%}
@@ -153,7 +190,7 @@
{% endif %}
{% if "async" in command %}
- RefPtr<{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback> callback = adoptRef(new {{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback(this, sessionId, callId));
+ OwnPtr<{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback> callback = adoptPtr(new {{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback(weakPtr(), sessionId, callId));
{% elif "returns" in command %}
// Declare output parameters.
OwnPtr<protocol::DictionaryValue> result = DictionaryValue::create();
@@ -166,6 +203,7 @@
{% endfor %}
{% endif %}
+ OwnPtr<DispatcherImplWeakPtr> weak = weakPtr();
ErrorString error;
m_{{domain.domain | lower}}Agent->{{command.name}}(&error
{%- for property in command.parameters -%}
@@ -193,22 +231,23 @@
{% endif %}
{% endfor %}
}
- sendResponse(sessionId, callId, error, result.release());
+ if (weak->get())
+ weak->get()->sendResponse(sessionId, callId, error, result.release());
{% elif not("async" in command) %}
- sendResponse(sessionId, callId, error);
+ if (weak->get())
+ weak->get()->sendResponse(sessionId, callId, error);
{% endif %}
}
{% endfor %}
{% endfor %}
-PassRefPtr<Dispatcher> Dispatcher::create(FrontendChannel* frontendChannel)
+PassOwnPtr<Dispatcher> Dispatcher::create(FrontendChannel* frontendChannel)
{
- return adoptRef(new DispatcherImpl(frontendChannel));
+ return adoptPtr(new DispatcherImpl(frontendChannel));
}
void DispatcherImpl::dispatch(int sessionId, const String& message)
{
- RefPtr<Dispatcher> protect(this);
int callId = 0;
OwnPtr<protocol::Value> parsedMessage = parseJSON(message);
ASSERT(parsedMessage);
@@ -288,8 +327,8 @@
return true;
}
-Dispatcher::CallbackBase::CallbackBase(PassRefPtr<DispatcherImpl> backendImpl, int sessionId, int id)
- : m_backendImpl(backendImpl), m_sessionId(sessionId), m_id(id), m_alreadySent(false) { }
+Dispatcher::CallbackBase::CallbackBase(PassOwnPtr<DispatcherImplWeakPtr> backendImpl, int sessionId, int id)
+ : m_backendImpl(backendImpl), m_sessionId(sessionId), m_id(id) { }
Dispatcher::CallbackBase::~CallbackBase() { }
@@ -299,17 +338,17 @@
sendIfActive(nullptr, error);
}
-bool Dispatcher::CallbackBase::isActive()
+void Dispatcher::CallbackBase::dispose()
{
- return !m_alreadySent && m_backendImpl->isActive();
+ m_backendImpl = nullptr;
}
void Dispatcher::CallbackBase::sendIfActive(PassOwnPtr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError)
{
- if (m_alreadySent)
+ if (!m_backendImpl->get())
return;
- m_backendImpl->sendResponse(m_sessionId, m_id, invocationError, nullptr, partialMessage);
- m_alreadySent = true;
+ m_backendImpl->get()->sendResponse(m_sessionId, m_id, invocationError, nullptr, partialMessage);
+ m_backendImpl = nullptr;
}
} // namespace protocol
diff --git a/Dispatcher_h.template b/Dispatcher_h.template
index 0694e5f..3a9f3f0 100644
--- a/Dispatcher_h.template
+++ b/Dispatcher_h.template
@@ -13,33 +13,28 @@
namespace protocol {
class FrontendChannel;
-class DispatcherImpl;
+class DispatcherImplWeakPtr;
using ErrorString = String;
-class PLATFORM_EXPORT Dispatcher: public RefCounted<Dispatcher> {
+class PLATFORM_EXPORT Dispatcher {
public:
- static PassRefPtr<Dispatcher> create(FrontendChannel* frontendChannel);
+ static PassOwnPtr<Dispatcher> create(FrontendChannel* frontendChannel);
virtual ~Dispatcher() { }
- class PLATFORM_EXPORT CallbackBase: public RefCounted<CallbackBase> {
+ class PLATFORM_EXPORT CallbackBase {
public:
- CallbackBase(PassRefPtr<DispatcherImpl> backendImpl, int sessionId, int id);
+ CallbackBase(PassOwnPtr<DispatcherImplWeakPtr> backendImpl, int sessionId, int id);
virtual ~CallbackBase();
void sendFailure(const ErrorString&);
- bool isActive();
+ void dispose();
protected:
void sendIfActive(PassOwnPtr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError);
private:
- void disable() { m_alreadySent = true; }
-
- RefPtr<DispatcherImpl> m_backendImpl;
+ OwnPtr<DispatcherImplWeakPtr> m_backendImpl;
int m_sessionId;
int m_id;
- bool m_alreadySent;
-
- friend class DispatcherImpl;
};
{% for domain in api.domains %}
@@ -51,7 +46,7 @@
{% if "async" in command %}
class PLATFORM_EXPORT {{command.name | to_title_case}}Callback : public CallbackBase {
public:
- {{command.name | to_title_case}}Callback(PassRefPtr<DispatcherImpl>, int sessionId, int id);
+ {{command.name | to_title_case}}Callback(PassOwnPtr<DispatcherImplWeakPtr>, int sessionId, int id);
void sendSuccess(
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
@@ -73,7 +68,7 @@
{%- endif -%}
{%- endfor -%}
{%- if "async" in command -%}
- , PassRefPtr<{{command.name | to_title_case}}Callback> callback
+ , PassOwnPtr<{{command.name | to_title_case}}Callback> callback
{%- else -%}
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
diff --git a/Parser.h b/Parser.h
index 17849d3..224aaf4 100644
--- a/Parser.h
+++ b/Parser.h
@@ -6,7 +6,6 @@
#define Parser_h
#include "platform/PlatformExport.h"
-#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
namespace blink {