| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TESTS_NACL_IO_TEST_FAKE_RESOURCE_MANAGER_H_ |
| #define TESTS_NACL_IO_TEST_FAKE_RESOURCE_MANAGER_H_ |
| |
| #include <map> |
| |
| #include <ppapi/c/pp_resource.h> |
| |
| #include "sdk_util/atomicops.h" |
| #include "sdk_util/macros.h" |
| #include "sdk_util/simple_lock.h" |
| |
| class FakeResource; |
| class FakeResourceTracker; |
| |
| class FakeResourceManager { |
| public: |
| FakeResourceManager(); |
| ~FakeResourceManager(); |
| |
| PP_Resource Create(FakeResource* resource, |
| const char* classname, |
| const char* file, |
| int line); |
| void AddRef(PP_Resource handle); |
| void Release(PP_Resource handle); |
| template <typename T> |
| T* Get(PP_Resource handle, bool not_found_ok=false); |
| |
| private: |
| FakeResourceTracker* Get(PP_Resource handle, bool not_found_ok); |
| |
| typedef std::map<PP_Resource, FakeResourceTracker*> ResourceMap; |
| PP_Resource next_handle_; |
| ResourceMap resource_map_; |
| sdk_util::SimpleLock lock_; // Protects next_handle_ and resource_map_. |
| |
| DISALLOW_COPY_AND_ASSIGN(FakeResourceManager); |
| }; |
| |
| // FakeResourceTracker wraps a FakeResource to keep metadata about the |
| // resource, including its refcount, the type of resource, etc. |
| class FakeResourceTracker { |
| public: |
| FakeResourceTracker(FakeResource* resource, |
| const char* classname, |
| const char* file, |
| int line); |
| ~FakeResourceTracker(); |
| |
| void AddRef() { sdk_util::AtomicAddFetch(&ref_count_, 1); } |
| void Release() { sdk_util::AtomicAddFetch(&ref_count_, -1); } |
| int32_t ref_count() const { return ref_count_; } |
| |
| // Give up ownership of this resource. It is the responsibility of the caller |
| // to delete this FakeResource. |
| FakeResource* Pass() { |
| FakeResource* result = resource_; |
| resource_ = NULL; |
| return result; |
| } |
| |
| template <typename T> |
| T* resource() { |
| if (!CheckType(T::classname())) |
| return NULL; |
| |
| return static_cast<T*>(resource_); |
| } |
| |
| FakeResource* resource() { return resource_; } |
| |
| const char* classname() const { return classname_; } |
| const char* file() const { return file_; } |
| int line() const { return line_; } |
| |
| private: |
| bool CheckType(const char* classname) const; |
| |
| FakeResource* resource_; // Owned. |
| const char* classname_; // Weak reference. |
| const char* file_; // Weak reference. |
| int line_; |
| int32_t ref_count_; |
| |
| DISALLOW_COPY_AND_ASSIGN(FakeResourceTracker); |
| }; |
| |
| class FakeResource { |
| public: |
| FakeResource() {} |
| // Called when the resource is destroyed. For debugging purposes, this does |
| // not happen until the resource manager is destroyed. |
| virtual ~FakeResource() {} |
| // Called when the last reference to the resource is released. |
| virtual void Destroy() {} |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(FakeResource); |
| }; |
| |
| template <typename T> |
| inline T* FakeResourceManager::Get(PP_Resource handle, bool not_found_ok) { |
| FakeResourceTracker* tracker = Get(handle, not_found_ok); |
| if (!tracker) |
| return NULL; |
| return tracker->resource<T>(); |
| } |
| |
| #define CREATE_RESOURCE(MANAGER, TYPE, RESOURCE) \ |
| (MANAGER)->Create((RESOURCE), #TYPE, __FILE__, __LINE__) |
| |
| #endif // TESTS_NACL_IO_TEST_FAKE_RESOURCE_MANAGER_H_ |