OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 CONTENT_BROWSER_RENDERER_HOST_RESOURCE_BUFFER_H_ | |
6 #define CONTENT_BROWSER_RENDERER_HOST_RESOURCE_BUFFER_H_ | |
7 | |
8 #include <queue> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/memory/ref_counted.h" | |
12 #include "base/shared_memory.h" | |
13 #include "content/common/content_export.h" | |
14 | |
15 namespace content { | |
16 | |
17 // ResourceBuffer implements a simple "circular buffer" allocation strategy. | |
18 // Allocations are recycled in FIFO order. | |
19 // | |
20 // You can think of the ResourceBuffer as a FIFO. The Allocate method reserves | |
21 // space in the buffer. Allocate may be called multiple times until the buffer | |
22 // is fully reserved (at which point CanAllocate returns false). Allocations | |
23 // are freed in FIFO order via a call to RecycleLeastRecentlyAllocated. | |
24 // | |
25 // ResourceBuffer is reference-counted for the benefit of consumers, who need | |
26 // to ensure that ResourceBuffer stays alive while they are using its memory. | |
27 // | |
28 // EXAMPLE USAGE: | |
29 // | |
30 // // Writes data into the ResourceBuffer, and returns the location (byte | |
31 // // offset and count) of the bytes written into the ResourceBuffer's shared | |
32 // // memory buffer. | |
33 // void WriteToBuffer(ResourceBuffer* buf, int* offset, int* count) { | |
34 // DCHECK(buf->CanAllocate()); | |
35 // | |
36 // *offset = -1; | |
37 // *count = 0; | |
38 // | |
39 // int size; | |
40 // char* ptr = buf->Allocate(&size); | |
41 // if (!ptr) { /* handle error */ } | |
42 // | |
43 // int bytes_read = static_cast<int>(fread(ptr, 1, size, file_pointer_)); | |
44 // if (!bytes_read) { /* handle error */ } | |
45 // | |
46 // if (bytes_read < size) | |
47 // buf->ShrinkLastAllocation(bytes_read); | |
48 // | |
49 // *offset = buf->GetLastAllocationOffset(); | |
50 // *count = bytes_read; | |
51 // } | |
52 // | |
53 // NOTE: As the above example illustrates, the ResourceBuffer keeps track of | |
54 // the last allocation made. Calling ShrinkLastAllocation is optional, as it | |
55 // just helps the ResourceBuffer optimize storage and be more aggressive about | |
56 // returning larger allocations from the Allocate method. | |
57 // | |
58 class CONTENT_EXPORT ResourceBuffer | |
59 : public base::RefCountedThreadSafe<ResourceBuffer> { | |
60 public: | |
61 ResourceBuffer(); | |
62 | |
63 // Initialize the shared memory buffer. It will be buffer_size bytes in | |
64 // length. The min/max_allocation_size parameters control the behavior of | |
65 // the Allocate method. It will prefer to return segments that are | |
66 // max_allocation_size in length, but will return segments less than that if | |
67 // space is limited. It will not return allocations smaller than | |
68 // min_allocation_size. | |
69 bool Initialize(int buffer_size, | |
70 int min_allocation_size, | |
71 int max_allocation_size); | |
72 bool IsInitialized() const; | |
73 | |
74 // Returns a shared memory handle that can be passed to the given process. | |
75 // The shared memory handle is only intended to be interpretted by code | |
76 // running in the specified process. NOTE: The caller should ensure that | |
77 // this memory eventually be returned to the operating system. | |
78 bool ShareToProcess(base::ProcessHandle process_handle, | |
79 base::SharedMemoryHandle* shared_memory_handle, | |
80 int* shared_memory_size); | |
81 | |
82 // Returns true if Allocate will succeed. | |
83 bool CanAllocate() const; | |
84 | |
85 // Returns a pointer into the shared memory buffer or NULL if the buffer is | |
86 // already fully allocated. The returned size will be max_allocation_size | |
87 // unless the buffer is close to being full. | |
88 char* Allocate(int* size); | |
89 | |
90 // Returns the offset into the shared memory buffer where the last allocation | |
91 // returned by Allocate can be found. | |
92 int GetLastAllocationOffset() const; | |
93 | |
94 // Called to reduce the size of the last allocation returned by Allocate. It | |
95 // is OK for new_size to match the current size of the last allocation. | |
96 void ShrinkLastAllocation(int new_size); | |
97 | |
98 // Called to allow reuse of memory that was previously allocated. See notes | |
99 // above the class for more details about this method. | |
100 void RecycleLeastRecentlyAllocated(); | |
101 | |
102 private: | |
103 friend class base::RefCountedThreadSafe<ResourceBuffer>; | |
104 ~ResourceBuffer(); | |
105 | |
106 base::SharedMemory shared_mem_; | |
107 | |
108 int buf_size_; | |
109 int min_alloc_size_; | |
110 int max_alloc_size_; | |
111 | |
112 // These point to the range of the shared memory that is currently allocated. | |
113 // If alloc_start_ is -1, then the range is empty and nothing is allocated. | |
114 // Otherwise, alloc_start_ points to the start of the allocated range, and | |
115 // alloc_end_ points just beyond the end of the previous allocation. In the | |
116 // wraparound case, alloc_end_ <= alloc_start_. See resource_buffer.cc for | |
117 // more details about these members. | |
118 int alloc_start_; | |
119 int alloc_end_; | |
120 | |
121 std::queue<int> alloc_sizes_; | |
122 | |
123 DISALLOW_COPY_AND_ASSIGN(ResourceBuffer); | |
124 }; | |
125 | |
126 } // namespace content | |
127 | |
128 #endif // CONTENT_BROWSER_RENDERER_HOST_RESOURCE_BUFFER_H_ | |
OLD | NEW |