// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_MEMORY_SHARED_MEMORY_H_
#define BASE_MEMORY_SHARED_MEMORY_H_

#include "build/build_config.h"

#include <string>

#if defined(OS_POSIX)
#include <stdio.h>
#include <sys/types.h>
#include <semaphore.h>
#endif

#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/memory/shared_memory_handle.h"
#include "base/process/process_handle.h"

#if defined(OS_POSIX)
#include "base/file_descriptor_posix.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#endif

namespace base {

class FilePath;

// Options for creating a shared memory object.
struct BASE_EXPORT SharedMemoryCreateOptions {
  SharedMemoryCreateOptions();

#if defined(OS_MACOSX) && !defined(OS_IOS)
  // The type of OS primitive that should back the SharedMemory object.
  SharedMemoryHandle::Type type;
#else
  // DEPRECATED (crbug.com/345734):
  // If NULL, the object is anonymous.  This pointer is owned by the caller
  // and must live through the call to Create().
  const std::string* name_deprecated;

  // DEPRECATED (crbug.com/345734):
  // If true, and the shared memory already exists, Create() will open the
  // existing shared memory and ignore the size parameter.  If false,
  // shared memory must not exist.  This flag is meaningless unless
  // name_deprecated is non-NULL.
  bool open_existing_deprecated;
#endif  // defined(OS_MACOSX) && !defined(OS_IOS)

  // Size of the shared memory object to be created.
  // When opening an existing object, this has no effect.
  size_t size;

  // If true, mappings might need to be made executable later.
  bool executable;

  // If true, the file can be shared read-only to a process.
  bool share_read_only;
};

// Platform abstraction for shared memory.  Provides a C++ wrapper
// around the OS primitive for a memory mapped file.
class BASE_EXPORT SharedMemory {
 public:
  SharedMemory();

#if defined(OS_WIN)
  // Similar to the default constructor, except that this allows for
  // calling LockDeprecated() to acquire the named mutex before either Create or
  // Open are called on Windows.
  explicit SharedMemory(const std::wstring& name);
#endif

  // Create a new SharedMemory object from an existing, open
  // shared memory file.
  //
  // WARNING: This does not reduce the OS-level permissions on the handle; it
  // only affects how the SharedMemory will be mmapped.  Use
  // ShareReadOnlyToProcess to drop permissions.  TODO(jln,jyasskin): DCHECK
  // that |read_only| matches the permissions of the handle.
  SharedMemory(const SharedMemoryHandle& handle, bool read_only);

  // Create a new SharedMemory object from an existing, open
  // shared memory file that was created by a remote process and not shared
  // to the current process.
  SharedMemory(const SharedMemoryHandle& handle,
               bool read_only,
               ProcessHandle process);

  // Closes any open files.
  ~SharedMemory();

  // Return true iff the given handle is valid (i.e. not the distingished
  // invalid value; NULL for a HANDLE and -1 for a file descriptor)
  static bool IsHandleValid(const SharedMemoryHandle& handle);

  // Returns invalid handle (see comment above for exact definition).
  static SharedMemoryHandle NULLHandle();

  // Closes a shared memory handle.
  static void CloseHandle(const SharedMemoryHandle& handle);

  // Returns the maximum number of handles that can be open at once per process.
  static size_t GetHandleLimit();

  // Duplicates The underlying OS primitive. Returns NULLHandle() on failure.
  // The caller is responsible for destroying the duplicated OS primitive.
  static SharedMemoryHandle DuplicateHandle(const SharedMemoryHandle& handle);

#if defined(OS_POSIX)
  // This method requires that the SharedMemoryHandle is backed by a POSIX fd.
  static int GetFdFromSharedMemoryHandle(const SharedMemoryHandle& handle);
#endif

#if defined(OS_POSIX) && !defined(OS_ANDROID)
  // Gets the size of the shared memory region referred to by |handle|.
  // Returns false on a failure to determine the size. On success, populates the
  // output variable |size|.
  static bool GetSizeFromSharedMemoryHandle(const SharedMemoryHandle& handle,
                                            size_t* size);
#endif  // defined(OS_POSIX) && !defined(OS_ANDROID)

  // Creates a shared memory object as described by the options struct.
  // Returns true on success and false on failure.
  bool Create(const SharedMemoryCreateOptions& options);

  // Creates and maps an anonymous shared memory segment of size size.
  // Returns true on success and false on failure.
  bool CreateAndMapAnonymous(size_t size);

#if defined(OS_MACOSX) && !defined(OS_IOS)
  // These two methods are analogs of CreateAndMapAnonymous and CreateAnonymous
  // that force the underlying OS primitive to be a POSIX fd. Do not add new
  // uses of these methods unless absolutely necessary, since constructing a
  // fd-backed SharedMemory object frequently takes 100ms+.
  // http://crbug.com/466437.
  bool CreateAndMapAnonymousPosix(size_t size);
  bool CreateAnonymousPosix(size_t size);
#endif  // defined(OS_MACOSX) && !defined(OS_IOS)

  // Creates an anonymous shared memory segment of size size.
  // Returns true on success and false on failure.
  bool CreateAnonymous(size_t size) {
    SharedMemoryCreateOptions options;
    options.size = size;
    return Create(options);
  }

#if !defined(OS_MACOSX) || defined(OS_IOS)
  // DEPRECATED (crbug.com/345734):
  // Creates or opens a shared memory segment based on a name.
  // If open_existing is true, and the shared memory already exists,
  // opens the existing shared memory and ignores the size parameter.
  // If open_existing is false, shared memory must not exist.
  // size is the size of the block to be created.
  // Returns true on success, false on failure.
  bool CreateNamedDeprecated(
      const std::string& name, bool open_existing, size_t size) {
    SharedMemoryCreateOptions options;
    options.name_deprecated = &name;
    options.open_existing_deprecated = open_existing;
    options.size = size;
    return Create(options);
  }

