1 // Copyright (c) 2012 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_LOADER_RESOURCE_SCHEDULER_H_ 6 #define CONTENT_BROWSER_LOADER_RESOURCE_SCHEDULER_H_ 7 8 #include <map> 9 #include <set> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/threading/non_thread_safe.h" 15 #include "content/common/content_export.h" 16 #include "net/base/priority_queue.h" 17 #include "net/base/request_priority.h" 18 19 namespace net { 20 class HostPortPair; 21 class URLRequest; 22 } 23 24 namespace content { 25 class ResourceThrottle; 26 27 // There is one ResourceScheduler. All renderer-initiated HTTP requests are 28 // expected to pass through it. 29 // 30 // There are two types of input to the scheduler: 31 // 1. Requests to start, cancel, or finish fetching a resource. 32 // 2. Notifications for renderer events, such as new tabs, navigation and 33 // painting. 34 // 35 // These input come from different threads, so they may not be in sync. The UI 36 // thread is considered the authority on renderer lifetime, which means some 37 // IPCs may be meaningless if they arrive after the UI thread signals a renderer 38 // has been deleted. 39 // 40 // The ResourceScheduler tracks many Clients, which should correlate with tabs. 41 // A client is uniquely identified by its child_id and route_id. 42 // 43 // Each Client may have many Requests in flight. Requests are uniquely 44 // identified within a Client by its ScheduledResourceRequest. 45 // 46 // Users should call ScheduleRequest() to notify this ResourceScheduler of a 47 // new request. The returned ResourceThrottle should be destroyed when the load 48 // finishes or is canceled. 49 // 50 // The scheduler may defer issuing the request via the ResourceThrottle 51 // interface or it may alter the request's priority by calling set_priority() on 52 // the URLRequest. 53 class CONTENT_EXPORT ResourceScheduler : public base::NonThreadSafe { 54 public: 55 ResourceScheduler(); 56 ~ResourceScheduler(); 57 58 // Requests that this ResourceScheduler schedule, and eventually loads, the 59 // specified |url_request|. Caller should delete the returned ResourceThrottle 60 // when the load completes or is canceled. 61 scoped_ptr<ResourceThrottle> ScheduleRequest( 62 int child_id, int route_id, net::URLRequest* url_request); 63 64 // Signals from the UI thread, posted as tasks on the IO thread: 65 66 // Called when a renderer is created. 67 void OnClientCreated(int child_id, int route_id); 68 69 // Called when a renderer is destroyed. 70 void OnClientDeleted(int child_id, int route_id); 71 72 // Signals from IPC messages directly from the renderers: 73 74 // Called when a client navigates to a new main document. 75 void OnNavigate(int child_id, int route_id); 76 77 // Called when the client has parsed the <body> element. This is a signal that 78 // resource loads won't interfere with first paint. 79 void OnWillInsertBody(int child_id, int route_id); 80 81 // Signals from the IO thread 82 83 // Called when we received a response to a http request that was served 84 // from a proxy using SPDY. 85 void OnReceivedSpdyProxiedHttpResponse(int child_id, int route_id); 86 87 private: 88 class RequestQueue; 89 class ScheduledResourceRequest; 90 struct RequestPriorityParams; 91 struct ScheduledResourceSorter { 92 bool operator()(const ScheduledResourceRequest* a, 93 const ScheduledResourceRequest* b) const; 94 }; 95 class Client; 96 97 typedef int64 ClientId; 98 typedef std::map<ClientId, Client*> ClientMap; 99 typedef std::set<ScheduledResourceRequest*> RequestSet; 100 101 // Called when a ScheduledResourceRequest is destroyed. 102 void RemoveRequest(ScheduledResourceRequest* request); 103 104 // Update the queue position for |request|, possibly causing it to start 105 // loading. 106 // 107 // Queues are maintained for each priority level. When |request| is 108 // reprioritized, it will move to the end of the queue for that priority 109 // level. 110 void ReprioritizeRequest(ScheduledResourceRequest* request, 111 net::RequestPriority new_priority, 112 int intra_priority_value); 113 114 // Returns the client ID for the given |child_id| and |route_id| combo. 115 ClientId MakeClientId(int child_id, int route_id); 116 117 ClientMap client_map_; 118 RequestSet unowned_requests_; 119 }; 120 121 } // namespace content 122 123 #endif // CONTENT_BROWSER_LOADER_RESOURCE_SCHEDULER_H_ 124