12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CONTENT_BROWSER_WEBUI_URL_DATA_SOURCE_IMPL_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CONTENT_BROWSER_WEBUI_URL_DATA_SOURCE_IMPL_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner_helpers.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/url_data_manager.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base { 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RefCountedMemory; 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLDataManagerBackend; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLDataSource; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLDataSourceImpl; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Trait used to handle deleting a URLDataSource. Deletion happens on the UI 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// thread. 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation note: the normal shutdown sequence is for the UI loop to 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// stop pumping events then the IO loop and thread are stopped. When the 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// URLDataSources are no longer referenced (which happens when IO thread stops) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// they get added to the UI message loop for deletion. But because the UI loop 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// has stopped by the time this happens the URLDataSources would be leaked. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To make sure URLDataSources are properly deleted URLDataManager manages 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// deletion of the URLDataSources. When a URLDataSource is no longer referenced 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it is added to |data_sources_| and a task is posted to the UI thread to 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// handle the actual deletion. During shutdown |DeleteDataSources| is invoked so 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that all pending URLDataSources are properly deleted. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DeleteURLDataSource { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void Destruct(const URLDataSourceImpl* data_source) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataManager::DeleteDataSource(data_source); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A URLDataSource is an object that can answer requests for data 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// asynchronously. URLDataSources are collectively owned with refcounting smart 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pointers and should never be deleted on the IO thread, since their calls 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// are handled almost always on the UI thread and there's a possibility of a 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// data race. The |DeleteDataSource| trait above is used to enforce this. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLDataSourceImpl : public base::RefCountedThreadSafe< 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSourceImpl, DeleteURLDataSource> { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See source_name_ below for docs on that parameter. Takes ownership of 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |source|. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSourceImpl(const std::string& source_name, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSource* source); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Report that a request has resulted in the data |bytes|. 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the request can't be satisfied, pass NULL for |bytes| to indicate 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the request is over. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SendResponse(int request_id, base::RefCountedMemory* bytes); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& source_name() const { return source_name_; } 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSource* source() const { return source_.get(); } 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~URLDataSourceImpl(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class URLDataManager; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class URLDataManagerBackend; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::DeleteHelper<URLDataSourceImpl>; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // SendResponse invokes this on the IO thread. Notifies the backend to 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // handle the actual work of sending the data. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SendResponseOnIOThread( 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedMemory> bytes); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The name of this source. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // E.g., for favicons, this could be "favicon", which results in paths for 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // specific resources like "favicon/34" getting sent to this source. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string source_name_; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This field is set and maintained by URLDataManagerBackend. It is set when 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the DataSource is added, and unset if the DataSource is removed. A 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DataSource can be removed in two ways: the URLDataManagerBackend is 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // deleted, or another DataSource is registered with the same name. backend_ 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should only be accessed on the IO thread. This reference can't be via a 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // scoped_refptr else there would be a cycle between the backend and data 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // source. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataManagerBackend* backend_; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<URLDataSource> source_; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CONTENT_BROWSER_WEBUI_URL_DATA_SOURCE_IMPL_H_ 98