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_LOADER_RESOURCE_BUFFER_H_ 6 #define CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_ 7 8 #include <queue> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/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_LOADER_RESOURCE_BUFFER_H_ 129