1// Copyright (c) 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#ifndef CONTENT_BROWSER_WEBUI_URL_DATA_SOURCE_IMPL_H_
6#define CONTENT_BROWSER_WEBUI_URL_DATA_SOURCE_IMPL_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/sequenced_task_runner_helpers.h"
11#include "content/browser/webui/url_data_manager.h"
12#include "content/common/content_export.h"
13
14namespace base {
15class RefCountedMemory;
16}
17
18namespace content {
19class URLDataManagerBackend;
20class URLDataSource;
21class URLDataSourceImpl;
22
23// Trait used to handle deleting a URLDataSource. Deletion happens on the UI
24// thread.
25//
26// Implementation note: the normal shutdown sequence is for the UI loop to
27// stop pumping events then the IO loop and thread are stopped. When the
28// URLDataSources are no longer referenced (which happens when IO thread stops)
29// they get added to the UI message loop for deletion. But because the UI loop
30// has stopped by the time this happens the URLDataSources would be leaked.
31//
32// To make sure URLDataSources are properly deleted URLDataManager manages
33// deletion of the URLDataSources.  When a URLDataSource is no longer referenced
34// it is added to |data_sources_| and a task is posted to the UI thread to
35// handle the actual deletion. During shutdown |DeleteDataSources| is invoked so
36// that all pending URLDataSources are properly deleted.
37struct DeleteURLDataSource {
38  static void Destruct(const URLDataSourceImpl* data_source) {
39    URLDataManager::DeleteDataSource(data_source);
40  }
41};
42
43// A URLDataSource is an object that can answer requests for data
44// asynchronously. URLDataSources are collectively owned with refcounting smart
45// pointers and should never be deleted on the IO thread, since their calls
46// are handled almost always on the UI thread and there's a possibility of a
47// data race.  The |DeleteDataSource| trait above is used to enforce this.
48class URLDataSourceImpl : public base::RefCountedThreadSafe<
49    URLDataSourceImpl, DeleteURLDataSource> {
50 public:
51  // See source_name_ below for docs on that parameter. Takes ownership of
52  // |source|.
53  URLDataSourceImpl(const std::string& source_name,
54                    URLDataSource* source);
55
56  // Report that a request has resulted in the data |bytes|.
57  // If the request can't be satisfied, pass NULL for |bytes| to indicate
58  // the request is over.
59  virtual void SendResponse(int request_id, base::RefCountedMemory* bytes);
60
61  const std::string& source_name() const { return source_name_; }
62  URLDataSource* source() const { return source_.get(); }
63
64 protected:
65  virtual ~URLDataSourceImpl();
66
67 private:
68  friend class URLDataManager;
69  friend class URLDataManagerBackend;
70  friend class base::DeleteHelper<URLDataSourceImpl>;
71
72  // SendResponse invokes this on the IO thread. Notifies the backend to
73  // handle the actual work of sending the data.
74  virtual void SendResponseOnIOThread(
75      int request_id,
76      scoped_refptr<base::RefCountedMemory> bytes);
77
78  // The name of this source.
79  // E.g., for favicons, this could be "favicon", which results in paths for
80  // specific resources like "favicon/34" getting sent to this source.
81  const std::string source_name_;
82
83  // This field is set and maintained by URLDataManagerBackend. It is set when
84  // the DataSource is added, and unset if the DataSource is removed. A
85  // DataSource can be removed in two ways: the URLDataManagerBackend is
86  // deleted, or another DataSource is registered with the same name. backend_
87  // should only be accessed on the IO thread. This reference can't be via a
88  // scoped_refptr else there would be a cycle between the backend and data
89  // source.
90  URLDataManagerBackend* backend_;
91
92  scoped_ptr<URLDataSource> source_;
93};
94
95}  // namespace content
96
97#endif  // CONTENT_BROWSER_WEBUI_URL_DATA_SOURCE_IMPL_H_
98