<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/debugger/worker_devtools_manager_io.h"

#include <list>

#include "base/tuple.h"
#include "content/browser/browser_thread.h"
#include "content/browser/debugger/devtools_manager.h"
#include "content/browser/debugger/worker_devtools_message_filter.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/devtools_messages.h"

namespace {

void NotifyWorkerDevToolsClientClosingOnIOThread(int worker_process_host_id,
                                                 int worker_route_id) {
  WorkerDevToolsManagerIO::GetInstance()->WorkerDevToolsClientClosing(
      worker_process_host_id,
      worker_route_id);
}

class ClientsUI : public DevToolsClientHost::CloseListener {
 public:
  static ClientsUI* GetInstance() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    static ClientsUI* instance = new ClientsUI();
    return instance;
  }

  DevToolsClientHost* FindDevToolsClient(int worker_process_host_id,
                                         int worker_route_id) {
    WorkerIdToClientHostMap::iterator it =
        worker_id_to_client_host_.find(WorkerId(worker_process_host_id,
                                                worker_route_id));
    if (it == worker_id_to_client_host_.end())
      return NULL;
    return it->second;
  }

  bool FindWorkerInfo(DevToolsClientHost* client_host,
                      int* host_id,
                      int* route_id) {
    for (WorkerIdToClientHostMap::const_iterator it =
             worker_id_to_client_host_.begin();
         it != worker_id_to_client_host_.end(); ++it) {
      if (it->second == client_host) {
        WorkerId id = it->first;
        *host_id = id.first;
        *route_id = id.second;
        return true;
      }
    }
    return false;
  }

  void RegisterDevToolsClientForWorker(int worker_process_host_id,
                                       int worker_route_id,
                                       DevToolsClientHost* client) {
    client->set_close_listener(this);
    WorkerId worker_id(worker_process_host_id, worker_route_id);
    worker_id_to_client_host_[worker_id] = client;
  }

 private:
  ClientsUI() {}
  virtual ~ClientsUI() {}

  virtual void ClientHostClosing(DevToolsClientHost* host) {
    WorkerIdToClientHostMap::iterator it = worker_id_to_client_host_.begin();
    for (; it != worker_id_to_client_host_.end(); ++it) {
      if (it->second == host) {
        WorkerId id = it->first;
        BrowserThread::PostTask(
            BrowserThread::IO, FROM_HERE,
            NewRunnableFunction(NotifyWorkerDevToolsClientClosingOnIOThread,
                                id.first, id.second));
        worker_id_to_client_host_.erase(it);
        return;
      }
    }
  }

  typedef std::pair<int, int> WorkerId;
  typedef std::map<WorkerId, DevToolsClientHost*> WorkerIdToClientHostMap;
  WorkerIdToClientHostMap worker_id_to_client_host_;

  DISALLOW_COPY_AND_ASSIGN(ClientsUI);
};

}  // namespace

class WorkerDevToolsManagerIO::InspectedWorkersList {
 public:
  InspectedWorkersList() {}

  void AddInstance(WorkerProcessHost* host, int route_id) {
    DCHECK(!Contains(host->id(), route_id));
    map_.push_back(Entry(host, route_id));
  }

  bool Contains(int host_id, int route_id) {
    return FindHost(host_id, route_id) != NULL;
  }

  WorkerProcessHost* FindHost(int host_id, int route_id) {
    Entries::iterator it = FindEntry(host_id, route_id);
    if (it == map_.end())
      return NULL;
    return it->host;
  }

  WorkerProcessHost* RemoveInstance(int host_id, int route_id) {
    Entries::iterator it = FindEntry(host_id, route_id);
    if (it == map_.end())
      return NULL;
    WorkerProcessHost* host = it->host;
    map_.erase(it);
    return host;
  }

  void WorkerDevToolsMessageFilterClosing(int worker_process_host_id) {
    Entries::iterator it = map_.begin();
    while (it != map_.end()) {
      if (it->host->id() == worker_process_host_id)
        it = map_.erase(it);
      else
        ++it;
    }
  }

 private:
  struct Entry {
    Entry(WorkerProcessHost* host, int route_id)
        : host(host),
          route_id(route_id) {}
    WorkerProcessHost* const host;
    int const route_id;
  };
  typedef std::list<Entry> Entries;

