1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/child/quota_message_filter.h"
6
7#include "base/message_loop/message_loop_proxy.h"
8#include "content/child/quota_dispatcher.h"
9#include "content/child/thread_safe_sender.h"
10#include "content/child/worker_thread_task_runner.h"
11#include "content/common/quota_messages.h"
12
13namespace content {
14
15QuotaMessageFilter::QuotaMessageFilter(
16    ThreadSafeSender* thread_safe_sender)
17    : main_thread_loop_proxy_(base::MessageLoopProxy::current()),
18      thread_safe_sender_(thread_safe_sender),
19      next_request_id_(0) {
20}
21
22QuotaMessageFilter::~QuotaMessageFilter() {}
23
24int QuotaMessageFilter::GenerateRequestID(int thread_id) {
25  base::AutoLock lock(request_id_map_lock_);
26  request_id_map_[next_request_id_] = thread_id;
27  return next_request_id_++;
28}
29
30void QuotaMessageFilter::ClearThreadRequests(int thread_id) {
31  base::AutoLock lock(request_id_map_lock_);
32  for (RequestIdToThreadId::iterator iter = request_id_map_.begin();
33       iter != request_id_map_.end();) {
34    if (iter->second == thread_id)
35      request_id_map_.erase(iter++);
36    else
37      iter++;
38  }
39}
40
41base::TaskRunner* QuotaMessageFilter::OverrideTaskRunnerForMessage(
42    const IPC::Message& msg) {
43  if (IPC_MESSAGE_CLASS(msg) != QuotaMsgStart)
44    return NULL;
45
46  int request_id = -1, thread_id = 0;
47  const bool success = PickleIterator(msg).ReadInt(&request_id);
48  DCHECK(success);
49
50  {
51    base::AutoLock lock(request_id_map_lock_);
52    RequestIdToThreadId::iterator found = request_id_map_.find(request_id);
53    if (found != request_id_map_.end()) {
54      thread_id = found->second;
55      request_id_map_.erase(found);
56    }
57  }
58
59  if (!thread_id)
60    return main_thread_loop_proxy_.get();
61  return new WorkerThreadTaskRunner(thread_id);
62}
63
64bool QuotaMessageFilter::OnMessageReceived(const IPC::Message& msg) {
65  if (IPC_MESSAGE_CLASS(msg) != QuotaMsgStart)
66    return false;
67  QuotaDispatcher::ThreadSpecificInstance(thread_safe_sender_.get(), this)
68      ->OnMessageReceived(msg);
69  return true;
70}
71
72}  // namespace content
73