ipc/glue/SharedMemorySysV.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:774180047b15
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 #ifndef mozilla_ipc_SharedMemorySysV_h
9 #define mozilla_ipc_SharedMemorySysV_h
10
11 #if (defined(OS_LINUX) && !defined(ANDROID)) || defined(OS_BSD)
12
13 // SysV shared memory isn't available on Windows, but we define the
14 // following macro so that #ifdefs are clearer (compared to #ifdef
15 // OS_LINUX).
16 #define MOZ_HAVE_SHAREDMEMORYSYSV
17
18 #include "SharedMemory.h"
19
20 #include "nsDebug.h"
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28
29 //
30 // This is a low-level wrapper around platform shared memory. Don't
31 // use it directly; use Shmem allocated through IPDL interfaces.
32 //
33
34 namespace mozilla {
35 namespace ipc {
36
37
38 class SharedMemorySysV : public SharedMemory
39 {
40 public:
41 typedef int Handle;
42
43 SharedMemorySysV() :
44 mHandle(-1),
45 mData(nullptr)
46 {
47 }
48
49 SharedMemorySysV(Handle aHandle) :
50 mHandle(aHandle),
51 mData(nullptr)
52 {
53 }
54
55 virtual ~SharedMemorySysV()
56 {
57 shmdt(mData);
58 mHandle = -1;
59 mData = nullptr;
60 }
61
62 virtual bool Create(size_t aNbytes) MOZ_OVERRIDE
63 {
64 int id = shmget(IPC_PRIVATE, aNbytes, IPC_CREAT | 0600);
65 if (id == -1)
66 return false;
67
68 mHandle = id;
69 mAllocSize = aNbytes;
70 Created(aNbytes);
71
72 return Map(aNbytes);
73 }
74
75 virtual bool Map(size_t nBytes) MOZ_OVERRIDE
76 {
77 // already mapped
78 if (mData)
79 return true;
80
81 if (!IsHandleValid(mHandle))
82 return false;
83
84 void* mem = shmat(mHandle, nullptr, 0);
85 if (mem == (void*) -1) {
86 char warning[256];
87 ::snprintf(warning, sizeof(warning)-1,
88 "shmat(): %s (%d)\n", strerror(errno), errno);
89
90 NS_WARNING(warning);
91
92 return false;
93 }
94
95 // Mark the handle as deleted so that, should this process go away, the
96 // segment is cleaned up.
97 shmctl(mHandle, IPC_RMID, 0);
98
99 mData = mem;
100
101 #ifdef DEBUG
102 struct shmid_ds info;
103 if (shmctl(mHandle, IPC_STAT, &info) < 0)
104 return false;
105
106 NS_ABORT_IF_FALSE(nBytes <= info.shm_segsz,
107 "Segment doesn't have enough space!");
108 #endif
109
110 Mapped(nBytes);
111 return true;
112 }
113
114 virtual void* memory() const MOZ_OVERRIDE
115 {
116 return mData;
117 }
118
119 virtual SharedMemoryType Type() const MOZ_OVERRIDE
120 {
121 return TYPE_SYSV;
122 }
123
124 Handle GetHandle() const
125 {
126 NS_ABORT_IF_FALSE(IsHandleValid(mHandle), "invalid handle");
127 return mHandle;
128 }
129
130 static Handle NULLHandle()
131 {
132 return -1;
133 }
134
135 static bool IsHandleValid(Handle aHandle)
136 {
137 return aHandle != -1;
138 }
139
140 private:
141 Handle mHandle;
142 void* mData;
143 };
144
145 } // namespace ipc
146 } // namespace mozilla
147
148 #endif // OS_LINUX
149
150 #endif // ifndef mozilla_ipc_SharedMemorySysV_h

mercurial