Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: base/shared_memory_posix.cc

Issue 204024: posix: clean up shared memory code (Closed)
Patch Set: ok Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/shared_memory.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/shared_memory.h" 5 #include "base/shared_memory.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <sys/mman.h> 9 #include <sys/mman.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 return false; 89 return false;
90 90
91 max_size_ = size; 91 max_size_ = size;
92 return true; 92 return true;
93 } 93 }
94 94
95 // Our current implementation of shmem is with mmap()ing of files. 95 // Our current implementation of shmem is with mmap()ing of files.
96 // These files need to be deleted explicitly. 96 // These files need to be deleted explicitly.
97 // In practice this call is only needed for unit tests. 97 // In practice this call is only needed for unit tests.
98 bool SharedMemory::Delete(const std::wstring& name) { 98 bool SharedMemory::Delete(const std::wstring& name) {
99 std::wstring mem_filename; 99 FilePath path;
100 if (FilenameForMemoryName(name, &mem_filename) == false) 100 if (!FilePathForMemoryName(name, &path))
101 return false; 101 return false;
102 102
103 FilePath path(WideToUTF8(mem_filename));
104 if (file_util::PathExists(path)) { 103 if (file_util::PathExists(path)) {
105 return file_util::Delete(path, false); 104 return file_util::Delete(path, false);
106 } 105 }
107 106
108 // Doesn't exist, so success. 107 // Doesn't exist, so success.
109 return true; 108 return true;
110 } 109 }
111 110
112 bool SharedMemory::Open(const std::wstring &name, bool read_only) { 111 bool SharedMemory::Open(const std::wstring &name, bool read_only) {
113 read_only_ = read_only; 112 read_only_ = read_only;
114 113
115 int posix_flags = 0; 114 int posix_flags = 0;
116 posix_flags |= read_only ? O_RDONLY : O_RDWR; 115 posix_flags |= read_only ? O_RDONLY : O_RDWR;
117 116
118 return CreateOrOpen(name, posix_flags, 0); 117 return CreateOrOpen(name, posix_flags, 0);
119 } 118 }
120 119
121 // For the given shmem named |memname|, return a filename to mmap() 120 // For the given shmem named |memname|, return a filename to mmap()
122 // (and possibly create). Modifies |filename|. Return false on 121 // (and possibly create). Modifies |filename|. Return false on
123 // error, or true of we are happy. 122 // error, or true of we are happy.
124 bool SharedMemory::FilenameForMemoryName(const std::wstring &memname, 123 bool SharedMemory::FilePathForMemoryName(const std::wstring& memname,
125 std::wstring *filename) { 124 FilePath* path) {
126 std::wstring mem_filename;
127
128 // mem_name will be used for a filename; make sure it doesn't 125 // mem_name will be used for a filename; make sure it doesn't
129 // contain anything which will confuse us. 126 // contain anything which will confuse us.
130 DCHECK(memname.find_first_of(L"/") == std::string::npos); 127 DCHECK(memname.find_first_of(L"/") == std::string::npos);
131 DCHECK(memname.find_first_of(L"\0") == std::string::npos); 128 DCHECK(memname.find_first_of(L"\0") == std::string::npos);
132 129
133 FilePath temp_dir; 130 FilePath temp_dir;
134 if (file_util::GetShmemTempDir(&temp_dir) == false) 131 if (file_util::GetShmemTempDir(&temp_dir) == false)
135 return false; 132 return false;
136 133
137 mem_filename = UTF8ToWide(temp_dir.value()); 134 *path = temp_dir.AppendASCII("com.google.chrome.shmem." +
138 file_util::AppendToPath(&mem_filename, L"com.google.chrome.shmem." + memname); 135 WideToASCII(memname));
139 *filename = mem_filename;
140 return true; 136 return true;
141 } 137 }
142 138
143 // Chromium mostly only use the unique/private shmem as specified by 139 // Chromium mostly only use the unique/private shmem as specified by
144 // "name == L"". The exception is in the StatsTable. 140 // "name == L"". The exception is in the StatsTable.
145 // TODO(jrg): there is no way to "clean up" all unused named shmem if 141 // TODO(jrg): there is no way to "clean up" all unused named shmem if
146 // we restart from a crash. (That isn't a new problem, but it is a problem.) 142 // we restart from a crash. (That isn't a new problem, but it is a problem.)
147 // In case we want to delete it later, it may be useful to save the value 143 // In case we want to delete it later, it may be useful to save the value
148 // of mem_filename after FilenameForMemoryName(). 144 // of mem_filename after FilePathForMemoryName().
149 bool SharedMemory::CreateOrOpen(const std::wstring &name, 145 bool SharedMemory::CreateOrOpen(const std::wstring &name,
150 int posix_flags, size_t size) { 146 int posix_flags, size_t size) {
151 DCHECK(mapped_file_ == -1); 147 DCHECK(mapped_file_ == -1);
152 148
153 file_util::ScopedFILE file_closer; 149 file_util::ScopedFILE file_closer;
154 FILE *fp; 150 FILE *fp;
155 151
152 FilePath path;
156 if (name == L"") { 153 if (name == L"") {
157 // It doesn't make sense to have a read-only private piece of shmem 154 // It doesn't make sense to have a read-only private piece of shmem
158 DCHECK(posix_flags & (O_RDWR | O_WRONLY)); 155 DCHECK(posix_flags & (O_RDWR | O_WRONLY));
159 156
160 FilePath path; 157 // Q: Why not use the shm_open() etc. APIs?
158 // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU
161 fp = file_util::CreateAndOpenTemporaryShmemFile(&path); 159 fp = file_util::CreateAndOpenTemporaryShmemFile(&path);
162 160
163 // Deleting the file prevents anyone else from mapping it in 161 // Deleting the file prevents anyone else from mapping it in
164 // (making it private), and prevents the need for cleanup (once 162 // (making it private), and prevents the need for cleanup (once
165 // the last fd is closed, it is truly freed). 163 // the last fd is closed, it is truly freed).
166 file_util::Delete(path, false); 164 file_util::Delete(path, false);
167 } else { 165 } else {
168 std::wstring mem_filename; 166 if (!FilePathForMemoryName(name, &path))
169 if (FilenameForMemoryName(name, &mem_filename) == false)
170 return false; 167 return false;
171 168
172 std::string mode; 169 std::string mode;
173 switch (posix_flags) { 170 switch (posix_flags) {
174 case (O_RDWR | O_CREAT): 171 case (O_RDWR | O_CREAT):
175 // Careful: "w+" will truncate if it already exists. 172 // Careful: "w+" will truncate if it already exists.
176 mode = "a+"; 173 mode = "a+";
177 break; 174 break;
178 case O_RDWR: 175 case O_RDWR:
179 mode = "r+"; 176 mode = "r+";
180 break; 177 break;
181 case O_RDONLY: 178 case O_RDONLY:
182 mode = "r"; 179 mode = "r";
183 break; 180 break;
184 default: 181 default:
185 NOTIMPLEMENTED(); 182 NOTIMPLEMENTED();
186 break; 183 break;
187 } 184 }
188 185
189 fp = file_util::OpenFile(mem_filename, mode.c_str()); 186 fp = file_util::OpenFile(path, mode.c_str());
190 } 187 }
191 188
192 if (fp == NULL) 189 if (fp == NULL) {
190 if (posix_flags & O_CREAT)
191 LOG(ERROR) << "Creating shared memory in " << path.value() << " failed: "
192 << strerror(errno);
193 return false; 193 return false;
194 }
195
194 file_closer.reset(fp); // close when we go out of scope 196 file_closer.reset(fp); // close when we go out of scope
195 197
196 // Make sure the (new) file is the right size. 198 // Make sure the (new) file is the right size.
197 if (size && (posix_flags & (O_RDWR | O_CREAT))) { 199 if (size && (posix_flags & (O_RDWR | O_CREAT))) {
198 // Get current size. 200 // Get current size.
199 struct stat stat; 201 struct stat stat;
200 if (fstat(fileno(fp), &stat) != 0) 202 if (fstat(fileno(fp), &stat) != 0)
201 return false; 203 return false;
202 const size_t current_size = stat.st_size; 204 const size_t current_size = stat.st_size;
203 if (current_size != size) { 205 if (current_size != size) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 302
301 void SharedMemory::Unlock() { 303 void SharedMemory::Unlock() {
302 LockOrUnlockCommon(F_ULOCK); 304 LockOrUnlockCommon(F_ULOCK);
303 } 305 }
304 306
305 SharedMemoryHandle SharedMemory::handle() const { 307 SharedMemoryHandle SharedMemory::handle() const {
306 return FileDescriptor(mapped_file_, false); 308 return FileDescriptor(mapped_file_, false);
307 } 309 }
308 310
309 } // namespace base 311 } // namespace base
OLDNEW
« no previous file with comments | « base/shared_memory.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698