ipc/chromium/src/base/shared_memory.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/shared_memory.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,206 @@
     1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#ifndef BASE_SHARED_MEMORY_H_
     1.9 +#define BASE_SHARED_MEMORY_H_
    1.10 +
    1.11 +#include "build/build_config.h"
    1.12 +
    1.13 +#if defined(OS_POSIX)
    1.14 +#include <sys/types.h>
    1.15 +#include <semaphore.h>
    1.16 +#include "base/file_descriptor_posix.h"
    1.17 +#endif
    1.18 +#include <string>
    1.19 +
    1.20 +#include "base/basictypes.h"
    1.21 +#include "base/process.h"
    1.22 +
    1.23 +namespace base {
    1.24 +
    1.25 +// SharedMemoryHandle is a platform specific type which represents
    1.26 +// the underlying OS handle to a shared memory segment.
    1.27 +#if defined(OS_WIN)
    1.28 +typedef HANDLE SharedMemoryHandle;
    1.29 +typedef HANDLE SharedMemoryLock;
    1.30 +#elif defined(OS_POSIX)
    1.31 +// A SharedMemoryId is sufficient to identify a given shared memory segment on a
    1.32 +// system, but insufficient to map it.
    1.33 +typedef FileDescriptor SharedMemoryHandle;
    1.34 +typedef ino_t SharedMemoryId;
    1.35 +// On POSIX, the lock is implemented as a lockf() on the mapped file,
    1.36 +// so no additional member (or definition of SharedMemoryLock) is
    1.37 +// needed.
    1.38 +#endif
    1.39 +
    1.40 +// Platform abstraction for shared memory.  Provides a C++ wrapper
    1.41 +// around the OS primitive for a memory mapped file.
    1.42 +class SharedMemory {
    1.43 + public:
    1.44 +  // Create a new SharedMemory object.
    1.45 +  SharedMemory();
    1.46 +
    1.47 +  // Create a new SharedMemory object from an existing, open
    1.48 +  // shared memory file.
    1.49 +  SharedMemory(SharedMemoryHandle handle, bool read_only);
    1.50 +
    1.51 +  // Create a new SharedMemory object from an existing, open
    1.52 +  // shared memory file that was created by a remote process and not shared
    1.53 +  // to the current process.
    1.54 +  SharedMemory(SharedMemoryHandle handle, bool read_only,
    1.55 +      base::ProcessHandle process);
    1.56 +
    1.57 +  // Destructor.  Will close any open files.
    1.58 +  ~SharedMemory();
    1.59 +
    1.60 +  // Return true iff the given handle is valid (i.e. not the distingished
    1.61 +  // invalid value; NULL for a HANDLE and -1 for a file descriptor)
    1.62 +  static bool IsHandleValid(const SharedMemoryHandle& handle);
    1.63 +
    1.64 +  // Return invalid handle (see comment above for exact definition).
    1.65 +  static SharedMemoryHandle NULLHandle();
    1.66 +
    1.67 +  // Creates or opens a shared memory segment based on a name.
    1.68 +  // If read_only is true, opens the memory as read-only.
    1.69 +  // If open_existing is true, and the shared memory already exists,
    1.70 +  // opens the existing shared memory and ignores the size parameter.
    1.71 +  // If name is the empty string, use a unique name.
    1.72 +  // Returns true on success, false on failure.
    1.73 +  bool Create(const std::string& name, bool read_only, bool open_existing,
    1.74 +              size_t size);
    1.75 +
    1.76 +  // Deletes resources associated with a shared memory segment based on name.
    1.77 +  // Not all platforms require this call.
    1.78 +  bool Delete(const std::wstring& name);
    1.79 +
    1.80 +  // Opens a shared memory segment based on a name.
    1.81 +  // If read_only is true, opens for read-only access.
    1.82 +  // If name is the empty string, use a unique name.
    1.83 +  // Returns true on success, false on failure.
    1.84 +  bool Open(const std::wstring& name, bool read_only);
    1.85 +
    1.86 +  // Maps the shared memory into the caller's address space.
    1.87 +  // Returns true on success, false otherwise.  The memory address
    1.88 +  // is accessed via the memory() accessor.
    1.89 +  bool Map(size_t bytes);
    1.90 +
    1.91 +  // Unmaps the shared memory from the caller's address space.
    1.92 +  // Returns true if successful; returns false on error or if the
    1.93 +  // memory is not mapped.
    1.94 +  bool Unmap();
    1.95 +
    1.96 +  // Get the size of the opened shared memory backing file.
    1.97 +  // Note:  This size is only available to the creator of the
    1.98 +  // shared memory, and not to those that opened shared memory
    1.99 +  // created externally.
   1.100 +  // Returns 0 if not opened or unknown.
   1.101 +  size_t max_size() const { return max_size_; }
   1.102 +
   1.103 +  // Gets a pointer to the opened memory space if it has been
   1.104 +  // Mapped via Map().  Returns NULL if it is not mapped.
   1.105 +  void *memory() const { return memory_; }
   1.106 +
   1.107 +  // Get access to the underlying OS handle for this segment.
   1.108 +  // Use of this handle for anything other than an opaque
   1.109 +  // identifier is not portable.
   1.110 +  SharedMemoryHandle handle() const;
   1.111 +
   1.112 +#if defined(OS_POSIX)
   1.113 +  // Return a unique identifier for this shared memory segment. Inode numbers
   1.114 +  // are technically only unique to a single filesystem. However, we always
   1.115 +  // allocate shared memory backing files from the same directory, so will end
   1.116 +  // up on the same filesystem.
   1.117 +  SharedMemoryId id() const { return inode_; }
   1.118 +#endif
   1.119 +
   1.120 +  // Closes the open shared memory segment.
   1.121 +  // It is safe to call Close repeatedly.
   1.122 +  void Close();
   1.123 +
   1.124 +  // Share the shared memory to another process.  Attempts
   1.125 +  // to create a platform-specific new_handle which can be
   1.126 +  // used in a remote process to access the shared memory
   1.127 +  // file.  new_handle is an ouput parameter to receive
   1.128 +  // the handle for use in the remote process.
   1.129 +  // Returns true on success, false otherwise.
   1.130 +  bool ShareToProcess(base::ProcessHandle process,
   1.131 +                      SharedMemoryHandle* new_handle) {
   1.132 +    return ShareToProcessCommon(process, new_handle, false);
   1.133 +  }
   1.134 +
   1.135 +  // Logically equivalent to:
   1.136 +  //   bool ok = ShareToProcess(process, new_handle);
   1.137 +  //   Close();
   1.138 +  //   return ok;
   1.139 +  // Note that the memory is unmapped by calling this method, regardless of the
   1.140 +  // return value.
   1.141 +  bool GiveToProcess(ProcessHandle process,
   1.142 +                     SharedMemoryHandle* new_handle) {
   1.143 +    return ShareToProcessCommon(process, new_handle, true);
   1.144 +  }
   1.145 +
   1.146 +  // Lock the shared memory.
   1.147 +  // This is a cross-process lock which may be recursively
   1.148 +  // locked by the same thread.
   1.149 +  // TODO(port):
   1.150 +  // WARNING: on POSIX the lock only works across processes, not
   1.151 +  // across threads.  2 threads in the same process can both grab the
   1.152 +  // lock at the same time.  There are several solutions for this
   1.153 +  // (futex, lockf+anon_semaphore) but none are both clean and common
   1.154 +  // across Mac and Linux.
   1.155 +  void Lock();
   1.156 +
   1.157 +  // Release the shared memory lock.
   1.158 +  void Unlock();
   1.159 +
   1.160 + private:
   1.161 +#if defined(OS_POSIX)
   1.162 +  bool CreateOrOpen(const std::wstring &name, int posix_flags, size_t size);
   1.163 +  bool FilenameForMemoryName(const std::wstring &memname,
   1.164 +                             std::wstring *filename);
   1.165 +  void LockOrUnlockCommon(int function);
   1.166 +
   1.167 +#endif
   1.168 +  bool ShareToProcessCommon(ProcessHandle process,
   1.169 +                            SharedMemoryHandle* new_handle,
   1.170 +                            bool close_self);
   1.171 +
   1.172 +#if defined(OS_WIN)
   1.173 +  std::wstring       name_;
   1.174 +  HANDLE             mapped_file_;
   1.175 +#elif defined(OS_POSIX)
   1.176 +  int                mapped_file_;
   1.177 +  ino_t              inode_;
   1.178 +#endif
   1.179 +  void*              memory_;
   1.180 +  bool               read_only_;
   1.181 +  size_t             max_size_;
   1.182 +#if !defined(OS_POSIX)
   1.183 +  SharedMemoryLock   lock_;
   1.184 +#endif
   1.185 +
   1.186 +  DISALLOW_EVIL_CONSTRUCTORS(SharedMemory);
   1.187 +};
   1.188 +
   1.189 +// A helper class that acquires the shared memory lock while
   1.190 +// the SharedMemoryAutoLock is in scope.
   1.191 +class SharedMemoryAutoLock {
   1.192 + public:
   1.193 +  explicit SharedMemoryAutoLock(SharedMemory* shared_memory)
   1.194 +      : shared_memory_(shared_memory) {
   1.195 +    shared_memory_->Lock();
   1.196 +  }
   1.197 +
   1.198 +  ~SharedMemoryAutoLock() {
   1.199 +    shared_memory_->Unlock();
   1.200 +  }
   1.201 +
   1.202 + private:
   1.203 +  SharedMemory* shared_memory_;
   1.204 +  DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryAutoLock);
   1.205 +};
   1.206 +
   1.207 +}  // namespace base
   1.208 +
   1.209 +#endif  // BASE_SHARED_MEMORY_H_

mercurial