diff options
Diffstat (limited to 'chromium/content/browser/loader/resource_buffer.h')
-rw-r--r-- | chromium/content/browser/loader/resource_buffer.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/chromium/content/browser/loader/resource_buffer.h b/chromium/content/browser/loader/resource_buffer.h new file mode 100644 index 00000000000..0908edbc083 --- /dev/null +++ b/chromium/content/browser/loader/resource_buffer.h @@ -0,0 +1,128 @@ +// Copyright (c) 2012 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 CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_ +#define CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_ + +#include <queue> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/shared_memory.h" +#include "content/common/content_export.h" + +namespace content { + +// ResourceBuffer implements a simple "circular buffer" allocation strategy. +// Allocations are recycled in FIFO order. +// +// You can think of the ResourceBuffer as a FIFO. The Allocate method reserves +// space in the buffer. Allocate may be called multiple times until the buffer +// is fully reserved (at which point CanAllocate returns false). Allocations +// are freed in FIFO order via a call to RecycleLeastRecentlyAllocated. +// +// ResourceBuffer is reference-counted for the benefit of consumers, who need +// to ensure that ResourceBuffer stays alive while they are using its memory. +// +// EXAMPLE USAGE: +// +// // Writes data into the ResourceBuffer, and returns the location (byte +// // offset and count) of the bytes written into the ResourceBuffer's shared +// // memory buffer. +// void WriteToBuffer(ResourceBuffer* buf, int* offset, int* count) { +// DCHECK(buf->CanAllocate()); +// +// *offset = -1; +// *count = 0; +// +// int size; +// char* ptr = buf->Allocate(&size); +// if (!ptr) { /* handle error */ } +// +// int bytes_read = static_cast<int>(fread(ptr, 1, size, file_pointer_)); +// if (!bytes_read) { /* handle error */ } +// +// if (bytes_read < size) +// buf->ShrinkLastAllocation(bytes_read); +// +// *offset = buf->GetLastAllocationOffset(); +// *count = bytes_read; +// } +// +// NOTE: As the above example illustrates, the ResourceBuffer keeps track of +// the last allocation made. Calling ShrinkLastAllocation is optional, as it +// just helps the ResourceBuffer optimize storage and be more aggressive about +// returning larger allocations from the Allocate method. +// +class CONTENT_EXPORT ResourceBuffer + : public base::RefCountedThreadSafe<ResourceBuffer> { + public: + ResourceBuffer(); + + // Initialize the shared memory buffer. It will be buffer_size bytes in + // length. The min/max_allocation_size parameters control the behavior of + // the Allocate method. It will prefer to return segments that are + // max_allocation_size in length, but will return segments less than that if + // space is limited. It will not return allocations smaller than + // min_allocation_size. + bool Initialize(int buffer_size, + int min_allocation_size, + int max_allocation_size); + bool IsInitialized() const; + + // Returns a shared memory handle that can be passed to the given process. + // The shared memory handle is only intended to be interpretted by code + // running in the specified process. NOTE: The caller should ensure that + // this memory eventually be returned to the operating system. + bool ShareToProcess(base::ProcessHandle process_handle, + base::SharedMemoryHandle* shared_memory_handle, + int* shared_memory_size); + + // Returns true if Allocate will succeed. + bool CanAllocate() const; + + // Returns a pointer into the shared memory buffer or NULL if the buffer is + // already fully allocated. The returned size will be max_allocation_size + // unless the buffer is close to being full. + char* Allocate(int* size); + + // Returns the offset into the shared memory buffer where the last allocation + // returned by Allocate can be found. + int GetLastAllocationOffset() const; + + // Called to reduce the size of the last allocation returned by Allocate. It + // is OK for new_size to match the current size of the last allocation. + void ShrinkLastAllocation(int new_size); + + // Called to allow reuse of memory that was previously allocated. See notes + // above the class for more details about this method. + void RecycleLeastRecentlyAllocated(); + + private: + friend class base::RefCountedThreadSafe<ResourceBuffer>; + ~ResourceBuffer(); + + base::SharedMemory shared_mem_; + + int buf_size_; + int min_alloc_size_; + int max_alloc_size_; + + // These point to the range of the shared memory that is currently allocated. + // If alloc_start_ is -1, then the range is empty and nothing is allocated. + // Otherwise, alloc_start_ points to the start of the allocated range, and + // alloc_end_ points just beyond the end of the previous allocation. In the + // wraparound case, alloc_end_ <= alloc_start_. See resource_buffer.cc for + // more details about these members. + int alloc_start_; + int alloc_end_; + + std::queue<int> alloc_sizes_; + + DISALLOW_COPY_AND_ASSIGN(ResourceBuffer); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_ |