OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading |
6 | 6 |
7 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 7 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 #include <vector> | 10 #include <vector> |
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 // in the order in which they occur during the lifetime of a request, so we can | 1823 // in the order in which they occur during the lifetime of a request, so we can |
1824 // regard states with larger numeric values as being further along toward | 1824 // regard states with larger numeric values as being further along toward |
1825 // completion. We regard those states as more interesting to report since they | 1825 // completion. We regard those states as more interesting to report since they |
1826 // represent progress. | 1826 // represent progress. |
1827 // | 1827 // |
1828 // For example, by this measure "tranferring data" is a more interesting state | 1828 // For example, by this measure "tranferring data" is a more interesting state |
1829 // than "resolving host" because when we are transferring data we are actually | 1829 // than "resolving host" because when we are transferring data we are actually |
1830 // doing something that corresponds to changes that the user might observe, | 1830 // doing something that corresponds to changes that the user might observe, |
1831 // whereas waiting for a host name to resolve implies being stuck. | 1831 // whereas waiting for a host name to resolve implies being stuck. |
1832 // | 1832 // |
1833 net::LoadState MoreInterestingLoadState(net::LoadState a, net::LoadState b) { | 1833 const net::LoadStateWithParam& MoreInterestingLoadState( |
1834 return (a < b) ? b : a; | 1834 const net::LoadStateWithParam& a, const net::LoadStateWithParam& b) { |
| 1835 return (a.state < b.state) ? b : a; |
1835 } | 1836 } |
1836 | 1837 |
1837 // Carries information about a load state change. | 1838 // Carries information about a load state change. |
1838 struct LoadInfo { | 1839 struct LoadInfo { |
1839 GURL url; | 1840 GURL url; |
1840 net::LoadState load_state; | 1841 net::LoadStateWithParam load_state; |
1841 uint64 upload_position; | 1842 uint64 upload_position; |
1842 uint64 upload_size; | 1843 uint64 upload_size; |
1843 }; | 1844 }; |
1844 | 1845 |
1845 // Map from ProcessID+ViewID pair to LoadState | 1846 // Map from ProcessID+ViewID pair to LoadState |
1846 typedef std::map<std::pair<int, int>, LoadInfo> LoadInfoMap; | 1847 typedef std::map<std::pair<int, int>, LoadInfo> LoadInfoMap; |
1847 | 1848 |
1848 // Used to marshall calls to LoadStateChanged from the IO to UI threads. We do | 1849 // Used to marshall calls to LoadStateChanged from the IO to UI threads. We do |
1849 // them all as a single task to avoid spamming the UI thread. | 1850 // them all as a single task to avoid spamming the UI thread. |
1850 class LoadInfoUpdateTask : public Task { | 1851 class LoadInfoUpdateTask : public Task { |
(...skipping 21 matching lines...) Expand all Loading... |
1872 | 1873 |
1873 PendingRequestList::const_iterator i; | 1874 PendingRequestList::const_iterator i; |
1874 | 1875 |
1875 // Determine the largest upload size of all requests | 1876 // Determine the largest upload size of all requests |
1876 // in each View (good chance it's zero). | 1877 // in each View (good chance it's zero). |
1877 std::map<std::pair<int, int>, uint64> largest_upload_size; | 1878 std::map<std::pair<int, int>, uint64> largest_upload_size; |
1878 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) { | 1879 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) { |
1879 net::URLRequest* request = i->second; | 1880 net::URLRequest* request = i->second; |
1880 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); | 1881 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
1881 uint64 upload_size = info->upload_size(); | 1882 uint64 upload_size = info->upload_size(); |
1882 if (request->GetLoadState() != net::LOAD_STATE_SENDING_REQUEST) | 1883 if (request->GetLoadState().state != net::LOAD_STATE_SENDING_REQUEST) |
1883 upload_size = 0; | 1884 upload_size = 0; |
1884 std::pair<int, int> key(info->child_id(), info->route_id()); | 1885 std::pair<int, int> key(info->child_id(), info->route_id()); |
1885 if (upload_size && largest_upload_size[key] < upload_size) | 1886 if (upload_size && largest_upload_size[key] < upload_size) |
1886 largest_upload_size[key] = upload_size; | 1887 largest_upload_size[key] = upload_size; |
1887 } | 1888 } |
1888 | 1889 |
1889 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) { | 1890 for (i = pending_requests_.begin(); i != pending_requests_.end(); ++i) { |
1890 net::URLRequest* request = i->second; | 1891 net::URLRequest* request = i->second; |
1891 net::LoadState load_state = request->GetLoadState(); | 1892 net::LoadStateWithParam load_state = request->GetLoadState(); |
1892 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); | 1893 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); |
| 1894 std::pair<int, int> key(info->child_id(), info->route_id()); |
1893 | 1895 |
1894 // We also poll for upload progress on this timer and send upload | 1896 // We also poll for upload progress on this timer and send upload |
1895 // progress ipc messages to the plugin process. | 1897 // progress ipc messages to the plugin process. |
1896 bool update_upload_progress = MaybeUpdateUploadProgress(info, request); | 1898 MaybeUpdateUploadProgress(info, request); |
1897 | 1899 |
1898 if (info->last_load_state() != load_state || update_upload_progress) { | 1900 // If a request is uploading data, ignore all other requests so that the |
1899 std::pair<int, int> key(info->child_id(), info->route_id()); | 1901 // upload progress takes priority for being shown in the status bar. |
| 1902 if (largest_upload_size.find(key) != largest_upload_size.end() && |
| 1903 info->upload_size() < largest_upload_size[key]) |
| 1904 continue; |
1900 | 1905 |
1901 // If a request is uploading data, ignore all other requests so that the | 1906 net::LoadStateWithParam to_insert = load_state; |
1902 // upload progress takes priority for being shown in the status bar. | 1907 LoadInfoMap::iterator existing = info_map.find(key); |
1903 if (largest_upload_size.find(key) != largest_upload_size.end() && | 1908 if (existing != info_map.end()) { |
1904 info->upload_size() < largest_upload_size[key]) | 1909 to_insert = |
| 1910 MoreInterestingLoadState(existing->second.load_state, load_state); |
| 1911 if (to_insert.state == existing->second.load_state.state) |
1905 continue; | 1912 continue; |
1906 | |
1907 info->set_last_load_state(load_state); | |
1908 | |
1909 net::LoadState to_insert; | |
1910 LoadInfoMap::iterator existing = info_map.find(key); | |
1911 if (existing == info_map.end()) { | |
1912 to_insert = load_state; | |
1913 } else { | |
1914 to_insert = | |
1915 MoreInterestingLoadState(existing->second.load_state, load_state); | |
1916 if (to_insert == existing->second.load_state) | |
1917 continue; | |
1918 } | |
1919 LoadInfo& load_info = info_map[key]; | |
1920 load_info.url = request->url(); | |
1921 load_info.load_state = to_insert; | |
1922 load_info.upload_size = info->upload_size(); | |
1923 load_info.upload_position = request->GetUploadProgress(); | |
1924 } | 1913 } |
| 1914 LoadInfo& load_info = info_map[key]; |
| 1915 load_info.url = request->url(); |
| 1916 load_info.load_state = to_insert; |
| 1917 load_info.upload_size = info->upload_size(); |
| 1918 load_info.upload_position = request->GetUploadProgress(); |
1925 } | 1919 } |
1926 | 1920 |
1927 if (info_map.empty()) | 1921 if (info_map.empty()) |
1928 return; | 1922 return; |
1929 | 1923 |
1930 LoadInfoUpdateTask* task = new LoadInfoUpdateTask; | 1924 LoadInfoUpdateTask* task = new LoadInfoUpdateTask; |
1931 task->info_map.swap(info_map); | 1925 task->info_map.swap(info_map); |
1932 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, task); | 1926 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, task); |
1933 } | 1927 } |
1934 | 1928 |
1935 // Calls the ResourceHandler to send upload progress messages to the renderer. | 1929 // Calls the ResourceHandler to send upload progress messages to the renderer. |
1936 // Returns true iff an upload progress message should be sent to the UI thread. | 1930 void ResourceDispatcherHost::MaybeUpdateUploadProgress( |
1937 bool ResourceDispatcherHost::MaybeUpdateUploadProgress( | |
1938 ResourceDispatcherHostRequestInfo *info, | 1931 ResourceDispatcherHostRequestInfo *info, |
1939 net::URLRequest *request) { | 1932 net::URLRequest *request) { |
1940 | 1933 |
1941 if (!info->upload_size() || info->waiting_for_upload_progress_ack()) | 1934 if (!info->upload_size() || info->waiting_for_upload_progress_ack()) |
1942 return false; | 1935 return; |
1943 | 1936 |
1944 uint64 size = info->upload_size(); | 1937 uint64 size = info->upload_size(); |
1945 uint64 position = request->GetUploadProgress(); | 1938 uint64 position = request->GetUploadProgress(); |
1946 if (position == info->last_upload_position()) | 1939 if (position == info->last_upload_position()) |
1947 return false; // no progress made since last time | 1940 return; // no progress made since last time |
1948 | 1941 |
1949 const uint64 kHalfPercentIncrements = 200; | 1942 const uint64 kHalfPercentIncrements = 200; |
1950 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); | 1943 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); |
1951 | 1944 |
1952 uint64 amt_since_last = position - info->last_upload_position(); | 1945 uint64 amt_since_last = position - info->last_upload_position(); |
1953 TimeDelta time_since_last = TimeTicks::Now() - info->last_upload_ticks(); | 1946 TimeDelta time_since_last = TimeTicks::Now() - info->last_upload_ticks(); |
1954 | 1947 |
1955 bool is_finished = (size == position); | 1948 bool is_finished = (size == position); |
1956 bool enough_new_progress = (amt_since_last > (size / kHalfPercentIncrements)); | 1949 bool enough_new_progress = (amt_since_last > (size / kHalfPercentIncrements)); |
1957 bool too_much_time_passed = time_since_last > kOneSecond; | 1950 bool too_much_time_passed = time_since_last > kOneSecond; |
1958 | 1951 |
1959 if (is_finished || enough_new_progress || too_much_time_passed) { | 1952 if (is_finished || enough_new_progress || too_much_time_passed) { |
1960 if (request->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) { | 1953 if (request->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) { |
1961 info->resource_handler()->OnUploadProgress(info->request_id(), | 1954 info->resource_handler()->OnUploadProgress(info->request_id(), |
1962 position, size); | 1955 position, size); |
1963 info->set_waiting_for_upload_progress_ack(true); | 1956 info->set_waiting_for_upload_progress_ack(true); |
1964 } | 1957 } |
1965 info->set_last_upload_ticks(TimeTicks::Now()); | 1958 info->set_last_upload_ticks(TimeTicks::Now()); |
1966 info->set_last_upload_position(position); | 1959 info->set_last_upload_position(position); |
1967 return true; | |
1968 } | 1960 } |
1969 return false; | |
1970 } | 1961 } |
1971 | 1962 |
1972 void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) { | 1963 void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) { |
1973 std::pair<int, int> key(child_id, route_id); | 1964 std::pair<int, int> key(child_id, route_id); |
1974 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << | 1965 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << |
1975 "BlockRequestsForRoute called multiple time for the same RVH"; | 1966 "BlockRequestsForRoute called multiple time for the same RVH"; |
1976 blocked_requests_map_[key] = new BlockedRequestsList(); | 1967 blocked_requests_map_[key] = new BlockedRequestsList(); |
1977 } | 1968 } |
1978 | 1969 |
1979 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(int child_id, | 1970 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(int child_id, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2125 return HTTP_AUTH_RESOURCE_BLOCKED_CROSS; | 2116 return HTTP_AUTH_RESOURCE_BLOCKED_CROSS; |
2126 } | 2117 } |
2127 | 2118 |
2128 bool ResourceDispatcherHost::allow_cross_origin_auth_prompt() { | 2119 bool ResourceDispatcherHost::allow_cross_origin_auth_prompt() { |
2129 return allow_cross_origin_auth_prompt_; | 2120 return allow_cross_origin_auth_prompt_; |
2130 } | 2121 } |
2131 | 2122 |
2132 void ResourceDispatcherHost::set_allow_cross_origin_auth_prompt(bool value) { | 2123 void ResourceDispatcherHost::set_allow_cross_origin_auth_prompt(bool value) { |
2133 allow_cross_origin_auth_prompt_ = value; | 2124 allow_cross_origin_auth_prompt_ = value; |
2134 } | 2125 } |
OLD | NEW |