| Index: courgette/memory_allocator.cc
|
| ===================================================================
|
| --- courgette/memory_allocator.cc (revision 80344)
|
| +++ courgette/memory_allocator.cc (working copy)
|
| @@ -11,19 +11,15 @@
|
|
|
| #ifdef OS_WIN
|
|
|
| -// A helper function to help diagnose failures we've seen in the field.
|
| -// The function constructs a string containing the error and throws a runtime
|
| -// exception. The calling convention is set to stdcall to force argument
|
| -// passing via the stack.
|
| +namespace courgette {
|
| +
|
| __declspec(noinline)
|
| -void __stdcall RuntimeError(DWORD err) {
|
| +void __stdcall ThrowExceptionOnAllocationFailure(uint32 err) {
|
| char buffer[20] = {0};
|
| wsprintfA(buffer, "err: %u", err);
|
| throw buffer;
|
| }
|
|
|
| -namespace courgette {
|
| -
|
| // TempFile
|
|
|
| TempFile::TempFile() : file_(base::kInvalidPlatformFileValue), size_(0) {
|
| @@ -33,11 +29,14 @@
|
| Close();
|
| }
|
|
|
| -FilePath TempFile::PrepareTempFile() {
|
| - FilePath path;
|
| - if (!file_util::CreateTemporaryFile(&path))
|
| - RuntimeError(::GetLastError());
|
| - return path;
|
| +bool TempFile::PrepareTempFile(FilePath* path,
|
| + AllocationFailureHandler failure_handler) {
|
| + if (!file_util::CreateTemporaryFile(path)) {
|
| + if (failure_handler)
|
| + failure_handler(::GetLastError());
|
| + return false;
|
| + }
|
| + return true;
|
| }
|
|
|
| void TempFile::Close() {
|
| @@ -48,9 +47,12 @@
|
| }
|
| }
|
|
|
| -void TempFile::Create() {
|
| +bool TempFile::Create(AllocationFailureHandler failure_handler) {
|
| DCHECK(file_ == base::kInvalidPlatformFileValue);
|
| - FilePath path(PrepareTempFile());
|
| + FilePath path;
|
| + if (!PrepareTempFile(&path, failure_handler))
|
| + return false;
|
| +
|
| bool created = false;
|
| base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
|
| int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ |
|
| @@ -58,8 +60,13 @@
|
| base::PLATFORM_FILE_DELETE_ON_CLOSE |
|
| base::PLATFORM_FILE_TEMPORARY;
|
| file_ = base::CreatePlatformFile(path, flags, &created, &error_code);
|
| - if (file_ == base::kInvalidPlatformFileValue)
|
| - RuntimeError(error_code);
|
| + if (file_ == base::kInvalidPlatformFileValue) {
|
| + if (failure_handler)
|
| + failure_handler(error_code);
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
| bool TempFile::valid() const {
|
| @@ -74,11 +81,15 @@
|
| return size_;
|
| }
|
|
|
| -void TempFile::SetSize(size_t size) {
|
| +bool TempFile::SetSize(size_t size, AllocationFailureHandler failure_handler) {
|
| bool set = base::TruncatePlatformFile(file_, size);
|
| - if (!set)
|
| - RuntimeError(::GetLastError());
|
| - size_ = size;
|
| + if (!set) {
|
| + if (failure_handler)
|
| + failure_handler(::GetLastError());
|
| + } else {
|
| + size_ = size;
|
| + }
|
| + return set;
|
| }
|
|
|
| // FileMapping
|
| @@ -90,22 +101,32 @@
|
| Close();
|
| }
|
|
|
| -void FileMapping::InitializeView(size_t size) {
|
| +bool FileMapping::InitializeView(size_t size,
|
| + AllocationFailureHandler failure_handler) {
|
| DCHECK(view_ == NULL);
|
| DCHECK(mapping_ != NULL);
|
| view_ = ::MapViewOfFile(mapping_, FILE_MAP_WRITE, 0, 0, size);
|
| - if (!view_)
|
| - RuntimeError(::GetLastError());
|
| + if (!view_) {
|
| + if (failure_handler)
|
| + failure_handler(::GetLastError());
|
| + Close();
|
| + return false;
|
| + }
|
| + return true;
|
| }
|
|
|
| -void FileMapping::Create(HANDLE file, size_t size) {
|
| +bool FileMapping::Create(HANDLE file, size_t size,
|
| + AllocationFailureHandler failure_handler) {
|
| DCHECK(file != INVALID_HANDLE_VALUE);
|
| DCHECK(!valid());
|
| mapping_ = ::CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 0, NULL);
|
| - if (!mapping_)
|
| - RuntimeError(::GetLastError());
|
| + if (!mapping_) {
|
| + if (failure_handler)
|
| + failure_handler(::GetLastError());
|
| + return false;
|
| + }
|
|
|
| - InitializeView(size);
|
| + return InitializeView(size, failure_handler);
|
| }
|
|
|
| void FileMapping::Close() {
|
| @@ -133,17 +154,23 @@
|
| TempMapping::~TempMapping() {
|
| }
|
|
|
| -void TempMapping::Initialize(size_t size) {
|
| +bool TempMapping::Initialize(size_t size,
|
| + AllocationFailureHandler failure_handler) {
|
| // TODO(tommi): The assumption here is that the alignment of pointers (this)
|
| // is as strict or stricter than the alignment of the element type. This is
|
| // not always true, e.g. __m128 has 16-byte alignment.
|
| size += sizeof(this);
|
| - file_.Create();
|
| - file_.SetSize(size);
|
| - mapping_.Create(file_.handle(), size);
|
| + if (!file_.Create(failure_handler) ||
|
| + !file_.SetSize(size, failure_handler) ||
|
| + !mapping_.Create(file_.handle(), size, failure_handler)) {
|
| + file_.Close();
|
| + return false;
|
| + }
|
|
|
| TempMapping** write = reinterpret_cast<TempMapping**>(mapping_.view());
|
| write[0] = this;
|
| +
|
| + return true;
|
| }
|
|
|
| void* TempMapping::memory() const {
|
| @@ -154,6 +181,10 @@
|
| return mem;
|
| }
|
|
|
| +bool TempMapping::valid() const {
|
| + return mapping_.valid();
|
| +}
|
| +
|
| // static
|
| TempMapping* TempMapping::GetMappingFromPtr(void* mem) {
|
| TempMapping* ret = NULL;
|
|
|