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 {