ipc/chromium/src/base/shared_memory_win.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/shared_memory_win.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,186 @@
     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 +#include "base/shared_memory.h"
     1.9 +
    1.10 +#include "base/logging.h"
    1.11 +#include "base/win_util.h"
    1.12 +#include "base/string_util.h"
    1.13 +
    1.14 +namespace base {
    1.15 +
    1.16 +SharedMemory::SharedMemory()
    1.17 +    : mapped_file_(NULL),
    1.18 +      memory_(NULL),
    1.19 +      read_only_(false),
    1.20 +      max_size_(0),
    1.21 +      lock_(NULL) {
    1.22 +}
    1.23 +
    1.24 +SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only)
    1.25 +    : mapped_file_(handle),
    1.26 +      memory_(NULL),
    1.27 +      read_only_(read_only),
    1.28 +      max_size_(0),
    1.29 +      lock_(NULL) {
    1.30 +}
    1.31 +
    1.32 +SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only,
    1.33 +                           ProcessHandle process)
    1.34 +    : mapped_file_(NULL),
    1.35 +      memory_(NULL),
    1.36 +      read_only_(read_only),
    1.37 +      max_size_(0),
    1.38 +      lock_(NULL) {
    1.39 +  ::DuplicateHandle(process, handle,
    1.40 +                    GetCurrentProcess(), &mapped_file_,
    1.41 +                    STANDARD_RIGHTS_REQUIRED |
    1.42 +                    (read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS),
    1.43 +                    FALSE, 0);
    1.44 +}
    1.45 +
    1.46 +SharedMemory::~SharedMemory() {
    1.47 +  Close();
    1.48 +  if (lock_ != NULL)
    1.49 +    CloseHandle(lock_);
    1.50 +}
    1.51 +
    1.52 +// static
    1.53 +bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
    1.54 +  return handle != NULL;
    1.55 +}
    1.56 +
    1.57 +// static
    1.58 +SharedMemoryHandle SharedMemory::NULLHandle() {
    1.59 +  return NULL;
    1.60 +}
    1.61 +
    1.62 +bool SharedMemory::Create(const std::string &cname, bool read_only,
    1.63 +                          bool open_existing, size_t size) {
    1.64 +  DCHECK(mapped_file_ == NULL);
    1.65 +  std::wstring name = UTF8ToWide(cname);
    1.66 +  name_ = name;
    1.67 +  read_only_ = read_only;
    1.68 +  mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
    1.69 +      read_only_ ? PAGE_READONLY : PAGE_READWRITE, 0, static_cast<DWORD>(size),
    1.70 +      name.empty() ? NULL : name.c_str());
    1.71 +  if (!mapped_file_)
    1.72 +    return false;
    1.73 +
    1.74 +  // Check if the shared memory pre-exists.
    1.75 +  if (GetLastError() == ERROR_ALREADY_EXISTS && !open_existing) {
    1.76 +    Close();
    1.77 +    return false;
    1.78 +  }
    1.79 +  max_size_ = size;
    1.80 +  return true;
    1.81 +}
    1.82 +
    1.83 +bool SharedMemory::Delete(const std::wstring& name) {
    1.84 +  // intentionally empty -- there is nothing for us to do on Windows.
    1.85 +  return true;
    1.86 +}
    1.87 +
    1.88 +bool SharedMemory::Open(const std::wstring &name, bool read_only) {
    1.89 +  DCHECK(mapped_file_ == NULL);
    1.90 +
    1.91 +  name_ = name;
    1.92 +  read_only_ = read_only;
    1.93 +  mapped_file_ = OpenFileMapping(
    1.94 +      read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, false,
    1.95 +      name.empty() ? NULL : name.c_str());
    1.96 +  if (mapped_file_ != NULL) {
    1.97 +    // Note: size_ is not set in this case.
    1.98 +    return true;
    1.99 +  }
   1.100 +  return false;
   1.101 +}
   1.102 +
   1.103 +bool SharedMemory::Map(size_t bytes) {
   1.104 +  if (mapped_file_ == NULL)
   1.105 +    return false;
   1.106 +
   1.107 +  memory_ = MapViewOfFile(mapped_file_,
   1.108 +      read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, 0, 0, bytes);
   1.109 +  if (memory_ != NULL) {
   1.110 +    return true;
   1.111 +  }
   1.112 +  return false;
   1.113 +}
   1.114 +
   1.115 +bool SharedMemory::Unmap() {
   1.116 +  if (memory_ == NULL)
   1.117 +    return false;
   1.118 +
   1.119 +  UnmapViewOfFile(memory_);
   1.120 +  memory_ = NULL;
   1.121 +  return true;
   1.122 +}
   1.123 +
   1.124 +bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
   1.125 +                                        SharedMemoryHandle *new_handle,
   1.126 +                                        bool close_self) {
   1.127 +  *new_handle = 0;
   1.128 +  DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ;
   1.129 +  DWORD options = 0;
   1.130 +  HANDLE mapped_file = mapped_file_;
   1.131 +  HANDLE result;
   1.132 +  if (!read_only_)
   1.133 +    access |= FILE_MAP_WRITE;
   1.134 +  if (close_self) {
   1.135 +    // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file.
   1.136 +    options = DUPLICATE_CLOSE_SOURCE;
   1.137 +    mapped_file_ = NULL;
   1.138 +    Unmap();
   1.139 +  }
   1.140 +
   1.141 +  if (process == GetCurrentProcess() && close_self) {
   1.142 +    *new_handle = mapped_file;
   1.143 +    return true;
   1.144 +  }
   1.145 +
   1.146 +  if (!DuplicateHandle(GetCurrentProcess(), mapped_file, process,
   1.147 +      &result, access, FALSE, options))
   1.148 +    return false;
   1.149 +  *new_handle = result;
   1.150 +  return true;
   1.151 +}
   1.152 +
   1.153 +
   1.154 +void SharedMemory::Close() {
   1.155 +  if (memory_ != NULL) {
   1.156 +    UnmapViewOfFile(memory_);
   1.157 +    memory_ = NULL;
   1.158 +  }
   1.159 +
   1.160 +  if (mapped_file_ != NULL) {
   1.161 +    CloseHandle(mapped_file_);
   1.162 +    mapped_file_ = NULL;
   1.163 +  }
   1.164 +}
   1.165 +
   1.166 +void SharedMemory::Lock() {
   1.167 +  if (lock_ == NULL) {
   1.168 +    std::wstring name = name_;
   1.169 +    name.append(L"lock");
   1.170 +    lock_ = CreateMutex(NULL, FALSE, name.c_str());
   1.171 +    DCHECK(lock_ != NULL);
   1.172 +    if (lock_ == NULL) {
   1.173 +      DLOG(ERROR) << "Could not create mutex" << GetLastError();
   1.174 +      return;  // there is nothing good we can do here.
   1.175 +    }
   1.176 +  }
   1.177 +  WaitForSingleObject(lock_, INFINITE);
   1.178 +}
   1.179 +
   1.180 +void SharedMemory::Unlock() {
   1.181 +  DCHECK(lock_ != NULL);
   1.182 +  ReleaseMutex(lock_);
   1.183 +}
   1.184 +
   1.185 +SharedMemoryHandle SharedMemory::handle() const {
   1.186 +  return mapped_file_;
   1.187 +}
   1.188 +
   1.189 +}  // namespace base

mercurial