Chromium Code Reviews| Index: base/shared_memory_posix.cc |
| diff --git a/base/shared_memory_posix.cc b/base/shared_memory_posix.cc |
| index 7a238ed880b12a641b7461fc01285b7d169d9cc2..95216843e1af42b76527b6a34bcce0e0e8ebab3f 100644 |
| --- a/base/shared_memory_posix.cc |
| +++ b/base/shared_memory_posix.cc |
| @@ -17,6 +17,14 @@ |
| #include "base/threading/thread_restrictions.h" |
| #include "base/utf_string_conversions.h" |
| +#if defined(OS_ANDROID) |
| +// For Android, we use ashmem to implement SharedMemory. ashmem_create_region |
| +// will automatically pin the region. We never explicitly call pin/unpin. When |
| +// all the file descriptors from different processes associated with the region |
| +// are closed, the memory buffer will go away. |
| +#include "third_party/ashmem/ashmem.h" |
| +#endif |
| + |
| #if defined(OS_MACOSX) |
| #include "base/mac/foundation_util.h" |
| #endif // OS_MACOSX |
| @@ -103,6 +111,26 @@ bool SharedMemory::CreateAnonymous(uint32 size) { |
| // of mem_filename after FilePathForMemoryName(). |
| bool SharedMemory::CreateNamed(const std::string& name, |
| bool open_existing, uint32 size) { |
| +#if defined(OS_ANDROID) |
|
darin (slow to review)
2011/06/17 16:29:29
it seems like almost all of the code in this file
michaelbai
2011/06/17 22:41:29
I moved fully android specific methods into shared
|
| + DCHECK(mapped_file_ == -1); |
|
joth
2011/06/17 11:25:54
DCHECK_EQ(-1, mapped_file_)
michaelbai
2011/06/17 22:41:29
Done.
|
| + |
| + // "name" is just a label in ashmem. It is visible in /proc/pid/maps. |
| + mapped_file_ = ashmem_create_region(name.data(), size); |
|
joth
2011/06/17 11:25:54
name.c_str(), to ensure it is null terminated
michaelbai
2011/06/17 22:41:29
Done, thanks
|
| + if (-1 == mapped_file_) { |
| + LOG(ERROR) << "Shared memory creation failed"; |
|
darin (slow to review)
2011/06/17 16:29:29
nit: do you really need these log statements to be
michaelbai
2011/06/17 22:41:29
Done.
|
| + return false; |
| + } |
| + |
| + int err = ashmem_set_prot_region(mapped_file_, |
| + PROT_READ | PROT_WRITE | PROT_EXEC); |
| + if (err < 0) { |
| + LOG(ERROR) << "Error " << err << " when setting protection of ashmem"; |
| + return false; |
| + } |
| + created_size_ = size; |
| + |
| + return true; |
| +#else |
| DCHECK_EQ(-1, mapped_file_); |
| if (size == 0) return false; |
| @@ -171,12 +199,19 @@ bool SharedMemory::CreateNamed(const std::string& name, |
| } |
| return PrepareMapFile(fp); |
| +#endif // defined(OS_ANDROID) |
| } |
| // Our current implementation of shmem is with mmap()ing of files. |
| // These files need to be deleted explicitly. |
| // In practice this call is only needed for unit tests. |
| bool SharedMemory::Delete(const std::string& name) { |
| +#if defined(OS_ANDROID) |
| + // ashmem doesn't support name mapping |
| + NOTIMPLEMENTED(); |
| + return false; |
| +#endif |
| + |
| FilePath path; |
| if (!FilePathForMemoryName(name, &path)) |
| return false; |
| @@ -196,6 +231,12 @@ bool SharedMemory::Open(const std::string& name, bool read_only) { |
| read_only_ = read_only; |
| +#if defined(OS_ANDROID) |
| + // ashmem doesn't support name mapping |
| + NOTIMPLEMENTED(); |
| + return false; |
| +#endif |
| + |
| const char *mode = read_only ? "r" : "r+"; |
| FILE *fp = file_util::OpenFile(path, mode); |
| return PrepareMapFile(fp); |
| @@ -205,6 +246,21 @@ bool SharedMemory::Map(uint32 bytes) { |
| if (mapped_file_ == -1) |
| return false; |
| +#if defined(OS_ANDROID) |
| + const uint32 ashmem_bytes = ashmem_get_size_region(mapped_file_); |
|
joth
2011/06/17 11:25:54
ashmem_get_size_region appears to return 'int', pr
michaelbai
2011/06/17 22:41:29
Done.
|
| + DCHECK_GE(ashmem_bytes, bytes); |
| + if (bytes == 0) { |
| + // The caller wants to determine the map region size from ashmem. |
| + bytes = ashmem_bytes; |
| + // HACK: we set the created size here so that it is available in |
| + // transport_dib_android.cc. Other choices would be to add an accessor to |
| + // mapped_size_ (apparently undesirable, see the comment for created_size() |
| + // in shared_memory.h) or to duplicate the ashmem_get_size_region call above |
| + // in TransportDIB::Map(). |
|
joth
2011/06/17 11:25:54
can we fix this? It seems to be abusing both Map(0
michaelbai
2011/06/17 22:41:29
Method added, I will have another CL to handle the
|
| + created_size_ = bytes; |
| + } |
| +#endif |
| + |
| memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), |
| MAP_SHARED, mapped_file_, 0); |
| @@ -240,6 +296,16 @@ void SharedMemory::Close() { |
| } |
| } |
| +// The lockf() function is not available on Android; we translate to flock(). |
| +#if defined(OS_ANDROID) |
| +#define F_LOCK LOCK_EX |
| +#define F_ULOCK LOCK_UN |
| +static inline int lockf(int fd, int cmd, off_t ignored_len) { |
|
joth
2011/06/17 11:25:54
nit: use anon namespace rather than static (unless
michaelbai
2011/06/17 22:41:29
Done.
|
| + return flock(fd, cmd); |
| +} |
| +#endif |
| + |
| + |
| void SharedMemory::Lock() { |
| LockOrUnlockCommon(F_LOCK); |
| } |
| @@ -248,6 +314,7 @@ void SharedMemory::Unlock() { |
| LockOrUnlockCommon(F_ULOCK); |
| } |
| +#if !defined(OS_ANDROID) |
| bool SharedMemory::PrepareMapFile(FILE *fp) { |
| DCHECK_EQ(-1, mapped_file_); |
| if (fp == NULL) return false; |
| @@ -276,6 +343,7 @@ bool SharedMemory::PrepareMapFile(FILE *fp) { |
| return true; |
| } |
| +#endif |
| // For the given shmem named |mem_name|, return a filename to mmap() |
| // (and possibly create). Modifies |filename|. Return false on |