1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef TESTS_NACL_IO_TEST_FAKE_RESOURCE_MANAGER_H_
6 #define TESTS_NACL_IO_TEST_FAKE_RESOURCE_MANAGER_H_
7
8 #include <map>
9
10 #include <ppapi/c/pp_resource.h>
11
12 #include "sdk_util/atomicops.h"
13 #include "sdk_util/macros.h"
14 #include "sdk_util/simple_lock.h"
15
16 class FakeResource;
17 class FakeResourceTracker;
18
19 class FakeResourceManager {
20 public:
21 FakeResourceManager();
22 ~FakeResourceManager();
23
24 PP_Resource Create(FakeResource* resource,
25 const char* classname,
26 const char* file,
27 int line);
28 void AddRef(PP_Resource handle);
29 void Release(PP_Resource handle);
30 template <typename T>
31 T* Get(PP_Resource handle, bool not_found_ok=false);
32
33 private:
34 FakeResourceTracker* Get(PP_Resource handle, bool not_found_ok);
35
36 typedef std::map<PP_Resource, FakeResourceTracker*> ResourceMap;
37 PP_Resource next_handle_;
38 ResourceMap resource_map_;
39 sdk_util::SimpleLock lock_; // Protects next_handle_ and resource_map_.
40
41 DISALLOW_COPY_AND_ASSIGN(FakeResourceManager);
42 };
43
44 // FakeResourceTracker wraps a FakeResource to keep metadata about the
45 // resource, including its refcount, the type of resource, etc.
46 class FakeResourceTracker {
47 public:
48 FakeResourceTracker(FakeResource* resource,
49 const char* classname,
50 const char* file,
51 int line);
52 ~FakeResourceTracker();
53
AddRef()54 void AddRef() { sdk_util::AtomicAddFetch(&ref_count_, 1); }
Release()55 void Release() { sdk_util::AtomicAddFetch(&ref_count_, -1); }
ref_count()56 int32_t ref_count() const { return ref_count_; }
57
58 // Give up ownership of this resource. It is the responsibility of the caller
59 // to delete this FakeResource.
Pass()60 FakeResource* Pass() {
61 FakeResource* result = resource_;
62 resource_ = NULL;
63 return result;
64 }
65
66 template <typename T>
resource()67 T* resource() {
68 if (!CheckType(T::classname()))
69 return NULL;
70
71 return static_cast<T*>(resource_);
72 }
73
resource()74 FakeResource* resource() { return resource_; }
75
classname()76 const char* classname() const { return classname_; }
file()77 const char* file() const { return file_; }
line()78 int line() const { return line_; }
79
80 private:
81 bool CheckType(const char* classname) const;
82
83 FakeResource* resource_; // Owned.
84 const char* classname_; // Weak reference.
85 const char* file_; // Weak reference.
86 int line_;
87 int32_t ref_count_;
88
89 DISALLOW_COPY_AND_ASSIGN(FakeResourceTracker);
90 };
91
92 class FakeResource {
93 public:
FakeResource()94 FakeResource() {}
95 // Called when the resource is destroyed. For debugging purposes, this does
96 // not happen until the resource manager is destroyed.
~FakeResource()97 virtual ~FakeResource() {}
98 // Called when the last reference to the resource is released.
Destroy()99 virtual void Destroy() {}
100
101 private:
102 DISALLOW_COPY_AND_ASSIGN(FakeResource);
103 };
104
105 template <typename T>
Get(PP_Resource handle,bool not_found_ok)106 inline T* FakeResourceManager::Get(PP_Resource handle, bool not_found_ok) {
107 FakeResourceTracker* tracker = Get(handle, not_found_ok);
108 if (!tracker)
109 return NULL;
110 return tracker->resource<T>();
111 }
112
113 #define CREATE_RESOURCE(MANAGER, TYPE, RESOURCE) \
114 (MANAGER)->Create((RESOURCE), #TYPE, __FILE__, __LINE__)
115
116 #endif // TESTS_NACL_IO_TEST_FAKE_RESOURCE_MANAGER_H_
117