| Index: chrome/browser/renderer_host/browser_render_process_host.cc
|
| diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
|
| index eda2f1a226f5114b4ee7186952d68ca553aae855..d17ab8355a423111fee2578541d439174d9ce307 100644
|
| --- a/chrome/browser/renderer_host/browser_render_process_host.cc
|
| +++ b/chrome/browser/renderer_host/browser_render_process_host.cc
|
| @@ -128,7 +128,10 @@ void BrowserRenderProcessHost::RegisterPrefs(PrefService* prefs) {
|
| BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile)
|
| : RenderProcessHost(profile),
|
| visible_widgets_(0),
|
| - backgrounded_(true) {
|
| + backgrounded_(true),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_(
|
| + base::TimeDelta::FromSeconds(5),
|
| + this, &BrowserRenderProcessHost::ClearTransportDIBCache)) {
|
| DCHECK(host_id() >= 0); // We use a negative host_id_ in destruction.
|
| widget_helper_ = new RenderWidgetHelper(host_id());
|
|
|
| @@ -170,6 +173,8 @@ BrowserRenderProcessHost::~BrowserRenderProcessHost() {
|
|
|
| NotificationService::current()->RemoveObserver(this,
|
| NotificationType::USER_SCRIPTS_LOADED, NotificationService::AllSources());
|
| +
|
| + ClearTransportDIBCache();
|
| }
|
|
|
| // When we're started with the --start-renderers-manually flag, we pop up a
|
| @@ -605,6 +610,65 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() {
|
| return true;
|
| }
|
|
|
| +// This is a platform specific function for mapping a transport DIB given its id
|
| +TransportDIB* BrowserRenderProcessHost::MapTransportDIB(
|
| + TransportDIB::Id dib_id) {
|
| +#if defined(OS_WIN)
|
| + // On Windows we need to duplicate the handle from the remote process
|
| + HANDLE section = win_util::GetSectionFromProcess(
|
| + dib_id.handle, GetRendererProcessHandle(), false /* read write */);
|
| + return TransportDIB::Map(section);
|
| +#elif defined(OS_MACOSX)
|
| + // On OSX, the browser allocates all DIBs and keeps a file descriptor around
|
| + // for each.
|
| + return widget_helper_->MapTransportDIB(dib_id);
|
| +#elif defined(OS_LINUX)
|
| + return TransportDIB::Map(dib_id);
|
| +#endif // defined(OS_LINUX)
|
| +}
|
| +
|
| +TransportDIB* BrowserRenderProcessHost::GetTransportDIB(
|
| + TransportDIB::Id dib_id) {
|
| + const std::map<TransportDIB::Id, TransportDIB*>::iterator
|
| + i = cached_dibs_.find(dib_id);
|
| + if (i != cached_dibs_.end()) {
|
| + cached_dibs_cleaner_.Reset();
|
| + return i->second;
|
| + }
|
| +
|
| + TransportDIB* dib = MapTransportDIB(dib_id);
|
| + if (!dib)
|
| + return NULL;
|
| +
|
| + if (cached_dibs_.size() >= MAX_MAPPED_TRANSPORT_DIBS) {
|
| + // Clean a single entry from the cache
|
| + std::map<TransportDIB::Id, TransportDIB*>::iterator smallest_iterator;
|
| + size_t smallest_size = std::numeric_limits<size_t>::max();
|
| +
|
| + for (std::map<TransportDIB::Id, TransportDIB*>::iterator
|
| + i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) {
|
| + if (i->second->size() <= smallest_size)
|
| + smallest_iterator = i;
|
| + }
|
| +
|
| + delete smallest_iterator->second;
|
| + cached_dibs_.erase(smallest_iterator);
|
| + }
|
| +
|
| + cached_dibs_[dib_id] = dib;
|
| + cached_dibs_cleaner_.Reset();
|
| + return dib;
|
| +}
|
| +
|
| +void BrowserRenderProcessHost::ClearTransportDIBCache() {
|
| + for (std::map<TransportDIB::Id, TransportDIB*>::iterator
|
| + i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) {
|
| + delete i->second;
|
| + }
|
| +
|
| + cached_dibs_.clear();
|
| +}
|
| +
|
| bool BrowserRenderProcessHost::Send(IPC::Message* msg) {
|
| if (!channel_.get()) {
|
| delete msg;
|
|
|