| Index: ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.cc
|
| ===================================================================
|
| --- ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.cc (revision 0)
|
| +++ ppapi/native_client/src/shared/ppapi_proxy/plugin_resource_tracker.cc (revision 0)
|
| @@ -0,0 +1,101 @@
|
| +// Copyright (c) 2011 The Native Client Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "native_client/src/shared/ppapi_proxy/plugin_resource_tracker.h"
|
| +
|
| +#include <limits>
|
| +#include <set>
|
| +
|
| +#include "native_client/src/include/nacl_macros.h"
|
| +#include "native_client/src/include/portability.h"
|
| +#include "native_client/src/shared/ppapi_proxy/plugin_globals.h"
|
| +#include "native_client/src/shared/ppapi_proxy/plugin_resource.h"
|
| +#include "native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h"
|
| +#include "ppapi/c/pp_resource.h"
|
| +
|
| +namespace ppapi_proxy {
|
| +
|
| +PluginResourceTracker::ResourceAndRefCounts::ResourceAndRefCounts(
|
| + PluginResource* r, size_t browser_count)
|
| + : resource(r), browser_refcount(browser_count), plugin_refcount(1) {
|
| +}
|
| +
|
| +PluginResourceTracker::ResourceAndRefCounts::~ResourceAndRefCounts() {
|
| +}
|
| +
|
| +scoped_refptr<PluginResource> PluginResourceTracker::GetExistingResource(
|
| + PP_Resource res) const {
|
| + ResourceMap::const_iterator result = live_resources_.find(res);
|
| + if (result == live_resources_.end())
|
| + return scoped_refptr<PluginResource>();
|
| + else
|
| + return result->second.resource;
|
| +}
|
| +
|
| +PluginResourceTracker::PluginResourceTracker() {
|
| +}
|
| +
|
| +void PluginResourceTracker::AddResource(PluginResource* resource,
|
| + PP_Resource id,
|
| + size_t browser_refcount) {
|
| + // Add the resource with plugin use-count 1.
|
| + live_resources_.insert(
|
| + std::make_pair(id, ResourceAndRefCounts(resource, browser_refcount)));
|
| +}
|
| +
|
| +bool PluginResourceTracker::AddRefResource(PP_Resource res) {
|
| + ResourceMap::iterator i = live_resources_.find(res);
|
| + if (i == live_resources_.end()) {
|
| + return false;
|
| + } else {
|
| + // We don't protect against overflow, since a plugin as malicious as to ref
|
| + // once per every byte in the address space could have just as well unrefed
|
| + // one time too many.
|
| + i->second.plugin_refcount++;
|
| + if (i->second.browser_refcount == 0) {
|
| + // If we don't currently have any refcount with the browser, try to
|
| + // obtain one.
|
| + i->second.browser_refcount++;
|
| + ObtainBrowserResource(res);
|
| + }
|
| + return true;
|
| + }
|
| +}
|
| +
|
| +bool PluginResourceTracker::UnrefResource(PP_Resource res) {
|
| + ResourceMap::iterator i = live_resources_.find(res);
|
| + if (i != live_resources_.end()) {
|
| + i->second.plugin_refcount--;
|
| + if (0 == i->second.plugin_refcount) {
|
| + size_t browser_refcount = i->second.browser_refcount;
|
| + live_resources_.erase(i);
|
| +
|
| + // Release all browser references.
|
| + ReleaseBrowserResource(res, browser_refcount);
|
| + }
|
| + return true;
|
| + } else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +void PluginResourceTracker::ObtainBrowserResource(PP_Resource res) {
|
| + if (res) {
|
| + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
|
| + PpbCoreRpcClient::PPB_Core_AddRefResource(channel, res);
|
| + }
|
| +}
|
| +
|
| +void PluginResourceTracker::ReleaseBrowserResource(PP_Resource res,
|
| + size_t browser_refcount) {
|
| + // Release all browser references.
|
| + if (res && (browser_refcount > 0)) {
|
| + NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
|
| + PpbCoreRpcClient::ReleaseResourceMultipleTimes(channel, res,
|
| + browser_refcount);
|
| + }
|
| +}
|
| +
|
| +} // namespace ppapi_proxy
|
| +
|
|
|