// Copyright 2015 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.

#include "base/memory/shared_memory_handle.h"

#include <mach/mach_vm.h>
#include <sys/mman.h>
#include <unistd.h>

#include "base/mac/mac_util.h"
#include "base/mac/mach_logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/unguessable_token.h"
#include "starboard/types.h"

namespace base {

SharedMemoryHandle::SharedMemoryHandle() {}

SharedMemoryHandle::SharedMemoryHandle(
    const base::FileDescriptor& file_descriptor,
    size_t size,
    const base::UnguessableToken& guid)
    : type_(POSIX),
      file_descriptor_(file_descriptor),
      guid_(guid),
      size_(size) {}

SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size,
                                       const base::UnguessableToken& guid) {
  type_ = MACH;
  mach_port_t named_right;
  kern_return_t kr = mach_make_memory_entry_64(
      mach_task_self(),
      &size,
      0,  // Address.
      MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE,
      &named_right,
      MACH_PORT_NULL);  // Parent handle.
  if (kr != KERN_SUCCESS) {
    memory_object_ = MACH_PORT_NULL;
    return;
  }

  memory_object_ = named_right;
  size_ = size;
  ownership_passes_to_ipc_ = false;
  guid_ = guid;
}

SharedMemoryHandle::SharedMemoryHandle(mach_port_t memory_object,
                                       mach_vm_size_t size,
                                       const base::UnguessableToken& guid)
    : type_(MACH),
      memory_object_(memory_object),
      ownership_passes_to_ipc_(false),
      guid_(guid),
      size_(size) {}

SharedMemoryHandle SharedMemoryHandle::Duplicate() const {
  switch (type_) {
    case POSIX: {
      if (!IsValid())
        return SharedMemoryHandle();
      int duped_fd = HANDLE_EINTR(dup(file_descriptor_.fd));
      if (duped_fd < 0)
        return SharedMemoryHandle();
      return SharedMemoryHandle(FileDescriptor(duped_fd, true), size_, guid_);
    }
    case MACH: {
      if (!IsValid())
        return SharedMemoryHandle();

      // Increment the ref count.
      kern_return_t kr = mach_port_mod_refs(mach_task_self(), memory_object_,
                                            MACH_PORT_RIGHT_SEND, 1);
      DCHECK_EQ(kr, KERN_SUCCESS);
      SharedMemoryHandle handle(*this);
      handle.SetOwnershipPassesToIPC(true);
      return handle;
    }
  }
}

bool SharedMemoryHandle::IsValid() const {
  switch (type_) {
    case POSIX:
      return file_descriptor_.fd >= 0;
    case MACH:
      return memory_object_ != MACH_PORT_NULL;
  }
}

mach_port_t SharedMemoryHandle::GetMemoryObject() const {
  DCHECK_EQ(type_, MACH);
  return memory_object_;
}

bool SharedMemoryHandle::MapAt(off_t offset,
                               size_t bytes,
                               void** memory,
                               bool read_only) {
  DCHECK(IsValid());
  switch (type_) {
    case SharedMemoryHandle::POSIX:
      *memory = mmap(nullptr, bytes, PROT_READ | (read_only ? 0 : PROT_WRITE),
                     MAP_SHARED, file_descriptor_.fd, offset);
      return *memory != MAP_FAILED;
    case SharedMemoryHandle::MACH:
      kern_return_t kr = mach_vm_map(
          mach_task_self(),
          reinterpret_cast<mach_vm_address_t*>(memory),    // Output parameter
          bytes,
          0,                                               // Alignment mask
          VM_FLAGS_ANYWHERE,
          memory_object_,
          offset,
          FALSE,                                           // Copy
          VM_PROT_READ | (read_only ? 0 : VM_PROT_WRITE),  // Current protection
          VM_PROT_WRITE | VM_PROT_READ | VM_PROT_IS_MASK,  // Maximum protection
          VM_INHERIT_NONE);
      return kr == KERN_SUCCESS;
  }
}

void SharedMemoryHandle::Close() const {
  if (!IsValid())
    return;

  switch (type_) {
    case POSIX:
      if (IGNORE_EINTR(close(file_descriptor_.fd)) < 0)
        DPLOG(ERROR) << "Error closing fd";
      break;
    case MACH:
      kern_return_t kr = mach_port_deallocate(mach_task_self(), memory_object_);
      if (kr != KERN_SUCCESS)
        MACH_DLOG(ERROR, kr) << "Error deallocating mach port";
      break;
  }
}

void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) {
  DCHECK_EQ(type_, MACH);
  ownership_passes_to_ipc_ = ownership_passes;
}

bool SharedMemoryHandle::OwnershipPassesToIPC() const {
  DCHECK_EQ(type_, MACH);
  return ownership_passes_to_ipc_;
}

}  // namespace base
