blob: b3a45b4b7f8e233f4c815c33720e0b674025cc6a [file] [log] [blame]
[email protected]5ace0a82012-07-25 21:26:121// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]fbd31eb2011-03-01 00:19:022// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "courgette/memory_allocator.h"
6
7#include <map>
8
9#include "base/file_util.h"
[email protected]6c131952011-03-03 23:39:3210#include "base/stringprintf.h"
[email protected]fbd31eb2011-03-01 00:19:0211
12#ifdef OS_WIN
13
14namespace courgette {
15
16// TempFile
17
[email protected]43a9e242011-04-06 17:42:4518TempFile::TempFile() : file_(base::kInvalidPlatformFileValue) {
[email protected]fbd31eb2011-03-01 00:19:0219}
20
21TempFile::~TempFile() {
22 Close();
23}
24
25void TempFile::Close() {
26 if (valid()) {
27 base::ClosePlatformFile(file_);
28 file_ = base::kInvalidPlatformFileValue;
[email protected]fbd31eb2011-03-01 00:19:0229 }
30}
31
[email protected]43a9e242011-04-06 17:42:4532bool TempFile::Create() {
[email protected]fbd31eb2011-03-01 00:19:0233 DCHECK(file_ == base::kInvalidPlatformFileValue);
[email protected]43a9e242011-04-06 17:42:4534 FilePath path;
35 if (!file_util::CreateTemporaryFile(&path))
36 return false;
37
[email protected]6c131952011-03-03 23:39:3238 bool created = false;
39 base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
40 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ |
41 base::PLATFORM_FILE_WRITE |
42 base::PLATFORM_FILE_DELETE_ON_CLOSE |
43 base::PLATFORM_FILE_TEMPORARY;
44 file_ = base::CreatePlatformFile(path, flags, &created, &error_code);
45 if (file_ == base::kInvalidPlatformFileValue)
[email protected]43a9e242011-04-06 17:42:4546 return false;
47
48 return true;
[email protected]fbd31eb2011-03-01 00:19:0249}
50
51bool TempFile::valid() const {
52 return file_ != base::kInvalidPlatformFileValue;
53}
54
55base::PlatformFile TempFile::handle() const {
56 return file_;
57}
58
[email protected]43a9e242011-04-06 17:42:4559bool TempFile::SetSize(size_t size) {
60 return base::TruncatePlatformFile(file_, size);
[email protected]fbd31eb2011-03-01 00:19:0261}
62
63// FileMapping
64
65FileMapping::FileMapping() : mapping_(NULL), view_(NULL) {
66}
67
68FileMapping::~FileMapping() {
69 Close();
70}
71
[email protected]43a9e242011-04-06 17:42:4572bool FileMapping::InitializeView(size_t size) {
[email protected]6c131952011-03-03 23:39:3273 DCHECK(view_ == NULL);
74 DCHECK(mapping_ != NULL);
75 view_ = ::MapViewOfFile(mapping_, FILE_MAP_WRITE, 0, 0, size);
[email protected]43a9e242011-04-06 17:42:4576 if (!view_) {
77 Close();
78 return false;
79 }
80 return true;
[email protected]6c131952011-03-03 23:39:3281}
82
[email protected]43a9e242011-04-06 17:42:4583bool FileMapping::Create(HANDLE file, size_t size) {
[email protected]fbd31eb2011-03-01 00:19:0284 DCHECK(file != INVALID_HANDLE_VALUE);
85 DCHECK(!valid());
86 mapping_ = ::CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 0, NULL);
[email protected]6c131952011-03-03 23:39:3287 if (!mapping_)
[email protected]43a9e242011-04-06 17:42:4588 return false;
[email protected]fbd31eb2011-03-01 00:19:0289
[email protected]43a9e242011-04-06 17:42:4590 return InitializeView(size);
[email protected]fbd31eb2011-03-01 00:19:0291}
92
93void FileMapping::Close() {
94 if (view_)
95 ::UnmapViewOfFile(view_);
96 if (mapping_)
97 ::CloseHandle(mapping_);
98 mapping_ = NULL;
99 view_ = NULL;
100}
101
102bool FileMapping::valid() const {
103 return view_ != NULL;
104}
105
106void* FileMapping::view() const {
107 return view_;
108}
109
110// TempMapping
111
112TempMapping::TempMapping() {
113}
114
115TempMapping::~TempMapping() {
116}
117
[email protected]43a9e242011-04-06 17:42:45118bool TempMapping::Initialize(size_t size) {
[email protected]fbd31eb2011-03-01 00:19:02119 // TODO(tommi): The assumption here is that the alignment of pointers (this)
120 // is as strict or stricter than the alignment of the element type. This is
121 // not always true, e.g. __m128 has 16-byte alignment.
122 size += sizeof(this);
[email protected]43a9e242011-04-06 17:42:45123 if (!file_.Create() ||
124 !file_.SetSize(size) ||
125 !mapping_.Create(file_.handle(), size)) {
126 file_.Close();
127 return false;
128 }
[email protected]fbd31eb2011-03-01 00:19:02129
[email protected]6c131952011-03-03 23:39:32130 TempMapping** write = reinterpret_cast<TempMapping**>(mapping_.view());
131 write[0] = this;
[email protected]43a9e242011-04-06 17:42:45132
133 return true;
[email protected]fbd31eb2011-03-01 00:19:02134}
135
136void* TempMapping::memory() const {
137 uint8* mem = reinterpret_cast<uint8*>(mapping_.view());
[email protected]5ace0a82012-07-25 21:26:12138 // The 'this' pointer is written at the start of mapping_.view(), so
139 // go past it. (See Initialize()).
[email protected]fbd31eb2011-03-01 00:19:02140 if (mem)
141 mem += sizeof(this);
142 DCHECK(mem);
143 return mem;
144}
145
[email protected]43a9e242011-04-06 17:42:45146bool TempMapping::valid() const {
147 return mapping_.valid();
148}
149
[email protected]fbd31eb2011-03-01 00:19:02150// static
151TempMapping* TempMapping::GetMappingFromPtr(void* mem) {
152 TempMapping* ret = NULL;
153 if (mem) {
154 ret = reinterpret_cast<TempMapping**>(mem)[-1];
155 }
156 DCHECK(ret);
157 return ret;
158}
159
160} // namespace courgette
161
162#endif // OS_WIN