<commit_before>// Copyright (c) 2012 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/worker_host/worker_service_impl.h"

#include <string>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "base/threading/thread.h"
#include "content/browser/debugger/worker_devtools_manager.h"
#include "content/browser/worker_host/worker_message_filter.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/worker_service_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"

namespace content {

const int WorkerServiceImpl::kMaxWorkerProcessesWhenSharing = 10;
const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64;
const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16;

WorkerService* WorkerService::GetInstance() {
  return WorkerServiceImpl::GetInstance();
}

WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  return Singleton<WorkerServiceImpl>::get();
}

WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) {
}

WorkerServiceImpl::~WorkerServiceImpl() {
  // The observers in observers_ can't be used here because they might be
  // gone already.
}

void WorkerServiceImpl::OnWorkerMessageFilterClosing(
    WorkerMessageFilter* filter) {
  for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
    iter->FilterShutdown(filter);
  }

  // See if that process had any queued workers.
  for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
       i != queued_workers_.end();) {
    i->RemoveFilters(filter);
    if (i->NumFilters() == 0) {
      i = queued_workers_.erase(i);
    } else {
      ++i;
    }
  }

  // Also, see if that process had any pending shared workers.
  for (WorkerProcessHost::Instances::iterator iter =
           pending_shared_workers_.begin();
       iter != pending_shared_workers_.end(); ) {
    iter->worker_document_set()->RemoveAll(filter);
    if (iter->worker_document_set()->IsEmpty()) {
      iter = pending_shared_workers_.erase(iter);
    } else {
      ++iter;
    }
  }

  // Either a worker proceess has shut down, in which case we can start one of
  // the queued workers, or a renderer has shut down, in which case it doesn't
  // affect anything.  We call this function in both scenarios because then we
  // don't have to keep track which filters are from worker processes.
  TryStartingQueuedWorker();
}

void WorkerServiceImpl::CreateWorker(<commit_msg>Fix crash in WorkerTest.MultipleTabsQueuedSharedWorker. I could get this consistently when running debug content_browsertests builds in VS.<commit_after>// Copyright (c) 2012 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/worker_host/worker_service_impl.h"

#include <string>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/sys_info.h"
#include "base/threading/thread.h"
#include "content/browser/debugger/worker_devtools_manager.h"
#include "content/browser/worker_host/worker_message_filter.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/worker_service_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"

namespace content {

const int WorkerServiceImpl::kMaxWorkerProcessesWhenSharing = 10;
const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64;
const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16;

WorkerService* WorkerService::GetInstance() {
  return WorkerServiceImpl::GetInstance();
}

WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  return Singleton<WorkerServiceImpl>::get();
}

WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) {
}

WorkerServiceImpl::~WorkerServiceImpl() {
  // The observers in observers_ can't be used here because they might be
  // gone already.
}

void WorkerServiceImpl::OnWorkerMessageFilterClosing(
    WorkerMessageFilter* filter) {
  for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
    iter->FilterShutdown(filter);
  }

  // See if that process had any queued workers.
  for (WorkerProcessHost::Instances::iterator i = queued_workers_.begin();
       i != queued_workers_.end();) {
    i->RemoveFilters(filter);
    if (i->NumFilters() == 0) {
      i = queued_workers_.erase(i);
    } else {
      ++i;
    }
  }

  for (WorkerProcessHost::Instances::iterator i =
           pending_shared_workers_.begin();
       i != pending_shared_workers_.end(); ) {
     i->RemoveFilters(filter);
     if (i->NumFilters() == 0) {
      i = pending_shared_workers_.erase(i);
    } else {
      ++i;
    }
  }

  // Also, see if that process had any pending shared workers.
  for (WorkerProcessHost::Instances::iterator iter =
           pending_shared_workers_.begin();
       iter != pending_shared_workers_.end(); ) {
    iter->worker_document_set()->RemoveAll(filter);
    if (iter->worker_document_set()->IsEmpty()) {
      iter = pending_shared_workers_.erase(iter);
    } else {
      ++iter;
    }
  }

  // Either a worker proceess has shut down, in which case we can start one of
  // the queued workers, or a renderer has shut down, in which case it doesn't
  // affect anything.  We call this function in both scenarios because then we
  // don't have to keep track which filters are from worker processes.
  TryStartingQueuedWorker();
}

void WorkerServiceImpl::CreateWorker(
{'fraction_non_alphanumeric': 0.11422686945500633, 'fraction_numerical': 0.003960709759188847, 'mean_word_length': 4.739090909090909, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5557240', 'n_tokens_mistral': 1939, 'n_tokens_neox': 1891, 'n_words': 454}