Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_MEMORY_SHARED_MEMORY_H_
      6 #define BASE_MEMORY_SHARED_MEMORY_H_
      7 
      8 #include <stddef.h>
      9 
     10 #include <string>
     11 
     12 #include "base/base_export.h"
     13 #include "base/macros.h"
     14 #include "base/memory/shared_memory_handle.h"
     15 #include "base/process/process_handle.h"
     16 #include "build/build_config.h"
     17 
     18 #if defined(OS_POSIX)
     19 #include <stdio.h>
     20 #include <sys/types.h>
     21 #include <semaphore.h>
     22 #include "base/file_descriptor_posix.h"
     23 #include "base/files/file_util.h"
     24 #include "base/files/scoped_file.h"
     25 #endif
     26 
     27 namespace base {
     28 
     29 class FilePath;
     30 
     31 // Options for creating a shared memory object.
     32 struct BASE_EXPORT SharedMemoryCreateOptions {
     33   SharedMemoryCreateOptions();
     34 
     35 #if defined(OS_MACOSX) && !defined(OS_IOS)
     36   // The type of OS primitive that should back the SharedMemory object.
     37   SharedMemoryHandle::Type type;
     38 #else
     39   // DEPRECATED (crbug.com/345734):
     40   // If NULL, the object is anonymous.  This pointer is owned by the caller
     41   // and must live through the call to Create().
     42   const std::string* name_deprecated;
     43 
     44   // DEPRECATED (crbug.com/345734):
     45   // If true, and the shared memory already exists, Create() will open the
     46   // existing shared memory and ignore the size parameter.  If false,
     47   // shared memory must not exist.  This flag is meaningless unless
     48   // name_deprecated is non-NULL.
     49   bool open_existing_deprecated;
     50 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
     51 
     52   // Size of the shared memory object to be created.
     53   // When opening an existing object, this has no effect.
     54   size_t size;
     55 
     56   // If true, mappings might need to be made executable later.
     57   bool executable;
     58 
     59   // If true, the file can be shared read-only to a process.
     60   bool share_read_only;
     61 };
     62 
     63 // Platform abstraction for shared memory.  Provides a C++ wrapper
     64 // around the OS primitive for a memory mapped file.
     65 class BASE_EXPORT SharedMemory {
     66  public:
     67   SharedMemory();
     68 
     69 #if defined(OS_WIN)
     70   // Similar to the default constructor, except that this allows for
     71   // calling LockDeprecated() to acquire the named mutex before either Create or
     72   // Open are called on Windows.
     73   explicit SharedMemory(const std::wstring& name);
     74 #endif
     75 
     76   // Create a new SharedMemory object from an existing, open
     77   // shared memory file.
     78   //
     79   // WARNING: This does not reduce the OS-level permissions on the handle; it
     80   // only affects how the SharedMemory will be mmapped.  Use
     81   // ShareReadOnlyToProcess to drop permissions.  TODO(jln,jyasskin): DCHECK
     82   // that |read_only| matches the permissions of the handle.
     83   SharedMemory(const SharedMemoryHandle& handle, bool read_only);
     84 
     85 #if defined(OS_WIN)
     86   // Create a new SharedMemory object from an existing, open
     87   // shared memory file that was created by a remote process and not shared
     88   // to the current process.
     89   SharedMemory(const SharedMemoryHandle& handle,
     90                bool read_only,
     91                ProcessHandle process);
     92 #endif
     93 
     94   // Closes any open files.
     95   ~SharedMemory();
     96 
     97   // Return true iff the given handle is valid (i.e. not the distingished
     98   // invalid value; NULL for a HANDLE and -1 for a file descriptor)
     99   static bool IsHandleValid(const SharedMemoryHandle& handle);
    100 
    101   // Returns invalid handle (see comment above for exact definition).
    102   static SharedMemoryHandle NULLHandle();
    103 
    104   // Closes a shared memory handle.
    105   static void CloseHandle(const SharedMemoryHandle& handle);
    106 
    107   // Returns the maximum number of handles that can be open at once per process.
    108   static size_t GetHandleLimit();
    109 
    110   // Duplicates The underlying OS primitive. Returns NULLHandle() on failure.
    111   // The caller is responsible for destroying the duplicated OS primitive.
    112   static SharedMemoryHandle DuplicateHandle(const SharedMemoryHandle& handle);
    113 
    114 #if defined(OS_POSIX)
    115   // This method requires that the SharedMemoryHandle is backed by a POSIX fd.
    116   static int GetFdFromSharedMemoryHandle(const SharedMemoryHandle& handle);
    117 #endif
    118 
    119 #if defined(OS_POSIX) && !defined(OS_ANDROID)
    120   // Gets the size of the shared memory region referred to by |handle|.
    121   // Returns false on a failure to determine the size. On success, populates the
    122   // output variable |size|.
    123   static bool GetSizeFromSharedMemoryHandle(const SharedMemoryHandle& handle,
    124                                             size_t* size);
    125 #endif  // defined(OS_POSIX) && !defined(OS_ANDROID)
    126 
    127   // Creates a shared memory object as described by the options struct.
    128   // Returns true on success and false on failure.
    129   bool Create(const SharedMemoryCreateOptions& options);
    130 
    131   // Creates and maps an anonymous shared memory segment of size size.
    132   // Returns true on success and false on failure.
    133   bool CreateAndMapAnonymous(size_t size);
    134 
    135 #if defined(OS_MACOSX) && !defined(OS_IOS)
    136   // These two methods are analogs of CreateAndMapAnonymous and CreateAnonymous
    137   // that force the underlying OS primitive to be a POSIX fd. Do not add new
    138   // uses of these methods unless absolutely necessary, since constructing a
    139   // fd-backed SharedMemory object frequently takes 100ms+.
    140   // http://crbug.com/466437.
    141   bool CreateAndMapAnonymousPosix(size_t size);
    142   bool CreateAnonymousPosix(size_t size);
    143 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
    144 
    145   // Creates an anonymous shared memory segment of size size.
    146   // Returns true on success and false on failure.
    147   bool CreateAnonymous(size_t size) {
    148     SharedMemoryCreateOptions options;
    149     options.size = size;
    150     return Create(options);
    151   }
    152 
    153 #if !defined(OS_MACOSX) || defined(OS_IOS)
    154   // DEPRECATED (crbug.com/345734):
    155   // Creates or opens a shared memory segment based on a name.
    156   // If open_existing is true, and the shared memory already exists,
    157   // opens the existing shared memory and ignores the size parameter.
    158   // If open_existing is false, shared memory must not exist.
    159   // size is the size of the block to be created.
    160   // Returns true on success, false on failure.
    161   bool CreateNamedDeprecated(
    162       const std::string& name, bool open_existing, size_t size) {
    163     SharedMemoryCreateOptions options;
    164     options.name_deprecated = &name;
    165     options.open_existing_deprecated = open_existing;
    166     options.size = size;
    167     return Create(options);
    168   }
    169 
    170   // Deletes resources associated with a shared memory segment based on name.
    171   // Not all platforms require this call.
    172   bool Delete(const std::string& name);
    173 
    174   // Opens a shared memory segment based on a name.
    175   // If read_only is true, opens for read-only access.
    176   // Returns true on success, false on failure.
    177   bool Open(const std::string& name, bool read_only);
    178 #endif  // !defined(OS_MACOSX) || defined(OS_IOS)
    179 
    180   // Maps the shared memory into the caller's address space.
    181   // Returns true on success, false otherwise.  The memory address
    182   // is accessed via the memory() accessor.  The mapped address is guaranteed to
    183   // have an alignment of at least MAP_MINIMUM_ALIGNMENT. This method will fail
    184   // if this object is currently mapped.
    185   bool Map(size_t bytes) {
    186     return MapAt(0, bytes);
    187   }
    188 
    189   // Same as above, but with |offset| to specify from begining of the shared
    190   // memory block to map.
    191   // |offset| must be alignent to value of |SysInfo::VMAllocationGranularity()|.
    192   bool MapAt(off_t offset, size_t bytes);
    193   enum { MAP_MINIMUM_ALIGNMENT = 32 };
    194 
    195   // Unmaps the shared memory from the caller's address space.
    196   // Returns true if successful; returns false on error or if the
    197   // memory is not mapped.
    198   bool Unmap();
    199 
    200   // The size requested when the map is first created.
    201   size_t requested_size() const { return requested_size_; }
    202 
    203   // The actual size of the mapped memory (may be larger than requested).
    204   size_t mapped_size() const { return mapped_size_; }
    205 
    206   // Gets a pointer to the opened memory space if it has been
    207   // Mapped via Map().  Returns NULL if it is not mapped.
    208   void* memory() const { return memory_; }
    209 
    210   // Returns the underlying OS handle for this segment.
    211   // Use of this handle for anything other than an opaque
    212   // identifier is not portable.
    213   SharedMemoryHandle handle() const;
    214 
    215   // Closes the open shared memory segment. The memory will remain mapped if
    216   // it was previously mapped.
    217   // It is safe to call Close repeatedly.
    218   void Close();
    219 
    220   // Shares the shared memory to another process.  Attempts to create a
    221   // platform-specific new_handle which can be used in a remote process to read
    222   // the shared memory file.  new_handle is an output parameter to receive the
    223   // handle for use in the remote process.
    224   //
    225   // |*this| must have been initialized using one of the Create*() or Open()
    226   // methods with share_read_only=true. If it was constructed from a
    227   // SharedMemoryHandle, this call will CHECK-fail.
    228   //
    229   // Returns true on success, false otherwise.
    230   bool ShareReadOnlyToProcess(ProcessHandle process,
    231                               SharedMemoryHandle* new_handle) {
    232     return ShareToProcessCommon(process, new_handle, false, SHARE_READONLY);
    233   }
    234 
    235   // Logically equivalent to:
    236   //   bool ok = ShareReadOnlyToProcess(process, new_handle);
    237   //   Close();
    238   //   return ok;
    239   // Note that the memory is unmapped by calling this method, regardless of the
    240   // return value.
    241   bool GiveReadOnlyToProcess(ProcessHandle process,
    242                              SharedMemoryHandle* new_handle) {
    243     return ShareToProcessCommon(process, new_handle, true, SHARE_READONLY);
    244   }
    245 
    246   // Shares the shared memory to another process.  Attempts
    247   // to create a platform-specific new_handle which can be
    248   // used in a remote process to access the shared memory
    249   // file.  new_handle is an output parameter to receive
    250   // the handle for use in the remote process.
    251   // Returns true on success, false otherwise.
    252   bool ShareToProcess(ProcessHandle process,
    253                       SharedMemoryHandle* new_handle) {
    254     return ShareToProcessCommon(process, new_handle, false, SHARE_CURRENT_MODE);
    255   }
    256 
    257   // Logically equivalent to:
    258   //   bool ok = ShareToProcess(process, new_handle);
    259   //   Close();
    260   //   return ok;
    261   // Note that the memory is unmapped by calling this method, regardless of the
    262   // return value.
    263   bool GiveToProcess(ProcessHandle process,
    264                      SharedMemoryHandle* new_handle) {
    265     return ShareToProcessCommon(process, new_handle, true, SHARE_CURRENT_MODE);
    266   }
    267 
    268  private:
    269 #if defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_ANDROID)
    270   bool PrepareMapFile(ScopedFILE fp, ScopedFD readonly);
    271 #if !(defined(OS_MACOSX) && !defined(OS_IOS))
    272   bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
    273 #endif
    274 #endif  // defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_ANDROID)
    275   enum ShareMode {
    276     SHARE_READONLY,
    277     SHARE_CURRENT_MODE,
    278   };
    279   bool ShareToProcessCommon(ProcessHandle process,
    280                             SharedMemoryHandle* new_handle,
    281                             bool close_self,
    282                             ShareMode);
    283 
    284 #if defined(OS_WIN)
    285   // If true indicates this came from an external source so needs extra checks
    286   // before being mapped.
    287   bool external_section_;
    288   std::wstring       name_;
    289   HANDLE             mapped_file_;
    290 #elif defined(OS_MACOSX) && !defined(OS_IOS)
    291   // The OS primitive that backs the shared memory region.
    292   SharedMemoryHandle shm_;
    293 
    294   // The mechanism by which the memory is mapped. Only valid if |memory_| is not
    295   // |nullptr|.
    296   SharedMemoryHandle::Type mapped_memory_mechanism_;
    297 
    298   int readonly_mapped_file_;
    299 #elif defined(OS_POSIX)
    300   int                mapped_file_;
    301   int                readonly_mapped_file_;
    302 #endif
    303   size_t             mapped_size_;
    304   void*              memory_;
    305   bool               read_only_;
    306   size_t             requested_size_;
    307 
    308   DISALLOW_COPY_AND_ASSIGN(SharedMemory);
    309 };
    310 }  // namespace base
    311 
    312 #endif  // BASE_MEMORY_SHARED_MEMORY_H_
    313