  // Deletes resources associated with a shared memory segment based on name.
  // Not all platforms require this call.
  bool Delete(const std::string& name);

  // Opens a shared memory segment based on a name.
  // If read_only is true, opens for read-only access.
  // Returns true on success, false on failure.
  bool Open(const std::string& name, bool read_only);
#endif  // !defined(OS_MACOSX) || defined(OS_IOS)

  // Maps the shared memory into the caller's address space.
  // Returns true on success, false otherwise.  The memory address
  // is accessed via the memory() accessor.  The mapped address is guaranteed to
  // have an alignment of at least MAP_MINIMUM_ALIGNMENT. This method will fail
  // if this object is currently mapped.
  bool Map(size_t bytes) {
    return MapAt(0, bytes);
  }

  // Same as above, but with |offset| to specify from begining of the shared
  // memory block to map.
  // |offset| must be alignent to value of |SysInfo::VMAllocationGranularity()|.
  bool MapAt(off_t offset, size_t bytes);
  enum { MAP_MINIMUM_ALIGNMENT = 32 };

  // Unmaps the shared memory from the caller's address space.
  // Returns true if successful; returns false on error or if the
  // memory is not mapped.
  bool Unmap();

  // The size requested when the map is first created.
  size_t requested_size() const { return requested_size_; }

  // The actual size of the mapped memory (may be larger than requested).
  size_t mapped_size() const { return mapped_size_; }

  // Gets a pointer to the opened memory space if it has been
  // Mapped via Map().  Returns NULL if it is not mapped.
  void* memory() const { return memory_; }

  // Returns the underlying OS handle for this segment.
  // Use of this handle for anything other than an opaque
  // identifier is not portable.
  SharedMemoryHandle handle() const;

  // Closes the open shared memory segment. The memory will remain mapped if
  // it was previously mapped.
  // It is safe to call Close repeatedly.
  void Close();

  // Shares the shared memory to another process.  Attempts to create a
  // platform-specific new_handle which can be used in a remote process to read
  // the shared memory file.  new_handle is an output parameter to receive the
  // handle for use in the remote process.
  //
  // |*this| must have been initialized using one of the Create*() or Open()
  // methods with share_read_only=true. If it was constructed from a
  // SharedMemoryHandle, this call will CHECK-fail.
  //
  // Returns true on success, false otherwise.
  bool ShareReadOnlyToProcess(ProcessHandle process,
                              SharedMemoryHandle* new_handle) {
    return ShareToProcessCommon(process, new_handle, false, SHARE_READONLY);
  }

  // Logically equivalent to:
  //   bool ok = ShareReadOnlyToProcess(process, new_handle);
  //   Close();
  //   return ok;
  // Note that the memory is unmapped by calling this method, regardless of the
  // return value.
  bool GiveReadOnlyToProcess(ProcessHandle process,
                             SharedMemoryHandle* new_handle) {
    return ShareToProcessCommon(process, new_handle, true, SHARE_READONLY);
  }

  // Shares the shared memory to another process.  Attempts
  // to create a platform-specific new_handle which can be
  // used in a remote process to access the shared memory
  // file.  new_handle is an output parameter to receive
  // the handle for use in the remote process.
  // Returns true on success, false otherwise.
  bool ShareToProcess(ProcessHandle process,
                      SharedMemoryHandle* new_handle) {
    return ShareToProcessCommon(process, new_handle, false, SHARE_CURRENT_MODE);
  }

  // Logically equivalent to:
  //   bool ok = ShareToProcess(process, new_handle);
  //   Close();
  //   return ok;
  // Note that the memory is unmapped by calling this method, regardless of the
  // return value.
  bool GiveToProcess(ProcessHandle process,
                     SharedMemoryHandle* new_handle) {
    return ShareToProcessCommon(process, new_handle, true, SHARE_CURRENT_MODE);
  }

 private:
#if defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_ANDROID)
  bool PrepareMapFile(ScopedFILE fp, ScopedFD readonly);
#if !(defined(OS_MACOSX) && !defined(OS_IOS))
  bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
#endif
#endif  // defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_ANDROID)
  enum ShareMode {
    SHARE_READONLY,
    SHARE_CURRENT_MODE,
  };
  bool ShareToProcessCommon(ProcessHandle process,
                            SharedMemoryHandle* new_handle,
                            bool close_self,
                            ShareMode);

#if defined(OS_WIN)
  std::wstring       name_;
  HANDLE             mapped_file_;
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  // The OS primitive that backs the shared memory region.
  SharedMemoryHandle shm_;

  // The mechanism by which the memory is mapped. Only valid if |memory_| is not
  // |nullptr|.
  SharedMemoryHandle::Type mapped_memory_mechanism_;

  int readonly_mapped_file_;
#elif defined(OS_POSIX)
  int                mapped_file_;
  int                readonly_mapped_file_;
#endif
  size_t             mapped_size_;
  void*              memory_;
  bool               read_only_;
  size_t             requested_size_;

  DISALLOW_COPY_AND_ASSIGN(SharedMemory);
};
}  // namespace base

#endif  // BASE_MEMORY_SHARED_MEMORY_H_