  Entries::iterator FindEntry(int host_id, int route_id) {
    Entries::iterator it = map_.begin();
    while (it != map_.end()) {
      if (it->host->id() == host_id && it->route_id == route_id)
        break;
    }
    return it;<commit_msg>DevTools: browser hangs if inspected shared worker is restarted<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/debugger/worker_devtools_manager_io.h"

#include <list>

#include "base/tuple.h"
#include "content/browser/browser_thread.h"
#include "content/browser/debugger/devtools_manager.h"
#include "content/browser/debugger/worker_devtools_message_filter.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/devtools_messages.h"

namespace {

void NotifyWorkerDevToolsClientClosingOnIOThread(int worker_process_host_id,
                                                 int worker_route_id) {
  WorkerDevToolsManagerIO::GetInstance()->WorkerDevToolsClientClosing(
      worker_process_host_id,
      worker_route_id);
}

class ClientsUI : public DevToolsClientHost::CloseListener {
 public:
  static ClientsUI* GetInstance() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    static ClientsUI* instance = new ClientsUI();
    return instance;
  }

  DevToolsClientHost* FindDevToolsClient(int worker_process_host_id,
                                         int worker_route_id) {
    WorkerIdToClientHostMap::iterator it =
        worker_id_to_client_host_.find(WorkerId(worker_process_host_id,
                                                worker_route_id));
    if (it == worker_id_to_client_host_.end())
      return NULL;
    return it->second;
  }

  bool FindWorkerInfo(DevToolsClientHost* client_host,
                      int* host_id,
                      int* route_id) {
    for (WorkerIdToClientHostMap::const_iterator it =
             worker_id_to_client_host_.begin();
         it != worker_id_to_client_host_.end(); ++it) {
      if (it->second == client_host) {
        WorkerId id = it->first;
        *host_id = id.first;
        *route_id = id.second;
        return true;
      }
    }
    return false;
  }

  void RegisterDevToolsClientForWorker(int worker_process_host_id,
                                       int worker_route_id,
                                       DevToolsClientHost* client) {
    client->set_close_listener(this);
    WorkerId worker_id(worker_process_host_id, worker_route_id);
    worker_id_to_client_host_[worker_id] = client;
  }

 private:
  ClientsUI() {}
  virtual ~ClientsUI() {}

  virtual void ClientHostClosing(DevToolsClientHost* host) {
    WorkerIdToClientHostMap::iterator it = worker_id_to_client_host_.begin();
    for (; it != worker_id_to_client_host_.end(); ++it) {
      if (it->second == host) {
        WorkerId id = it->first;
        BrowserThread::PostTask(
            BrowserThread::IO, FROM_HERE,
            NewRunnableFunction(NotifyWorkerDevToolsClientClosingOnIOThread,
                                id.first, id.second));
        worker_id_to_client_host_.erase(it);
        return;
      }
    }
  }

  typedef std::pair<int, int> WorkerId;
  typedef std::map<WorkerId, DevToolsClientHost*> WorkerIdToClientHostMap;
  WorkerIdToClientHostMap worker_id_to_client_host_;

  DISALLOW_COPY_AND_ASSIGN(ClientsUI);
};

}  // namespace

class WorkerDevToolsManagerIO::InspectedWorkersList {
 public:
  InspectedWorkersList() {}

  void AddInstance(WorkerProcessHost* host, int route_id) {
    DCHECK(!Contains(host->id(), route_id));
    map_.push_back(Entry(host, route_id));
  }

  bool Contains(int host_id, int route_id) {
    return FindHost(host_id, route_id) != NULL;
  }

  WorkerProcessHost* FindHost(int host_id, int route_id) {
    Entries::iterator it = FindEntry(host_id, route_id);
    if (it == map_.end())
      return NULL;
    return it->host;
  }

  WorkerProcessHost* RemoveInstance(int host_id, int route_id) {
    Entries::iterator it = FindEntry(host_id, route_id);
    if (it == map_.end())
      return NULL;
    WorkerProcessHost* host = it->host;
    map_.erase(it);
    return host;
  }

  void WorkerDevToolsMessageFilterClosing(int worker_process_host_id) {
    Entries::iterator it = map_.begin();
    while (it != map_.end()) {
      if (it->host->id() == worker_process_host_id)
        it = map_.erase(it);
      else
        ++it;
    }
  }

 private:
  struct Entry {
    Entry(WorkerProcessHost* host, int route_id)
        : host(host),
          route_id(route_id) {}
    WorkerProcessHost* const host;
    int const route_id;
  };
  typedef std::list<Entry> Entries;

  Entries::iterator FindEntry(int host_id, int route_id) {
    Entries::iterator it = map_.begin();
    while (it != map_.end()) {
      if (it->host->id() == host_id && it->route_id == route_id)
        break;
      ++it;
    }
    return it;
{'fraction_non_alphanumeric': 0.10428147520135651, 'fraction_numerical': 0.000847816871555744, 'mean_word_length': 2.941938178780284, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '251677', 'n_tokens_mistral': 2971, 'n_tokens_neox': 2887, 'n_words': 566}