1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/glue/SharedMemorySysV.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,150 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=8 et : 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#ifndef mozilla_ipc_SharedMemorySysV_h 1.12 +#define mozilla_ipc_SharedMemorySysV_h 1.13 + 1.14 +#if (defined(OS_LINUX) && !defined(ANDROID)) || defined(OS_BSD) 1.15 + 1.16 +// SysV shared memory isn't available on Windows, but we define the 1.17 +// following macro so that #ifdefs are clearer (compared to #ifdef 1.18 +// OS_LINUX). 1.19 +#define MOZ_HAVE_SHAREDMEMORYSYSV 1.20 + 1.21 +#include "SharedMemory.h" 1.22 + 1.23 +#include "nsDebug.h" 1.24 + 1.25 +#include <errno.h> 1.26 +#include <fcntl.h> 1.27 +#include <stdio.h> 1.28 +#include <string.h> 1.29 +#include <sys/ipc.h> 1.30 +#include <sys/shm.h> 1.31 + 1.32 +// 1.33 +// This is a low-level wrapper around platform shared memory. Don't 1.34 +// use it directly; use Shmem allocated through IPDL interfaces. 1.35 +// 1.36 + 1.37 +namespace mozilla { 1.38 +namespace ipc { 1.39 + 1.40 + 1.41 +class SharedMemorySysV : public SharedMemory 1.42 +{ 1.43 +public: 1.44 + typedef int Handle; 1.45 + 1.46 + SharedMemorySysV() : 1.47 + mHandle(-1), 1.48 + mData(nullptr) 1.49 + { 1.50 + } 1.51 + 1.52 + SharedMemorySysV(Handle aHandle) : 1.53 + mHandle(aHandle), 1.54 + mData(nullptr) 1.55 + { 1.56 + } 1.57 + 1.58 + virtual ~SharedMemorySysV() 1.59 + { 1.60 + shmdt(mData); 1.61 + mHandle = -1; 1.62 + mData = nullptr; 1.63 + } 1.64 + 1.65 + virtual bool Create(size_t aNbytes) MOZ_OVERRIDE 1.66 + { 1.67 + int id = shmget(IPC_PRIVATE, aNbytes, IPC_CREAT | 0600); 1.68 + if (id == -1) 1.69 + return false; 1.70 + 1.71 + mHandle = id; 1.72 + mAllocSize = aNbytes; 1.73 + Created(aNbytes); 1.74 + 1.75 + return Map(aNbytes); 1.76 + } 1.77 + 1.78 + virtual bool Map(size_t nBytes) MOZ_OVERRIDE 1.79 + { 1.80 + // already mapped 1.81 + if (mData) 1.82 + return true; 1.83 + 1.84 + if (!IsHandleValid(mHandle)) 1.85 + return false; 1.86 + 1.87 + void* mem = shmat(mHandle, nullptr, 0); 1.88 + if (mem == (void*) -1) { 1.89 + char warning[256]; 1.90 + ::snprintf(warning, sizeof(warning)-1, 1.91 + "shmat(): %s (%d)\n", strerror(errno), errno); 1.92 + 1.93 + NS_WARNING(warning); 1.94 + 1.95 + return false; 1.96 + } 1.97 + 1.98 + // Mark the handle as deleted so that, should this process go away, the 1.99 + // segment is cleaned up. 1.100 + shmctl(mHandle, IPC_RMID, 0); 1.101 + 1.102 + mData = mem; 1.103 + 1.104 +#ifdef DEBUG 1.105 + struct shmid_ds info; 1.106 + if (shmctl(mHandle, IPC_STAT, &info) < 0) 1.107 + return false; 1.108 + 1.109 + NS_ABORT_IF_FALSE(nBytes <= info.shm_segsz, 1.110 + "Segment doesn't have enough space!"); 1.111 +#endif 1.112 + 1.113 + Mapped(nBytes); 1.114 + return true; 1.115 + } 1.116 + 1.117 + virtual void* memory() const MOZ_OVERRIDE 1.118 + { 1.119 + return mData; 1.120 + } 1.121 + 1.122 + virtual SharedMemoryType Type() const MOZ_OVERRIDE 1.123 + { 1.124 + return TYPE_SYSV; 1.125 + } 1.126 + 1.127 + Handle GetHandle() const 1.128 + { 1.129 + NS_ABORT_IF_FALSE(IsHandleValid(mHandle), "invalid handle"); 1.130 + return mHandle; 1.131 + } 1.132 + 1.133 + static Handle NULLHandle() 1.134 + { 1.135 + return -1; 1.136 + } 1.137 + 1.138 + static bool IsHandleValid(Handle aHandle) 1.139 + { 1.140 + return aHandle != -1; 1.141 + } 1.142 + 1.143 +private: 1.144 + Handle mHandle; 1.145 + void* mData; 1.146 +}; 1.147 + 1.148 +} // namespace ipc 1.149 +} // namespace mozilla 1.150 + 1.151 +#endif // OS_LINUX 1.152 + 1.153 +#endif // ifndef mozilla_ipc_SharedMemorySysV_h