|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim: sw=2 ts=8 et : |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include <android/log.h> |
|
9 #include <errno.h> |
|
10 #include <fcntl.h> |
|
11 #include <string.h> |
|
12 #include <sys/ioctl.h> |
|
13 #include <sys/mman.h> |
|
14 #include <sys/stat.h> |
|
15 #include <sys/types.h> |
|
16 #include <unistd.h> |
|
17 |
|
18 #include "base/process_util.h" |
|
19 |
|
20 #include "SharedMemoryBasic.h" |
|
21 |
|
22 // |
|
23 // Temporarily go directly to the kernel interface until we can |
|
24 // interact better with libcutils. |
|
25 // |
|
26 #include <linux/ashmem.h> |
|
27 |
|
28 namespace mozilla { |
|
29 namespace ipc { |
|
30 |
|
31 static void |
|
32 LogError(const char* what) |
|
33 { |
|
34 __android_log_print(ANDROID_LOG_ERROR, "Gecko", |
|
35 "%s: %s (%d)", what, strerror(errno), errno); |
|
36 } |
|
37 |
|
38 SharedMemoryBasic::SharedMemoryBasic() |
|
39 : mShmFd(-1) |
|
40 , mMemory(nullptr) |
|
41 { } |
|
42 |
|
43 SharedMemoryBasic::SharedMemoryBasic(const Handle& aHandle) |
|
44 : mShmFd(aHandle.fd) |
|
45 , mMemory(nullptr) |
|
46 { } |
|
47 |
|
48 SharedMemoryBasic::~SharedMemoryBasic() |
|
49 { |
|
50 Unmap(); |
|
51 Destroy(); |
|
52 } |
|
53 |
|
54 bool |
|
55 SharedMemoryBasic::Create(size_t aNbytes) |
|
56 { |
|
57 NS_ABORT_IF_FALSE(-1 == mShmFd, "Already Create()d"); |
|
58 |
|
59 // Carve a new instance off of /dev/ashmem |
|
60 int shmfd = open("/" ASHMEM_NAME_DEF, O_RDWR, 0600); |
|
61 if (-1 == shmfd) { |
|
62 LogError("ShmemAndroid::Create():open"); |
|
63 return false; |
|
64 } |
|
65 |
|
66 if (ioctl(shmfd, ASHMEM_SET_SIZE, aNbytes)) { |
|
67 LogError("ShmemAndroid::Unmap():ioctl(SET_SIZE)"); |
|
68 close(shmfd); |
|
69 return false; |
|
70 } |
|
71 |
|
72 mShmFd = shmfd; |
|
73 Created(aNbytes); |
|
74 return true; |
|
75 } |
|
76 |
|
77 bool |
|
78 SharedMemoryBasic::Map(size_t nBytes) |
|
79 { |
|
80 NS_ABORT_IF_FALSE(nullptr == mMemory, "Already Map()d"); |
|
81 |
|
82 mMemory = mmap(nullptr, nBytes, |
|
83 PROT_READ | PROT_WRITE, |
|
84 MAP_SHARED, |
|
85 mShmFd, |
|
86 0); |
|
87 if (MAP_FAILED == mMemory) { |
|
88 LogError("ShmemAndroid::Map()"); |
|
89 mMemory = nullptr; |
|
90 return false; |
|
91 } |
|
92 |
|
93 Mapped(nBytes); |
|
94 return true; |
|
95 } |
|
96 |
|
97 bool |
|
98 SharedMemoryBasic::ShareToProcess(base::ProcessHandle/*unused*/, |
|
99 Handle* aNewHandle) |
|
100 { |
|
101 NS_ABORT_IF_FALSE(mShmFd >= 0, "Should have been Create()d by now"); |
|
102 |
|
103 int shmfdDup = dup(mShmFd); |
|
104 if (-1 == shmfdDup) { |
|
105 LogError("ShmemAndroid::ShareToProcess()"); |
|
106 return false; |
|
107 } |
|
108 |
|
109 aNewHandle->fd = shmfdDup; |
|
110 aNewHandle->auto_close = true; |
|
111 return true; |
|
112 } |
|
113 |
|
114 void |
|
115 SharedMemoryBasic::Unmap() |
|
116 { |
|
117 if (!mMemory) { |
|
118 return; |
|
119 } |
|
120 |
|
121 if (munmap(mMemory, Size())) { |
|
122 LogError("ShmemAndroid::Unmap()"); |
|
123 } |
|
124 mMemory = nullptr; |
|
125 } |
|
126 |
|
127 void |
|
128 SharedMemoryBasic::Destroy() |
|
129 { |
|
130 if (mShmFd > 0) { |
|
131 close(mShmFd); |
|
132 } |
|
133 } |
|
134 |
|
135 } // namespace ipc |
|
136 } // namespace mozilla |