1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/embedder/simple_platform_shared_buffer.h"
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <windows.h>
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <limits>
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/logging.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/sys_info.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/embedder/platform_handle.h"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/embedder/scoped_platform_handle.h"
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace mojo {
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace embedder {
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// SimplePlatformSharedBuffer --------------------------------------------------
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool SimplePlatformSharedBuffer::Init() {
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(!handle_.is_valid());
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // TODO(vtl): Currently, we only support mapping up to 2^32-1 bytes.
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (static_cast<uint64_t>(num_bytes_) >
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      static_cast<uint64_t>(std::numeric_limits<DWORD>::max())) {
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // IMPORTANT NOTE: Unnamed objects are NOT SECURABLE. Thus if we ever want to
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // share read-only to other processes, we'll have to name our file mapping
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // object.
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // TODO(vtl): Unlike |base::SharedMemory|, we don't round up the size (to a
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // multiple of 64 KB). This may cause problems with NaCl. Cross this bridge
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // when we get there. crbug.com/210609
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  handle_.reset(PlatformHandle(CreateFileMapping(INVALID_HANDLE_VALUE,
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 nullptr,
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 PAGE_READWRITE,
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 0,
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                 static_cast<DWORD>(num_bytes_),
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 nullptr)));
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!handle_.is_valid()) {
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PLOG(ERROR) << "CreateFileMapping";
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return true;
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool SimplePlatformSharedBuffer::InitFromPlatformHandle(
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ScopedPlatformHandle platform_handle) {
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!handle_.is_valid());
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(vtl): Implement.
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NOTIMPLEMENTED();
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return false;
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::MapImpl(
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t offset,
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t length) {
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  size_t offset_rounding = offset % base::SysInfo::VMAllocationGranularity();
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  size_t real_offset = offset - offset_rounding;
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  size_t real_length = length + offset_rounding;
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // This should hold (since we checked |num_bytes| versus the maximum value of
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |off_t| on creation, but it never hurts to be paranoid.
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_LE(static_cast<uint64_t>(real_offset),
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            static_cast<uint64_t>(std::numeric_limits<DWORD>::max()));
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void* real_base = MapViewOfFile(handle_.get().handle,
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  FILE_MAP_READ | FILE_MAP_WRITE,
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  0,
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  static_cast<DWORD>(real_offset),
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  real_length);
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!real_base) {
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    PLOG(ERROR) << "MapViewOfFile";
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return scoped_ptr<PlatformSharedBufferMapping>();
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void* base = static_cast<char*>(real_base) + offset_rounding;
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return scoped_ptr<PlatformSharedBufferMapping>(
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new SimplePlatformSharedBufferMapping(
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base, length, real_base, real_length));
85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// SimplePlatformSharedBufferMapping -------------------------------------------
88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SimplePlatformSharedBufferMapping::Unmap() {
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  BOOL result = UnmapViewOfFile(real_base_);
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  PLOG_IF(ERROR, !result) << "UnmapViewOfFile";
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace embedder
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace mojo
96