Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: app/surface/transport_dib_win.cc

Issue 3834003: On Windows, create a new TransportDIB::Handle struct which includes the file (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Rebase Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <windows.h>
6
5 #include <limits> 7 #include <limits>
6 #include <windows.h>
7 8
8 #include "app/surface/transport_dib.h" 9 #include "app/surface/transport_dib.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/scoped_handle_win.h"
10 #include "base/scoped_ptr.h" 12 #include "base/scoped_ptr.h"
11 #include "base/sys_info.h" 13 #include "base/sys_info.h"
12 #include "skia/ext/platform_canvas.h" 14 #include "skia/ext/platform_canvas.h"
13 15
16 TransportDIB::Handle TransportDIB::Handle::DupForProcess(
17 base::ProcessHandle new_owner_process) const {
18 base::ProcessId new_owner_id = ::GetProcessId(new_owner_process);
19 if (!new_owner_id) {
20 LOG(WARNING) << "Could not get process id from handle"
21 << " handle:" << new_owner_process
22 << " error:" << ::GetLastError();
23 return Handle();
24 }
25 HANDLE owner_process = ::OpenProcess(PROCESS_DUP_HANDLE, FALSE, owner_id_);
26 if (!owner_process) {
27 LOG(WARNING) << "Could not open process"
28 << " id:" << owner_id_
29 << " error:" << ::GetLastError();
30 return Handle();
31 }
32 ::ScopedHandle scoped_owner_process(owner_process);
33 HANDLE new_section = NULL;
34 ::DuplicateHandle(owner_process, section_,
35 new_owner_process, &new_section,
36 STANDARD_RIGHTS_REQUIRED | FILE_MAP_ALL_ACCESS,
37 FALSE, 0);
38 if (!new_section) {
39 LOG(WARNING) << "Could not duplicate handle for process"
40 << " error:" << ::GetLastError();
41 return Handle();
42 }
43 return Handle(new_section, new_owner_id, false);
44 }
45
46 void TransportDIB::Handle::Close() const {
47 // Do not close this handle if it is invalid, or it has not been duped yet.
48 if (!is_valid() || should_dup_on_map_)
49 return;
50
51 // The handle was already duped for a target process, so we should close it.
52 // The target process may not have been us, so close using
53 // |::DuplicateHandle|.
54 HANDLE owner_process = ::OpenProcess(PROCESS_DUP_HANDLE, FALSE, owner_id_);
55 if (!owner_process) {
56 LOG(WARNING) << "Could not open process"
57 << " id:" << owner_id_
58 << " error:" << ::GetLastError();
59 return;
60 }
61 if (!::DuplicateHandle(owner_process, section_,
62 NULL, NULL,
63 DUPLICATE_CLOSE_SOURCE,
64 FALSE, 0)) {
65 NOTREACHED() << "Handle could not be closed: " << ::GetLastError();
66 }
67 }
68
69 void TransportDIB::ScopedHandle::Close() {
70 handle_.Close();
71 }
72
14 TransportDIB::TransportDIB() { 73 TransportDIB::TransportDIB() {
15 } 74 }
16 75
17 TransportDIB::~TransportDIB() { 76 TransportDIB::~TransportDIB() {
18 } 77 }
19 78
20 TransportDIB::TransportDIB(HANDLE handle) 79 TransportDIB::TransportDIB(HANDLE handle)
21 : shared_memory_(handle, false /* read write */) { 80 : shared_memory_(handle, false /* read write */) {
22 } 81 }
23 82
(...skipping 11 matching lines...) Expand all
35 return NULL; 94 return NULL;
36 } 95 }
37 96
38 dib->size_ = size; 97 dib->size_ = size;
39 dib->sequence_num_ = sequence_num; 98 dib->sequence_num_ = sequence_num;
40 99
41 return dib; 100 return dib;
42 } 101 }
43 102
44 // static 103 // static
45 TransportDIB* TransportDIB::Map(TransportDIB::Handle handle) { 104 TransportDIB* TransportDIB::Map(Handle handle) {
46 TransportDIB* dib = new TransportDIB(handle); 105 scoped_ptr<TransportDIB> dib(CreateWithHandle(handle));
47 if (!dib->shared_memory_.Map(0 /* map whole shared memory segment */)) { 106 if (!dib->Map())
107 return NULL;
108 return dib.release();
109 }
110
111 // static
112 TransportDIB* TransportDIB::CreateWithHandle(Handle handle) {
113 // It is not sufficient to compare the current process ID and the ID in the
114 // handle here to see if a duplication is required because they will always
115 // be the same in single process mode.
116 if (handle.should_dup_on_map())
117 handle = handle.DupForProcess(::GetCurrentProcess());
118 return new TransportDIB(handle.section());
119 }
120
121 // static
122 bool TransportDIB::is_valid(Handle dib) {
123 return dib.is_valid();
124 }
125
126 skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
127 // This DIB already mapped the file into this process, but PlatformCanvas
128 // will map it again.
129 DCHECK(!memory()) << "Mapped file twice in the same process.";
130
131 scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas);
132 if (!canvas->initialize(w, h, true, shared_memory_.handle()))
133 return NULL;
134 return canvas.release();
135 }
136
137 bool TransportDIB::Map() {
138 if (memory())
139 return true;
140
141 if (!shared_memory_.Map(0 /* map whole shared memory segment */)) {
48 LOG(ERROR) << "Failed to map transport DIB" 142 LOG(ERROR) << "Failed to map transport DIB"
49 << " handle:" << handle 143 << " handle:" << shared_memory_.handle()
50 << " error:" << GetLastError(); 144 << " error:" << ::GetLastError();
51 delete dib; 145 return false;
52 return NULL;
53 } 146 }
54 147
55 // There doesn't seem to be any way to find the size of the shared memory 148 // There doesn't seem to be any way to find the size of the shared memory
56 // region! GetFileSize indicates that the handle is invalid. Thus, we 149 // region! GetFileSize indicates that the handle is invalid. Thus, we
57 // conservatively set the size to the maximum and hope that the renderer 150 // conservatively set the size to the maximum and hope that the renderer
58 // isn't about to ask us to read off the end of the array. 151 // isn't about to ask us to read off the end of the array.
59 dib->size_ = std::numeric_limits<size_t>::max(); 152 size_ = std::numeric_limits<size_t>::max();
60 153 return true;
61 return dib;
62 } 154 }
63 155
64 bool TransportDIB::is_valid(Handle dib) { 156 TransportDIB::Handle TransportDIB::GetHandleForProcess(
65 return dib != NULL; 157 base::ProcessHandle process_handle) const {
66 } 158 return handle().DupForProcess(process_handle);
67
68 skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
69 scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas);
70 if (!canvas->initialize(w, h, true, handle()))
71 return NULL;
72 return canvas.release();
73 } 159 }
74 160
75 void* TransportDIB::memory() const { 161 void* TransportDIB::memory() const {
76 return shared_memory_.memory(); 162 return shared_memory_.memory();
77 } 163 }
78 164
79 TransportDIB::Handle TransportDIB::handle() const { 165 TransportDIB::Handle TransportDIB::handle() const {
80 return shared_memory_.handle(); 166 return TransferrableSectionHandle(shared_memory_.handle(),
167 ::GetCurrentProcessId(),
168 true);
81 } 169 }
82 170
83 TransportDIB::Id TransportDIB::id() const { 171 TransportDIB::Id TransportDIB::id() const {
84 return Id(shared_memory_.handle(), sequence_num_); 172 return sequence_num_;
85 } 173 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698