// 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/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;

// SharedMemoryHandle is a platform specific type which represents
// the underlying OS handle to a shared memory segment.
#if defined(OS_WIN)
typedef HANDLE SharedMemoryHandle;
#elif defined(OS_POSIX)
// A SharedMemoryId is sufficient to identify a given shared memory segment on a
// system, but insufficient to map it.
typedef FileDescriptor SharedMemoryHandle;
typedef ino_t SharedMemoryId;
#endif

// Options for creating a shared memory object.
struct SharedMemoryCreateOptions {
  SharedMemoryCreateOptions()
      : name_deprecated(NULL),
        size(0),
        open_existing_deprecated(false),
        executable(false),
        share_read_only(false) {}

  // 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;

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

  // 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;

  // 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(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(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();

  // 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);

  // 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);
  }

  // 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);

  // 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;

#if defined(OS_POSIX) && !defined(OS_NACL)
  // Returns a unique identifier for this shared memory segment. Inode numbers
  // are technically only unique to a single filesystem. However, we always
  // allocate shared memory backing files from the same directory, so will end
  // up on the same filesystem.
  SharedMemoryId id() const { return inode_; }
#endif

  // Closes the open shared memory segment.
  // 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);
  }

  // DEPRECATED (crbug.com/345734):
  // Locks the shared memory.
  //
  // WARNING: on POSIX the memory locking primitive only works across
  // processes, not across threads.  The LockDeprecated method is not currently
  // used in inner loops, so we protect against multiple threads in a
  // critical section using a class global lock.
  void LockDeprecated();

  // DEPRECATED (crbug.com/345734):
  // Releases the shared memory lock.
  void UnlockDeprecated();

 private:
#if defined(OS_POSIX) && !defined(OS_NACL)
#if !defined(OS_ANDROID)
  bool PrepareMapFile(ScopedFILE fp, ScopedFD readonly);
  bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
#endif
  void LockOrUnlockCommon(int function);
#endif  // defined(OS_POSIX) && !defined(OS_NACL)
  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_POSIX)
  int                mapped_file_;
  int                readonly_mapped_file_;
  ino_t              inode_;
#endif
  size_t             mapped_size_;
  void*              memory_;
  bool               read_only_;
  size_t             requested_size_;
#if !defined(OS_POSIX)
  HANDLE             lock_;
#endif

  DISALLOW_COPY_AND_ASSIGN(SharedMemory);
};

// DEPRECATED (crbug.com/345734):
// A helper class that acquires the shared memory lock while
// the SharedMemoryAutoLockDeprecated is in scope.
class SharedMemoryAutoLockDeprecated {
 public:
  explicit SharedMemoryAutoLockDeprecated(SharedMemory* shared_memory)
      : shared_memory_(shared_memory) {
    shared_memory_->LockDeprecated();
  }

  ~SharedMemoryAutoLockDeprecated() {
    shared_memory_->UnlockDeprecated();
  }

 private:
  SharedMemory* shared_memory_;
  DISALLOW_COPY_AND_ASSIGN(SharedMemoryAutoLockDeprecated);
};

}  // namespace base

#endif  // BASE_MEMORY_SHARED_MEMORY_H_
