summaryrefslogtreecommitdiffstats
path: root/ipc/chromium/src/base/shared_memory_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/chromium/src/base/shared_memory_win.cc')
-rw-r--r--ipc/chromium/src/base/shared_memory_win.cc176
1 files changed, 176 insertions, 0 deletions
diff --git a/ipc/chromium/src/base/shared_memory_win.cc b/ipc/chromium/src/base/shared_memory_win.cc
new file mode 100644
index 000000000..042adc834
--- /dev/null
+++ b/ipc/chromium/src/base/shared_memory_win.cc
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+// Copyright (c) 2006-2008 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/shared_memory.h"
+
+#include "base/logging.h"
+#include "base/win_util.h"
+#include "base/string_util.h"
+#include "mozilla/ipc/ProtocolUtils.h"
+
+namespace base {
+
+SharedMemory::SharedMemory()
+ : mapped_file_(NULL),
+ memory_(NULL),
+ read_only_(false),
+ max_size_(0),
+ lock_(NULL) {
+}
+
+SharedMemory::~SharedMemory() {
+ Close();
+ if (lock_ != NULL)
+ CloseHandle(lock_);
+}
+
+bool SharedMemory::SetHandle(SharedMemoryHandle handle, bool read_only) {
+ DCHECK(mapped_file_ == NULL);
+
+ mapped_file_ = handle;
+ read_only_ = read_only;
+ return true;
+}
+
+// static
+bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
+ return handle != NULL;
+}
+
+// static
+SharedMemoryHandle SharedMemory::NULLHandle() {
+ return NULL;
+}
+
+bool SharedMemory::Create(const std::string &cname, bool read_only,
+ bool open_existing, size_t size) {
+ DCHECK(mapped_file_ == NULL);
+ std::wstring name = UTF8ToWide(cname);
+ name_ = name;
+ read_only_ = read_only;
+ mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
+ read_only_ ? PAGE_READONLY : PAGE_READWRITE, 0, static_cast<DWORD>(size),
+ name.empty() ? NULL : name.c_str());
+ if (!mapped_file_)
+ return false;
+
+ // Check if the shared memory pre-exists.
+ if (GetLastError() == ERROR_ALREADY_EXISTS && !open_existing) {
+ Close();
+ return false;
+ }
+ max_size_ = size;
+ return true;
+}
+
+bool SharedMemory::Delete(const std::wstring& name) {
+ // intentionally empty -- there is nothing for us to do on Windows.
+ return true;
+}
+
+bool SharedMemory::Open(const std::wstring &name, bool read_only) {
+ DCHECK(mapped_file_ == NULL);
+
+ name_ = name;
+ read_only_ = read_only;
+ mapped_file_ = OpenFileMapping(
+ read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, false,
+ name.empty() ? NULL : name.c_str());
+ if (mapped_file_ != NULL) {
+ // Note: size_ is not set in this case.
+ return true;
+ }
+ return false;
+}
+
+bool SharedMemory::Map(size_t bytes) {
+ if (mapped_file_ == NULL)
+ return false;
+
+ memory_ = MapViewOfFile(mapped_file_,
+ read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, 0, 0, bytes);
+ if (memory_ != NULL) {
+ return true;
+ }
+ return false;
+}
+
+bool SharedMemory::Unmap() {
+ if (memory_ == NULL)
+ return false;
+
+ UnmapViewOfFile(memory_);
+ memory_ = NULL;
+ return true;
+}
+
+bool SharedMemory::ShareToProcessCommon(ProcessId processId,
+ SharedMemoryHandle *new_handle,
+ bool close_self) {
+ *new_handle = 0;
+ DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ;
+ DWORD options = 0;
+ HANDLE mapped_file = mapped_file_;
+ HANDLE result;
+ if (!read_only_)
+ access |= FILE_MAP_WRITE;
+ if (close_self) {
+ // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file.
+ options = DUPLICATE_CLOSE_SOURCE;
+ mapped_file_ = NULL;
+ Unmap();
+ }
+
+ if (processId == GetCurrentProcId() && close_self) {
+ *new_handle = mapped_file;
+ return true;
+ }
+
+ if (!mozilla::ipc::DuplicateHandle(mapped_file, processId, &result, access,
+ options)) {
+ return false;
+ }
+
+ *new_handle = result;
+ return true;
+}
+
+
+void SharedMemory::Close(bool unmap_view) {
+ if (unmap_view) {
+ Unmap();
+ }
+
+ if (mapped_file_ != NULL) {
+ CloseHandle(mapped_file_);
+ mapped_file_ = NULL;
+ }
+}
+
+void SharedMemory::Lock() {
+ if (lock_ == NULL) {
+ std::wstring name = name_;
+ name.append(L"lock");
+ lock_ = CreateMutex(NULL, FALSE, name.c_str());
+ DCHECK(lock_ != NULL);
+ if (lock_ == NULL) {
+ DLOG(ERROR) << "Could not create mutex" << GetLastError();
+ return; // there is nothing good we can do here.
+ }
+ }
+ WaitForSingleObject(lock_, INFINITE);
+}
+
+void SharedMemory::Unlock() {
+ DCHECK(lock_ != NULL);
+ ReleaseMutex(lock_);
+}
+
+SharedMemoryHandle SharedMemory::handle() const {
+ return mapped_file_;
+}
+
+} // namespace base