diff options
author | neb@chromium.org <neb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-20 21:01:10 +0000 |
---|---|---|
committer | neb@chromium.org <neb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-20 21:01:10 +0000 |
commit | 6205759e4ec4bf1d9e85049cc1cc90d76c916283 (patch) | |
tree | 6fd797237c6f8ee0bc532747af2e004b2ca3a865 | |
parent | 92a9c68ab835fd2148a8cce64db74dd20e01e9dd (diff) | |
download | chromium_src-6205759e4ec4bf1d9e85049cc1cc90d76c916283.zip chromium_src-6205759e4ec4bf1d9e85049cc1cc90d76c916283.tar.gz chromium_src-6205759e4ec4bf1d9e85049cc1cc90d76c916283.tar.bz2 |
De-coupled resource references by plugin from Resource object's refcount. Made so that ResourceTracker keeps the refs-by-plugin count, and when the ppapi plugin releases the last reference, it UnRefs the resource.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/2871027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@53098 0039d316-1c4b-4281-b951-d872f2087c98
19 files changed, 220 insertions, 194 deletions
diff --git a/webkit/glue/plugins/pepper_buffer.cc b/webkit/glue/plugins/pepper_buffer.cc index 4d94975..1c0bdd8 100644 --- a/webkit/glue/plugins/pepper_buffer.cc +++ b/webkit/glue/plugins/pepper_buffer.cc @@ -27,18 +27,17 @@ PP_Resource Create(PP_Module module_id, int32_t size) { scoped_refptr<Buffer> buffer(new Buffer(module)); if (!buffer->Init(size)) return NULL; - buffer->AddRef(); // AddRef for the caller. - return buffer->GetResource(); + return buffer->GetReference(); } bool IsBuffer(PP_Resource resource) { - return !!Resource::GetAs<Buffer>(resource).get(); + return !!Resource::GetAs<Buffer>(resource); } bool Describe(PP_Resource resource, int32_t* size_in_bytes) { scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(resource)); - if (!buffer.get()) + if (!buffer) return false; buffer->Describe(size_in_bytes); return true; @@ -46,7 +45,7 @@ bool Describe(PP_Resource resource, int32_t* size_in_bytes) { void* Map(PP_Resource resource) { scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(resource)); - if (!buffer.get()) + if (!buffer) return NULL; return buffer->Map(); } diff --git a/webkit/glue/plugins/pepper_device_context_2d.cc b/webkit/glue/plugins/pepper_device_context_2d.cc index 4f77751d..45ed9ee 100644 --- a/webkit/glue/plugins/pepper_device_context_2d.cc +++ b/webkit/glue/plugins/pepper_device_context_2d.cc @@ -73,14 +73,11 @@ PP_Resource Create(PP_Module module_id, scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module)); if (!context->Init(size->width, size->height, is_always_opaque)) return NULL; - context->AddRef(); // AddRef for the caller. - return context->GetResource(); + return context->GetReference(); } bool IsDeviceContext2D(PP_Resource resource) { - scoped_refptr<DeviceContext2D> context( - Resource::GetAs<DeviceContext2D>(resource)); - return !!context.get(); + return !!Resource::GetAs<DeviceContext2D>(resource); } bool Describe(PP_Resource device_context, @@ -88,7 +85,7 @@ bool Describe(PP_Resource device_context, bool* is_always_opaque) { scoped_refptr<DeviceContext2D> context( Resource::GetAs<DeviceContext2D>(device_context)); - if (!context.get()) + if (!context) return false; return context->Describe(size, is_always_opaque); } @@ -99,7 +96,7 @@ bool PaintImageData(PP_Resource device_context, const PP_Rect* src_rect) { scoped_refptr<DeviceContext2D> context( Resource::GetAs<DeviceContext2D>(device_context)); - if (!context.get()) + if (!context) return false; return context->PaintImageData(image, top_left, src_rect); } @@ -109,7 +106,7 @@ bool Scroll(PP_Resource device_context, const PP_Point* amount) { scoped_refptr<DeviceContext2D> context( Resource::GetAs<DeviceContext2D>(device_context)); - if (!context.get()) + if (!context) return false; return context->Scroll(clip_rect, amount); } @@ -117,7 +114,7 @@ bool Scroll(PP_Resource device_context, bool ReplaceContents(PP_Resource device_context, PP_Resource image) { scoped_refptr<DeviceContext2D> context( Resource::GetAs<DeviceContext2D>(device_context)); - if (!context.get()) + if (!context) return false; return context->ReplaceContents(image); } @@ -126,7 +123,7 @@ int32_t Flush(PP_Resource device_context, PP_CompletionCallback callback) { scoped_refptr<DeviceContext2D> context( Resource::GetAs<DeviceContext2D>(device_context)); - if (!context.get()) + if (!context) return PP_ERROR_BADRESOURCE; return context->Flush(callback); } @@ -214,7 +211,7 @@ bool DeviceContext2D::PaintImageData(PP_Resource image, return false; scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); - if (!image_resource.get()) + if (!image_resource) return false; QueuedOperation operation(QueuedOperation::PAINT); @@ -269,7 +266,7 @@ bool DeviceContext2D::Scroll(const PP_Rect* clip_rect, bool DeviceContext2D::ReplaceContents(PP_Resource image) { scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); - if (!image_resource.get()) + if (!image_resource) return false; if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) return false; @@ -301,7 +298,7 @@ int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) { gfx::Rect op_rect; switch (operation.type) { case QueuedOperation::PAINT: - ExecutePaintImageData(operation.paint_image.get(), + ExecutePaintImageData(operation.paint_image, operation.paint_x, operation.paint_y, operation.paint_src_rect, &op_rect); @@ -312,7 +309,7 @@ int32_t DeviceContext2D::Flush(const PP_CompletionCallback& callback) { &op_rect); break; case QueuedOperation::REPLACE: - ExecuteReplaceContents(operation.replace_image.get(), &op_rect); + ExecuteReplaceContents(operation.replace_image, &op_rect); break; } changed_rect = changed_rect.Union(op_rect); @@ -343,7 +340,7 @@ bool DeviceContext2D::ReadImageData(PP_Resource image, const PP_Point* top_left) { // Get and validate the image object to paint into. scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); - if (!image_resource.get()) + if (!image_resource) return false; if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) return false; // Must be in the right format. @@ -360,7 +357,7 @@ bool DeviceContext2D::ReadImageData(PP_Resource image, image_data_->height()) return false; - ImageDataAutoMapper auto_mapper(image_resource.get()); + ImageDataAutoMapper auto_mapper(image_resource); if (!auto_mapper.is_valid()) return false; skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); diff --git a/webkit/glue/plugins/pepper_directory_reader.cc b/webkit/glue/plugins/pepper_directory_reader.cc index f575e2c..93f19eef 100644 --- a/webkit/glue/plugins/pepper_directory_reader.cc +++ b/webkit/glue/plugins/pepper_directory_reader.cc @@ -17,16 +17,15 @@ namespace { PP_Resource Create(PP_Resource directory_ref_id) { scoped_refptr<FileRef> directory_ref( Resource::GetAs<FileRef>(directory_ref_id)); - if (!directory_ref.get()) + if (!directory_ref) return 0; DirectoryReader* reader = new DirectoryReader(directory_ref); - reader->AddRef(); // AddRef for the caller; - return reader->GetResource(); + return reader->GetReference(); } bool IsDirectoryReader(PP_Resource resource) { - return !!Resource::GetAs<DirectoryReader>(resource).get(); + return !!Resource::GetAs<DirectoryReader>(resource); } int32_t GetNextEntry(PP_Resource reader_id, @@ -34,7 +33,7 @@ int32_t GetNextEntry(PP_Resource reader_id, PP_CompletionCallback callback) { scoped_refptr<DirectoryReader> reader( Resource::GetAs<DirectoryReader>(reader_id)); - if (!reader.get()) + if (!reader) return PP_ERROR_BADRESOURCE; return reader->GetNextEntry(entry, callback); diff --git a/webkit/glue/plugins/pepper_file_chooser.cc b/webkit/glue/plugins/pepper_file_chooser.cc index 6c4c72a..5e45600 100644 --- a/webkit/glue/plugins/pepper_file_chooser.cc +++ b/webkit/glue/plugins/pepper_file_chooser.cc @@ -22,18 +22,17 @@ PP_Resource Create(PP_Instance instance_id, return 0; FileChooser* chooser = new FileChooser(instance, options); - chooser->AddRef(); // AddRef for the caller. - return chooser->GetResource(); + return chooser->GetReference(); } bool IsFileChooser(PP_Resource resource) { - return !!Resource::GetAs<FileChooser>(resource).get(); + return !!Resource::GetAs<FileChooser>(resource); } int32_t Show(PP_Resource chooser_id, PP_CompletionCallback callback) { scoped_refptr<FileChooser> chooser( - Resource::GetAs<FileChooser>(chooser_id).get()); - if (!chooser.get()) + Resource::GetAs<FileChooser>(chooser_id)); + if (!chooser) return PP_ERROR_BADRESOURCE; return chooser->Show(callback); @@ -41,16 +40,15 @@ int32_t Show(PP_Resource chooser_id, PP_CompletionCallback callback) { PP_Resource GetNextChosenFile(PP_Resource chooser_id) { scoped_refptr<FileChooser> chooser( - Resource::GetAs<FileChooser>(chooser_id).get()); - if (!chooser.get()) + Resource::GetAs<FileChooser>(chooser_id)); + if (!chooser) return 0; scoped_refptr<FileRef> file_ref(chooser->GetNextChosenFile()); - if (!file_ref.get()) + if (!file_ref) return 0; - file_ref->AddRef(); // AddRef for the caller. - return file_ref->GetResource(); + return file_ref->GetReference(); } const PPB_FileChooser ppb_filechooser = { diff --git a/webkit/glue/plugins/pepper_file_io.cc b/webkit/glue/plugins/pepper_file_io.cc index 7100c1f..46f7276 100644 --- a/webkit/glue/plugins/pepper_file_io.cc +++ b/webkit/glue/plugins/pepper_file_io.cc @@ -23,12 +23,11 @@ PP_Resource Create(PP_Module module_id) { return 0; FileIO* file_io = new FileIO(module); - file_io->AddRef(); // AddRef for the caller. - return file_io->GetResource(); + return file_io->GetReference(); } bool IsFileIO(PP_Resource resource) { - return !!Resource::GetAs<FileIO>(resource).get(); + return !!Resource::GetAs<FileIO>(resource); } int32_t Open(PP_Resource file_io_id, @@ -36,11 +35,11 @@ int32_t Open(PP_Resource file_io_id, int32_t open_flags, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref.get()) + if (!file_ref) return PP_ERROR_BADRESOURCE; return file_io->Open(file_ref, open_flags, callback); @@ -50,7 +49,7 @@ int32_t Query(PP_Resource file_io_id, PP_FileInfo* info, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Query(info, callback); @@ -61,7 +60,7 @@ int32_t Touch(PP_Resource file_io_id, PP_Time last_modified_time, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Touch(last_access_time, last_modified_time, callback); @@ -73,7 +72,7 @@ int32_t Read(PP_Resource file_io_id, int32_t bytes_to_read, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Read(offset, buffer, bytes_to_read, callback); @@ -85,7 +84,7 @@ int32_t Write(PP_Resource file_io_id, int32_t bytes_to_write, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Write(offset, buffer, bytes_to_write, callback); @@ -95,7 +94,7 @@ int32_t SetLength(PP_Resource file_io_id, int64_t length, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->SetLength(length, callback); @@ -104,7 +103,7 @@ int32_t SetLength(PP_Resource file_io_id, int32_t Flush(PP_Resource file_io_id, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->Flush(callback); @@ -112,7 +111,7 @@ int32_t Flush(PP_Resource file_io_id, void Close(PP_Resource file_io_id) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return; file_io->Close(); @@ -133,7 +132,7 @@ const PPB_FileIO ppb_fileio = { int32_t GetOSFileDescriptor(PP_Resource file_io_id) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->GetOSFileDescriptor(); @@ -144,7 +143,7 @@ int32_t WillWrite(PP_Resource file_io_id, int32_t bytes_to_write, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->WillWrite(offset, bytes_to_write, callback); @@ -154,7 +153,7 @@ int32_t WillSetLength(PP_Resource file_io_id, int64_t length, PP_CompletionCallback callback) { scoped_refptr<FileIO> file_io(Resource::GetAs<FileIO>(file_io_id)); - if (!file_io.get()) + if (!file_io) return PP_ERROR_BADRESOURCE; return file_io->WillSetLength(length, callback); diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc index 63563a1..9b42cff 100644 --- a/webkit/glue/plugins/pepper_file_ref.cc +++ b/webkit/glue/plugins/pepper_file_ref.cc @@ -50,8 +50,7 @@ PP_Resource CreateFileRef(PP_Instance instance_id, fs_type, validated_path, origin); - file_ref->AddRef(); // AddRef for the caller. - return file_ref->GetResource(); + return file_ref->GetReference(); } PP_Resource CreatePersistentFileRef(PP_Instance instance_id, const char* path) { @@ -63,12 +62,12 @@ PP_Resource CreateTemporaryFileRef(PP_Instance instance_id, const char* path) { } bool IsFileRef(PP_Resource resource) { - return !!Resource::GetAs<FileRef>(resource).get(); + return !!Resource::GetAs<FileRef>(resource); } PP_FileSystemType GetFileSystemType(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref.get()) + if (!file_ref) return PP_FILESYSTEMTYPE_EXTERNAL; return file_ref->file_system_type(); @@ -76,7 +75,7 @@ PP_FileSystemType GetFileSystemType(PP_Resource file_ref_id) { PP_Var GetName(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref.get()) + if (!file_ref) return PP_MakeVoid(); return StringToPPVar(file_ref->GetName()); @@ -84,7 +83,7 @@ PP_Var GetName(PP_Resource file_ref_id) { PP_Var GetPath(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref.get()) + if (!file_ref) return PP_MakeVoid(); if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) @@ -95,18 +94,17 @@ PP_Var GetPath(PP_Resource file_ref_id) { PP_Resource GetParent(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref.get()) + if (!file_ref) return 0; if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) return 0; scoped_refptr<FileRef> parent_ref(file_ref->GetParent()); - if (!parent_ref.get()) + if (!parent_ref) return 0; - parent_ref->AddRef(); // AddRef for the caller. - return parent_ref->GetResource(); + return parent_ref->GetReference(); } const PPB_FileRef ppb_fileref = { @@ -165,7 +163,6 @@ scoped_refptr<FileRef> FileRef::GetParent() { std::string parent_path = path_.substr(0, pos); FileRef* parent_ref = new FileRef(module(), fs_type_, parent_path, origin_); - parent_ref->AddRef(); // AddRef for the caller. return parent_ref; } diff --git a/webkit/glue/plugins/pepper_font.cc b/webkit/glue/plugins/pepper_font.cc index 8bc48a3..af4cb81d 100644 --- a/webkit/glue/plugins/pepper_font.cc +++ b/webkit/glue/plugins/pepper_font.cc @@ -34,9 +34,8 @@ PP_Resource MatchFontWithFallback(PP_Module module_id, return NULL; scoped_refptr<Font> font(new Font(module, fd)); - font->AddRef(); // AddRef for the caller. - return font->GetResource(); + return font->GetReference(); #else // For trusted pepper plugins, this is only needed in Linux since font loading // on Windows and Mac works through the renderer sandbox. @@ -45,7 +44,7 @@ PP_Resource MatchFontWithFallback(PP_Module module_id, } bool IsFont(PP_Resource resource) { - return !!Resource::GetAs<Font>(resource).get(); + return !!Resource::GetAs<Font>(resource); } bool GetFontTable(PP_Resource font_id, diff --git a/webkit/glue/plugins/pepper_image_data.cc b/webkit/glue/plugins/pepper_image_data.cc index 51245b4..8288fe2 100644 --- a/webkit/glue/plugins/pepper_image_data.cc +++ b/webkit/glue/plugins/pepper_image_data.cc @@ -36,13 +36,12 @@ PP_Resource Create(PP_Module module_id, scoped_refptr<ImageData> data(new ImageData(module)); if (!data->Init(format, size->width, size->height, init_to_zero)) return NULL; - data->AddRef(); // AddRef for the caller. - return data->GetResource(); + return data->GetReference(); } bool IsImageData(PP_Resource resource) { - return !!Resource::GetAs<ImageData>(resource).get(); + return !!Resource::GetAs<ImageData>(resource); } bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { @@ -50,7 +49,7 @@ bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { memset(desc, 0, sizeof(PP_ImageDataDesc)); scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource)); - if (!image_data.get()) + if (!image_data) return false; image_data->Describe(desc); return true; @@ -58,16 +57,15 @@ bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { void* Map(PP_Resource resource) { scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource)); - if (!image_data.get()) + if (!image_data) return NULL; return image_data->Map(); } void Unmap(PP_Resource resource) { scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource)); - if (!image_data) - return; - return image_data->Unmap(); + if (image_data) + image_data->Unmap(); } const PPB_ImageData ppb_imagedata = { diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index dcc7ea2..6a7bf54 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -376,8 +376,8 @@ bool PluginInstance::Initialize(WebPluginContainer* container, } bool PluginInstance::HandleDocumentLoad(URLLoader* loader) { - return instance_interface_->HandleDocumentLoad(GetPPInstance(), - loader->GetResource()); + Resource::ScopedResourceId resource(loader); + return instance_interface_->HandleDocumentLoad(GetPPInstance(), resource.id); } bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index e748e56..8ffd78b 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -75,21 +75,15 @@ base::MessageLoopProxy* GetMainThreadMessageLoop() { // PPB_Core -------------------------------------------------------------------- void AddRefResource(PP_Resource resource) { - Resource* res = ResourceTracker::Get()->GetResource(resource); - if (!res) { - DLOG(WARNING) << "AddRef()ing a nonexistent resource"; - return; + if (!ResourceTracker::Get()->AddRefResource(resource)) { + DLOG(WARNING) << "AddRefResource()ing a nonexistent resource"; } - res->AddRef(); } void ReleaseResource(PP_Resource resource) { - Resource* res = ResourceTracker::Get()->GetResource(resource); - if (!res) { - DLOG(WARNING) << "Release()ing a nonexistent resource"; - return; + if (!ResourceTracker::Get()->UnrefResource(resource)) { + DLOG(WARNING) << "ReleaseResource()ing a nonexistent resource"; } - res->Release(); } void* MemAlloc(size_t num_bytes) { diff --git a/webkit/glue/plugins/pepper_resource.cc b/webkit/glue/plugins/pepper_resource.cc index fe2cf4b..c568183 100644 --- a/webkit/glue/plugins/pepper_resource.cc +++ b/webkit/glue/plugins/pepper_resource.cc @@ -4,21 +4,16 @@ #include "webkit/glue/plugins/pepper_resource.h" -#include "third_party/ppapi/c/pp_resource.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { -Resource::Resource(PluginModule* module) : module_(module) { - ResourceTracker::Get()->AddResource(this); +PP_Resource Resource::GetReference() { + ResourceTracker *tracker = ResourceTracker::Get(); + if (resource_id_) + tracker->AddRefResource(resource_id_); + else + resource_id_ = tracker->AddResource(this); + return resource_id_; } - -Resource::~Resource() { - ResourceTracker::Get()->DeleteResource(this); -} - -PP_Resource Resource::GetResource() const { - return reinterpret_cast<intptr_t>(this); -} - } // namespace pepper diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h index 4e347cb..417a06b 100644 --- a/webkit/glue/plugins/pepper_resource.h +++ b/webkit/glue/plugins/pepper_resource.h @@ -5,6 +5,7 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_ +#include "base/logging.h" #include "base/basictypes.h" #include "base/ref_counted.h" #include "third_party/ppapi/c/pp_resource.h" @@ -29,8 +30,8 @@ class Widget; class Resource : public base::RefCountedThreadSafe<Resource> { public: - explicit Resource(PluginModule* module); - virtual ~Resource(); + explicit Resource(PluginModule* module) : resource_id_(0), module_(module) {} + virtual ~Resource() {} // Returns NULL if the resource is invalid or is a different type. template<typename T> @@ -39,8 +40,6 @@ class Resource : public base::RefCountedThreadSafe<Resource> { return resource ? resource->Cast<T>() : NULL; } - PP_Resource GetResource() const; - PluginModule* module() const { return module_; } // Cast the resource into a specified type. This will return NULL if the @@ -48,6 +47,27 @@ class Resource : public base::RefCountedThreadSafe<Resource> { // template call into As* functions. template <typename T> T* Cast() { return NULL; } + // Returns an resource id of this object. If the object doesn't have a + // resource id, new one is created with plugin refcount of 1. If it does, + // the refcount is incremented. Use this when you need to return a new + // reference to the plugin. + PP_Resource GetReference(); + + // When you need to ensure that a resource has a reference, but you do not + // want to increase the refcount (for example, if you need to call a plugin + // callback function with a reference), you can use this class. For example: + // + // plugin_callback(.., ScopedResourceId(resource).id, ...); + class ScopedResourceId { + public: + explicit ScopedResourceId(Resource* resource) + : id(resource->GetReference()) {} + ~ScopedResourceId() { + ResourceTracker::Get()->UnrefResource(id); + } + const PP_Resource id; + }; + private: // Type-specific getters for individual resource types. These will return // NULL if the resource does not match the specified type. Used by the Cast() @@ -66,7 +86,25 @@ class Resource : public base::RefCountedThreadSafe<Resource> { virtual URLResponseInfo* AsURLResponseInfo() { return NULL; } virtual Widget* AsWidget() { return NULL; } - PluginModule* module_; // Non-owning pointer to our module. + private: + // If referenced by a plugin, holds the id of this resource object. Do not + // access this member directly, because it is possible that the plugin holds + // no references to the object, and therefore the resource_id_ is zero. Use + // either GetReference() to obtain a new resource_id and increase the + // refcount, or TemporaryReference when you do not want to increase the + // refcount. + PP_Resource resource_id_; + + // Non-owning pointer to our module. + PluginModule* module_; + + // Called by the resource tracker when the last plugin reference has been + // dropped. + friend class ResourceTracker; + void StoppedTracking() { + DCHECK(resource_id_ != 0); + resource_id_ = 0; + } DISALLOW_COPY_AND_ASSIGN(Resource); }; diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc index c8779e4..8aa94d2 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.cc +++ b/webkit/glue/plugins/pepper_resource_tracker.cc @@ -4,57 +4,58 @@ #include "webkit/glue/plugins/pepper_resource_tracker.h" +#include <limits> #include <set> #include "base/logging.h" #include "third_party/ppapi/c/pp_resource.h" -#include "webkit/glue/plugins/pepper_buffer.h" -#include "webkit/glue/plugins/pepper_device_context_2d.h" -#include "webkit/glue/plugins/pepper_directory_reader.h" -#include "webkit/glue/plugins/pepper_file_chooser.h" -#include "webkit/glue/plugins/pepper_file_io.h" -#include "webkit/glue/plugins/pepper_file_ref.h" -#include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_resource.h" -#include "webkit/glue/plugins/pepper_url_loader.h" -#include "webkit/glue/plugins/pepper_url_request_info.h" -#include "webkit/glue/plugins/pepper_url_response_info.h" namespace pepper { -ResourceTracker::ResourceTracker() { -} - -ResourceTracker::~ResourceTracker() { -} - -// static -ResourceTracker* ResourceTracker::Get() { - return Singleton<ResourceTracker>::get(); -} - scoped_refptr<Resource> ResourceTracker::GetResource(PP_Resource res) const { - AutoLock lock(lock_); - Resource* resource = reinterpret_cast<Resource*>(res); - if (live_resources_.find(resource) == live_resources_.end()) + ResourceMap::const_iterator result = live_resources_.find(res); + if (result == live_resources_.end()) { return scoped_refptr<Resource>(); - return scoped_refptr<Resource>(resource); + } + return result->second.first; } -void ResourceTracker::AddResource(Resource* resource) { - AutoLock lock(lock_); - DCHECK(live_resources_.find(resource) == live_resources_.end()); - live_resources_.insert(resource); +PP_Resource ResourceTracker::AddResource(Resource* resource) { + // If the plugin manages to create 4B resources... + if (last_id_ == std::numeric_limits<PP_Resource>::max()) { + return 0; + } + // Add the resource with plugin use-count 1. + ++last_id_; + live_resources_.insert(std::make_pair(last_id_, std::make_pair(resource, 1))); + return last_id_; +} + +bool ResourceTracker::AddRefResource(PP_Resource res) { + ResourceMap::iterator i = live_resources_.find(res); + if (i != live_resources_.end()) { + // 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.second; + return true; + } else { + return false; + } } -void ResourceTracker::DeleteResource(Resource* resource) { - AutoLock lock(lock_); - ResourceSet::iterator found = live_resources_.find(resource); - if (found == live_resources_.end()) { - NOTREACHED(); - return; +bool ResourceTracker::UnrefResource(PP_Resource res) { + ResourceMap::iterator i = live_resources_.find(res); + if (i != live_resources_.end()) { + if (!--i->second.second) { + i->second.first->StoppedTracking(); + live_resources_.erase(i); + } + return true; + } else { + return false; } - live_resources_.erase(found); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h index 35c382d..d06c9ba 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.h +++ b/webkit/glue/plugins/pepper_resource_tracker.h @@ -9,7 +9,7 @@ #include "base/atomic_sequence_num.h" #include "base/basictypes.h" -#include "base/lock.h" +#include "base/hash_tables.h" #include "base/ref_counted.h" #include "base/singleton.h" #include "third_party/ppapi/c/pp_resource.h" @@ -25,7 +25,9 @@ class Resource; class ResourceTracker { public: // Returns the pointer to the singleton object. - static ResourceTracker* Get(); + static ResourceTracker* Get() { + return Singleton<ResourceTracker>::get(); + } // The returned pointer will be NULL if there is no resource. Note that this // return value is a scoped_refptr so that we ensure the resource is valid @@ -34,23 +36,36 @@ class ResourceTracker { // the object will get deleted out from under us. scoped_refptr<Resource> GetResource(PP_Resource res) const; - // Adds the given resource to the tracker and assigns it a resource ID. The - // assigned resource ID will be returned. - void AddResource(Resource* resource); - - void DeleteResource(Resource* resource); + // Increment resource's plugin refcount. See ResourceAndRefCount comments + // below. + bool AddRefResource(PP_Resource res); + bool UnrefResource(PP_Resource res); private: friend struct DefaultSingletonTraits<ResourceTracker>; - - ResourceTracker(); - ~ResourceTracker(); - - // Hold this lock when accessing this object's members. - mutable Lock lock_; - - typedef std::set<Resource*> ResourceSet; - ResourceSet live_resources_; + friend class Resource; + + // Prohibit creation other then by the Singleton class. + ResourceTracker() : last_id_(0) {} + ~ResourceTracker() {} + + // Adds the given resource to the tracker and assigns it a resource ID and + // refcount of 1. The assigned resource ID will be returned. Used only by the + // Resource class. + PP_Resource AddResource(Resource* resource); + + // Last assigned resource ID. + PP_Resource last_id_; + + // For each PP_Resource, keep the Resource* (as refptr) and plugin use count. + // This use count is different then Resource's RefCount, and is manipulated + // using this RefResource/UnrefResource. When it drops to zero, we just remove + // the resource from this resource tracker, but the resource object will be + // alive so long as some scoped_refptr still holds it's reference. This + // prevents plugins from forcing destruction of Resource objects. + typedef std::pair<scoped_refptr<Resource>, size_t> ResourceAndRefCount; + typedef base::hash_map<PP_Resource, ResourceAndRefCount> ResourceMap; + ResourceMap live_resources_; DISALLOW_COPY_AND_ASSIGN(ResourceTracker); }; diff --git a/webkit/glue/plugins/pepper_scrollbar.cc b/webkit/glue/plugins/pepper_scrollbar.cc index 155bd64..48db8d4 100644 --- a/webkit/glue/plugins/pepper_scrollbar.cc +++ b/webkit/glue/plugins/pepper_scrollbar.cc @@ -31,13 +31,11 @@ PP_Resource Create(PP_Instance instance_id, bool vertical) { return NULL; scoped_refptr<Scrollbar> scrollbar(new Scrollbar(instance, vertical)); - scrollbar->AddRef(); // AddRef for the caller. - - return scrollbar->GetResource(); + return scrollbar->GetReference(); } bool IsScrollbar(PP_Resource resource) { - return !!Resource::GetAs<Scrollbar>(resource).get(); + return !!Resource::GetAs<Scrollbar>(resource); } uint32_t GetThickness() { @@ -46,20 +44,20 @@ uint32_t GetThickness() { uint32_t GetValue(PP_Resource resource) { scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); - if (!scrollbar.get()) + if (!scrollbar) return 0; return scrollbar->GetValue(); } void SetValue(PP_Resource resource, uint32_t value) { scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); - if (scrollbar.get()) + if (scrollbar) scrollbar->SetValue(value); } void SetDocumentSize(PP_Resource resource, uint32_t size) { scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); - if (scrollbar.get()) + if (scrollbar) scrollbar->SetDocumentSize(size); } @@ -67,7 +65,7 @@ void SetTickMarks(PP_Resource resource, const PP_Rect* tick_marks, uint32_t count) { scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); - if (scrollbar.get()) + if (scrollbar) scrollbar->SetTickMarks(tick_marks, count); } @@ -75,7 +73,7 @@ void ScrollBy(PP_Resource resource, PP_ScrollBy unit, int32_t multiplier) { scoped_refptr<Scrollbar> scrollbar(Resource::GetAs<Scrollbar>(resource)); - if (scrollbar.get()) + if (scrollbar) scrollbar->ScrollBy(unit, multiplier); } @@ -184,8 +182,9 @@ void Scrollbar::valueChanged(WebKit::WebScrollbar* scrollbar) { module()->GetPluginInterface(PPP_SCROLLBAR_INTERFACE)); if (!ppp_scrollbar) return; + ScopedResourceId resource(this); ppp_scrollbar->ValueChanged( - instance()->GetPPInstance(), GetResource(), scrollbar_->value()); + instance()->GetPPInstance(), resource.id, scrollbar_->value()); } void Scrollbar::invalidateScrollbarRect(WebKit::WebScrollbar* scrollbar, diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc index 617cbc2..aa09686 100644 --- a/webkit/glue/plugins/pepper_url_loader.cc +++ b/webkit/glue/plugins/pepper_url_loader.cc @@ -42,25 +42,24 @@ PP_Resource Create(PP_Instance instance_id) { return 0; URLLoader* loader = new URLLoader(instance); - loader->AddRef(); // AddRef for the caller. - return loader->GetResource(); + return loader->GetReference(); } bool IsURLLoader(PP_Resource resource) { - return !!Resource::GetAs<URLLoader>(resource).get(); + return !!Resource::GetAs<URLLoader>(resource); } int32_t Open(PP_Resource loader_id, PP_Resource request_id, PP_CompletionCallback callback) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return PP_ERROR_BADRESOURCE; scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); - if (!request.get()) + if (!request) return PP_ERROR_BADRESOURCE; return loader->Open(request, callback); @@ -69,7 +68,7 @@ int32_t Open(PP_Resource loader_id, int32_t FollowRedirect(PP_Resource loader_id, PP_CompletionCallback callback) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return PP_ERROR_BADRESOURCE; return loader->FollowRedirect(callback); @@ -79,7 +78,7 @@ bool GetUploadProgress(PP_Resource loader_id, int64_t* bytes_sent, int64_t* total_bytes_to_be_sent) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return false; *bytes_sent = loader->bytes_sent(); @@ -91,7 +90,7 @@ bool GetDownloadProgress(PP_Resource loader_id, int64_t* bytes_received, int64_t* total_bytes_to_be_received) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return false; *bytes_received = loader->bytes_received(); @@ -101,15 +100,14 @@ bool GetDownloadProgress(PP_Resource loader_id, PP_Resource GetResponseInfo(PP_Resource loader_id) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return 0; URLResponseInfo* response_info = loader->response_info(); if (!response_info) return 0; - response_info->AddRef(); // AddRef for the caller. - return response_info->GetResource(); + return response_info->GetReference(); } int32_t ReadResponseBody(PP_Resource loader_id, @@ -117,7 +115,7 @@ int32_t ReadResponseBody(PP_Resource loader_id, int32_t bytes_to_read, PP_CompletionCallback callback) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return PP_ERROR_BADRESOURCE; return loader->ReadResponseBody(buffer, bytes_to_read, callback); @@ -125,7 +123,7 @@ int32_t ReadResponseBody(PP_Resource loader_id, void Close(PP_Resource loader_id) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); - if (!loader.get()) + if (!loader) return; loader->Close(); diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc index 9ce79ce..d230f20 100644 --- a/webkit/glue/plugins/pepper_url_request_info.cc +++ b/webkit/glue/plugins/pepper_url_request_info.cc @@ -53,13 +53,12 @@ PP_Resource Create(PP_Module module_id) { return 0; URLRequestInfo* request = new URLRequestInfo(module); - request->AddRef(); // AddRef for the caller. - return request->GetResource(); + return request->GetReference(); } bool IsURLRequestInfo(PP_Resource resource) { - return !!Resource::GetAs<URLRequestInfo>(resource).get(); + return !!Resource::GetAs<URLRequestInfo>(resource); } bool SetProperty(PP_Resource request_id, @@ -67,7 +66,7 @@ bool SetProperty(PP_Resource request_id, PP_Var var) { scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); - if (!request.get()) + if (!request) return false; if (var.type == PP_VARTYPE_BOOL) @@ -82,7 +81,7 @@ bool SetProperty(PP_Resource request_id, bool AppendDataToBody(PP_Resource request_id, PP_Var var) { scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); - if (!request.get()) + if (!request) return false; String* data = GetString(var); @@ -99,11 +98,11 @@ bool AppendFileToBody(PP_Resource request_id, PP_Time expected_last_modified_time) { scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); - if (!request.get()) + if (!request) return false; scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref.get()) + if (!file_ref) return false; return request->AppendFileToBody(file_ref, diff --git a/webkit/glue/plugins/pepper_url_response_info.cc b/webkit/glue/plugins/pepper_url_response_info.cc index b5db4bc5..bff92aa 100644 --- a/webkit/glue/plugins/pepper_url_response_info.cc +++ b/webkit/glue/plugins/pepper_url_response_info.cc @@ -38,14 +38,14 @@ class HeaderFlattener : public WebHTTPHeaderVisitor { }; bool IsURLResponseInfo(PP_Resource resource) { - return !!Resource::GetAs<URLResponseInfo>(resource).get(); + return !!Resource::GetAs<URLResponseInfo>(resource); } PP_Var GetProperty(PP_Resource response_id, PP_URLResponseProperty property) { scoped_refptr<URLResponseInfo> response( Resource::GetAs<URLResponseInfo>(response_id)); - if (!response.get()) + if (!response) return PP_MakeVoid(); return response->GetProperty(property); @@ -62,7 +62,7 @@ PP_Resource GetBody(PP_Resource response_id) { return 0; body->AddRef(); // AddRef for the caller. - return body->GetResource(); + return body->GetReference(); } const PPB_URLResponseInfo ppb_urlresponseinfo = { diff --git a/webkit/glue/plugins/pepper_widget.cc b/webkit/glue/plugins/pepper_widget.cc index 9d345274..74b0e40 100644 --- a/webkit/glue/plugins/pepper_widget.cc +++ b/webkit/glue/plugins/pepper_widget.cc @@ -18,31 +18,31 @@ namespace pepper { namespace { bool IsWidget(PP_Resource resource) { - return !!Resource::GetAs<Widget>(resource).get(); + return !!Resource::GetAs<Widget>(resource); } bool Paint(PP_Resource resource, const PP_Rect* rect, PP_Resource image_id) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); - if (!widget.get()) + if (!widget) return false; scoped_refptr<ImageData> image(Resource::GetAs<ImageData>(image_id)); - return widget.get() && widget->Paint(rect, image); + return widget && widget->Paint(rect, image); } bool HandleEvent(PP_Resource resource, const PP_Event* event) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); - return widget.get() && widget->HandleEvent(event); + return widget && widget->HandleEvent(event); } bool GetLocation(PP_Resource resource, PP_Rect* location) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); - return widget.get() && widget->GetLocation(location); + return widget && widget->GetLocation(location); } void SetLocation(PP_Resource resource, const PP_Rect* location) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); - if (widget.get()) + if (widget) widget->SetLocation(location); } @@ -84,7 +84,8 @@ void Widget::Invalidate(const PP_Rect* dirty) { module()->GetPluginInterface(PPP_WIDGET_INTERFACE)); if (!widget) return; - widget->Invalidate(instance_->GetPPInstance(), GetResource(), dirty); + ScopedResourceId resource(this); + widget->Invalidate(instance_->GetPPInstance(), resource.id, dirty); } } // namespace pepper |