| 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 read_buffer_ = spare_read_buffer_; |
| 54 spare_read_buffer_ = NULL; | 76 spare_read_buffer_ = NULL; |
| 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 } |
| 86 | 106 |
| 87 receiver_->Send(new ViewMsg_Resource_DataReceived( | 107 receiver_->Send(new ViewMsg_Resource_DataReceived( |
| 88 routing_id_, request_id, handle, *bytes_read)); | 108 routing_id_, request_id, handle, *bytes_read)); |
| 89 | 109 |
| 90 return true; | 110 return true; |
| 91 } | 111 } |
| 92 | 112 |
| 93 bool AsyncResourceHandler::OnResponseCompleted(int request_id, | 113 bool AsyncResourceHandler::OnResponseCompleted(int request_id, |
| 94 const URLRequestStatus& status) { | 114 const URLRequestStatus& status) { |
| 95 receiver_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, | 115 receiver_->Send(new ViewMsg_Resource_RequestComplete(routing_id_, |
| 96 request_id, status)); | 116 request_id, status)); |
| 97 | 117 |
| 98 // If we still have a read buffer, then see about caching it for later... | 118 // If we still have a read buffer, then see about caching it for later... |
| 99 if (spare_read_buffer_) { | 119 if (spare_read_buffer_) { |
| 100 read_buffer_.reset(); | 120 read_buffer_ = NULL; |
| 101 } else if (read_buffer_.get() && read_buffer_->memory()) { | 121 } else if (read_buffer_.get() && read_buffer_->data()) { |
| 102 spare_read_buffer_ = read_buffer_.release(); | 122 read_buffer_.swap(&spare_read_buffer_); |
| 103 } | 123 } |
| 104 return true; | 124 return true; |
| 105 } | 125 } |
| 106 | 126 |
| 107 // static | 127 // static |
| 108 void AsyncResourceHandler::GlobalCleanup() { | 128 void AsyncResourceHandler::GlobalCleanup() { |
| 109 delete spare_read_buffer_; | |
| 110 spare_read_buffer_ = NULL; | 129 spare_read_buffer_ = NULL; |
| 111 } | 130 } |
| OLD | NEW |