OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include "chrome/browser/renderer_host/async_resource_handler.h" | 5 #include "chrome/browser/renderer_host/async_resource_handler.h" |
6 | 6 |
7 #include "base/process.h" | 7 #include "base/process.h" |
| 8 #include "net/base/io_buffer.h" |
8 | 9 |
9 base::SharedMemory* AsyncResourceHandler::spare_read_buffer_; | 10 SharedIOBuffer* AsyncResourceHandler::spare_read_buffer_; |
| 11 |
| 12 // Our version of IOBuffer that uses shared memory. |
| 13 class SharedIOBuffer : public net::IOBuffer { |
| 14 public: |
| 15 SharedIOBuffer(int buffer_size) : net::IOBuffer(NULL), ok_(false) { |
| 16 if (shared_memory_.Create(std::wstring(), false, false, buffer_size) && |
| 17 shared_memory_.Map(buffer_size)) { |
| 18 ok_ = true; |
| 19 data_ = reinterpret_cast<char*>(shared_memory_.memory()); |
| 20 } |
| 21 } |
| 22 ~SharedIOBuffer() { |
| 23 data_ = NULL; |
| 24 } |
| 25 |
| 26 base::SharedMemory* shared_memory() { return &shared_memory_; } |
| 27 bool ok() { return ok_; } |
| 28 |
| 29 private: |
| 30 base::SharedMemory shared_memory_; |
| 31 bool ok_; |
| 32 }; |
10 | 33 |
11 AsyncResourceHandler::AsyncResourceHandler( | 34 AsyncResourceHandler::AsyncResourceHandler( |
12 ResourceDispatcherHost::Receiver* receiver, | 35 ResourceDispatcherHost::Receiver* receiver, |
13 int render_process_host_id, | 36 int render_process_host_id, |
14 int routing_id, | 37 int routing_id, |
15 base::ProcessHandle render_process, | 38 base::ProcessHandle render_process, |
16 const GURL& url, | 39 const GURL& url, |
17 ResourceDispatcherHost* resource_dispatcher_host) | 40 ResourceDispatcherHost* resource_dispatcher_host) |
18 : receiver_(receiver), | 41 : receiver_(receiver), |
19 render_process_host_id_(render_process_host_id), | 42 render_process_host_id_(render_process_host_id), |
(...skipping 17 matching lines...) Expand all Loading... |
37 new_url)); | 60 new_url)); |
38 } | 61 } |
39 | 62 |
40 bool AsyncResourceHandler::OnResponseStarted(int request_id, | 63 bool AsyncResourceHandler::OnResponseStarted(int request_id, |
41 ResourceResponse* response) { | 64 ResourceResponse* response) { |
42 receiver_->Send(new ViewMsg_Resource_ReceivedResponse( | 65 receiver_->Send(new ViewMsg_Resource_ReceivedResponse( |
43 routing_id_, request_id, response->response_head)); | 66 routing_id_, request_id, response->response_head)); |
44 return true; | 67 return true; |
45 } | 68 } |
46 | 69 |
47 bool AsyncResourceHandler::OnWillRead(int request_id, | 70 bool AsyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, |
48 char** buf, int* buf_size, | 71 int* buf_size, int min_size) { |
49 int min_size) { | |
50 DCHECK(min_size == -1); | 72 DCHECK(min_size == -1); |
51 static const int kReadBufSize = 32768; | 73 static const int kReadBufSize = 32768; |
52 if (spare_read_buffer_) { | 74 if (spare_read_buffer_) { |
53 read_buffer_.reset(spare_read_buffer_); | 75 DCHECK(!read_buffer_); |
54 spare_read_buffer_ = NULL; | 76 read_buffer_.swap(&spare_read_buffer_); |
55 } else { | 77 } else { |
56 read_buffer_.reset(new base::SharedMemory); | 78 read_buffer_ = new SharedIOBuffer(kReadBufSize); |
57 if (!read_buffer_->Create(std::wstring(), false, false, kReadBufSize)) | 79 if (!read_buffer_->ok()) |
58 return false; | |
59 if (!read_buffer_->Map(kReadBufSize)) | |
60 return false; | 80 return false; |
61 } | 81 } |
62 *buf = static_cast<char*>(read_buffer_->memory()); | 82 *buf = read_buffer_.get(); |
63 *buf_size = kReadBufSize; | 83 *buf_size = kReadBufSize; |
64 return true; | 84 return true; |
65 } | 85 } |
66 | 86 |
67 bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { | 87 bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { |
68 if (!*bytes_read) | 88 if (!*bytes_read) |
69 return true; | 89 return true; |
70 DCHECK(read_buffer_.get()); | 90 DCHECK(read_buffer_.get()); |
71 | 91 |
72 if (!rdh_->WillSendData(render_process_host_id_, request_id)) { | 92 if (!rdh_->WillSendData(render_process_host_id_, request_id)) { |
73 // We should not send this data now, we have too many pending requests. | 93 // We should not send this data now, we have too many pending requests. |
74 return true; | 94 return true; |
75 } | 95 } |
76 | 96 |
77 base::SharedMemoryHandle handle; | 97 base::SharedMemoryHandle handle; |
78 if (!read_buffer_->GiveToProcess(render_process_, &handle)) { | 98 if (!read_buffer_->shared_memory()->GiveToProcess(render_process_, &handle)) { |
79 // We wrongfully incremented the pending data count. Fake an ACK message | 99 // We wrongfully incremented the pending data count. Fake an ACK message |
80 // to fix this. We can't move this call above the WillSendData because | 100 // to fix this. We can't move this call above the WillSendData because |
81 // it's killing our read_buffer_, and we don't want that when we pause | 101 // it's killing our read_buffer_, and we don't want that when we pause |
82 // the request. | 102 // the request. |
83 rdh_->OnDataReceivedACK(render_process_host_id_, request_id); | 103 rdh_->OnDataReceivedACK(render_process_host_id_, request_id); |
84 return false; | 104 return false; |
85 } | 105 } |
| 106 // We just unmapped the memory. |
| 107 read_buffer_ = NULL; |
86 | 108 |
87 receiver_->Send(new ViewMsg_Resource_DataReceived( | 109 receiver_->Send(new ViewMsg_Resource_DataReceived( |
88 routing_id_, request_id, handle, *bytes_read)); | 110 routing_id_, request_id, handle, *bytes_read)); |
89 | 111 |
90 return true; | 112 return true; |
91 } | 113 } |
92 | 114 |
93 bool AsyncResourceHandler::OnResponseCompleted(int request_id, | 115 bool AsyncResourceHandler::OnResponseCompleted(int request_id, |
94 const URLRequestStatus& status) { | 116 const URLRequestStatus& status) { |
95 receiver_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, | 117 receiver_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, |
96 request_id, status)); | 118 request_id, status)); |
97 | 119 |
98 // If we still have a read buffer, then see about caching it for later... | 120 // If we still have a read buffer, then see about caching it for later... |
99 if (spare_read_buffer_) { | 121 if (spare_read_buffer_) { |
100 read_buffer_.reset(); | 122 read_buffer_ = NULL; |
101 } else if (read_buffer_.get() && read_buffer_->memory()) { | 123 } else if (read_buffer_.get()) { |
102 spare_read_buffer_ = read_buffer_.release(); | 124 read_buffer_.swap(&spare_read_buffer_); |
103 } | 125 } |
104 return true; | 126 return true; |
105 } | 127 } |
106 | 128 |
107 // static | 129 // static |
108 void AsyncResourceHandler::GlobalCleanup() { | 130 void AsyncResourceHandler::GlobalCleanup() { |
109 delete spare_read_buffer_; | |
110 spare_read_buffer_ = NULL; | 131 spare_read_buffer_ = NULL; |
111 } | 132 } |
OLD | NEW |