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

Side by Side Diff: app/surface/transport_dib.h

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
« no previous file with comments | « no previous file | app/surface/transport_dib_linux.cc » ('j') | app/surface/transport_dib_mac.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #ifndef APP_SURFACE_TRANSPORT_DIB_H_ 5 #ifndef APP_SURFACE_TRANSPORT_DIB_H_
6 #define APP_SURFACE_TRANSPORT_DIB_H_ 6 #define APP_SURFACE_TRANSPORT_DIB_H_
7 #pragma once 7 #pragma once
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/process.h"
10 11
11 #if defined(OS_WIN) || defined(OS_MACOSX) 12 #if defined(OS_WIN) || defined(OS_MACOSX)
12 #include "base/shared_memory.h" 13 #include "base/shared_memory.h"
13 #endif 14 #endif
14 15
15 #if defined(OS_WIN) 16 #if defined(OS_WIN)
16 #include <windows.h> 17 #include <windows.h>
17 #elif defined(USE_X11) 18 #elif defined(USE_X11)
18 #include "app/x11_util.h" 19 #include "app/x11_util.h"
19 #endif 20 #endif
20 21
21 namespace skia { 22 namespace skia {
22 class PlatformCanvas; 23 class PlatformCanvas;
23 } 24 }
24 25
25 // ----------------------------------------------------------------------------- 26 // -----------------------------------------------------------------------------
26 // A TransportDIB is a block of memory that is used to transport pixels 27 // A TransportDIB is a block of memory that is used to transport pixels
27 // between processes: from the renderer process to the browser, and 28 // between processes: from the renderer process to the browser, and
28 // between renderer and plugin processes. 29 // between renderer and plugin processes.
29 // ----------------------------------------------------------------------------- 30 // -----------------------------------------------------------------------------
30 class TransportDIB { 31 class TransportDIB {
31 public: 32 public:
32 ~TransportDIB(); 33 ~TransportDIB();
33 34
34 // Two typedefs are defined. A Handle is the type which can be sent over 35 // Two typedefs are defined. A |Handle| can be sent over the wire so that the
35 // the wire so that the remote side can map the transport DIB. The Id typedef 36 // remote side can map the |TransportDIB|. These handles may be reused from
36 // is sufficient to identify the transport DIB when you know that the remote 37 // previous DIBs. An |Id| is unique and never reused, but it is not sufficient
37 // side already may have it mapped. 38 // to map the DIB.
38 #if defined(OS_WIN) 39 #if defined(OS_WIN)
39 typedef HANDLE Handle; 40 // On Windows, a |Handle| is a combination of the section (i.e., file mapping)
40 // On Windows, the Id type includes a sequence number (epoch) to solve an ABA 41 // handle and the ID of the corresponding process. When the DIB is mapped in
42 // a remote process, the section handle is duplicated for use in that process.
43 // However, if the remote process does not have permission to duplicate the
44 // handle, the first process must duplicate the handle before sending it.
45 // E.g., this is necessary if the DIB is created in the browser and will be
46 // mapped in the sandboxed renderer.
47 class TransferrableSectionHandle {
48 public:
49 TransferrableSectionHandle()
50 : section_(NULL), owner_id_(NULL), should_dup_on_map_(false) {
51 }
52
53 TransferrableSectionHandle(HANDLE section, base::ProcessId owner_id,
54 bool should_dup_on_map)
55 : section_(section),
56 owner_id_(owner_id),
57 should_dup_on_map_(should_dup_on_map) {
58 }
59
60 // Duplicates the handle for use in the given process.
61 TransferrableSectionHandle DupForProcess(
62 base::ProcessHandle new_owner) const;
63
64 // Closes this handle. This should be called if this handle was duplicated
65 // and is not owned by a TransportDIB.
66 void Close() const;
67
68 // Returns true if this handle refers to an actual file mapping.
69 bool is_valid() const { return section_ != NULL && owner_id_ != NULL; }
70
71 HANDLE section() const { return section_; }
72 base::ProcessId owner_id() const { return owner_id_; }
73 bool should_dup_on_map() const { return should_dup_on_map_; }
74
75 private:
76 HANDLE section_;
77 base::ProcessId owner_id_;
78 // Whether the handle should be duplicated when the DIB is mapped.
79 bool should_dup_on_map_;
80 };
81 typedef TransferrableSectionHandle Handle;
82
83 // On Windows, the Id type is a sequence number (epoch) to solve an ABA
41 // issue: 84 // issue:
42 // 1) Process A creates a transport DIB with HANDLE=1 and sends to B. 85 // 1) Process A creates a transport DIB with HANDLE=1 and sends to B.
43 // 2) Process B maps the transport DIB and caches 1 -> DIB. 86 // 2) Process B maps the transport DIB and caches 1 -> DIB.
44 // 3) Process A closes the transport DIB and creates a new one. The new DIB 87 // 3) Process A closes the transport DIB and creates a new one. The new DIB
45 // is also assigned HANDLE=1. 88 // is also assigned HANDLE=1.
46 // 4) Process A sends the Handle to B, but B incorrectly believes that it 89 // 4) Process A sends the Handle to B, but B incorrectly believes that it
47 // already has it cached. 90 // already has it cached.
48 struct HandleAndSequenceNum { 91 typedef uint32 Id;
49 HandleAndSequenceNum()
50 : handle(NULL),
51 sequence_num(0) {
52 }
53
54 HandleAndSequenceNum(HANDLE h, uint32 seq_num)
55 : handle(h),
56 sequence_num(seq_num) {
57 }
58
59 bool operator< (const HandleAndSequenceNum& other) const {
60 // Use the lexicographic order on the tuple <handle, sequence_num>.
61 if (other.handle != handle)
62 return other.handle < handle;
63 return other.sequence_num < sequence_num;
64 }
65
66 HANDLE handle;
67 uint32 sequence_num;
68 };
69 typedef HandleAndSequenceNum Id;
70 92
71 // Returns a default, invalid handle, that is meant to indicate a missing 93 // Returns a default, invalid handle, that is meant to indicate a missing
72 // Transport DIB. 94 // Transport DIB.
73 static Handle DefaultHandleValue() { return NULL; } 95 static Handle DefaultHandleValue() { return Handle(); }
74 96
75 // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE 97 // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE
76 // ACTUALLY USED AS A REAL HANDLE. 98 // ACTUALLY USED AS A REAL HANDLE.
77 static Handle GetFakeHandleForTest() { 99 static Handle GetFakeHandleForTest() {
78 static int fake_handle = 10; 100 static int fake_handle = 10;
79 return reinterpret_cast<Handle>(fake_handle++); 101 return Handle(reinterpret_cast<HANDLE>(fake_handle++), 1, false);
80 } 102 }
81 #elif defined(OS_MACOSX) 103 #elif defined(OS_MACOSX)
82 typedef base::SharedMemoryHandle Handle; 104 typedef base::SharedMemoryHandle Handle;
83 // On Mac, the inode number of the backing file is used as an id. 105 // On Mac, the inode number of the backing file is used as an id.
84 typedef base::SharedMemoryId Id; 106 typedef base::SharedMemoryId Id;
85 107
86 // Returns a default, invalid handle, that is meant to indicate a missing 108 // Returns a default, invalid handle, that is meant to indicate a missing
87 // Transport DIB. 109 // Transport DIB.
88 static Handle DefaultHandleValue() { return Handle(); } 110 static Handle DefaultHandleValue() { return Handle(); }
89 111
(...skipping 12 matching lines...) Expand all
102 static Handle DefaultHandleValue() { return -1; } 124 static Handle DefaultHandleValue() { return -1; }
103 125
104 // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE 126 // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE
105 // ACTUALLY USED AS A REAL HANDLE. 127 // ACTUALLY USED AS A REAL HANDLE.
106 static Handle GetFakeHandleForTest() { 128 static Handle GetFakeHandleForTest() {
107 static int fake_handle = 10; 129 static int fake_handle = 10;
108 return fake_handle++; 130 return fake_handle++;
109 } 131 }
110 #endif 132 #endif
111 133
112 // Create a new TransportDIB, returning NULL on failure. 134 // When passing a TransportDIB::Handle across processes, you must always close
135 // the handle, even if you return early, or the handle will be leaked. Typical
136 // usage will be:
137 //
138 // MyIPCHandler(TransportDIB::Handle dib_handle) {
139 // TransportDIB::ScopedHandle handle_scoper(dib_handle);
140 // ... do some stuff, possible returning early ...
141 //
142 // TransportDIB* dib = TransportDIB::Map(handle_scoper.release());
143 // // The handle lifetime is now managed by the TransportDIB.
144 class ScopedHandle {
145 public:
146 ScopedHandle() : handle_(DefaultHandleValue()) {}
147 explicit ScopedHandle(Handle handle) : handle_(handle) {}
148
149 ~ScopedHandle() {
150 Close();
151 }
152
153 Handle release() {
154 Handle temp = handle_;
155 handle_ = DefaultHandleValue();
156 return temp;
157 }
158
159 operator Handle() { return handle_; }
160
161 private:
162 void Close();
163
164 Handle handle_;
165 DISALLOW_COPY_AND_ASSIGN(ScopedHandle);
166 };
167
168 // Create a new |TransportDIB|, returning NULL on failure.
113 // 169 //
114 // The size is the minimum size in bytes of the memory backing the transport 170 // The size is the minimum size in bytes of the memory backing the transport
115 // DIB (we may actually allocate more than that to give us better reuse when 171 // DIB (we may actually allocate more than that to give us better reuse when
116 // cached). 172 // cached).
117 // 173 //
118 // The sequence number is used to uniquely identify the transport DIB. It 174 // The sequence number is used to uniquely identify the transport DIB. It
119 // should be unique for all transport DIBs ever created in the same 175 // should be unique for all transport DIBs ever created in the same
120 // renderer. 176 // renderer.
177 //
178 // On Linux, this will also map the DIB into the current process.
121 static TransportDIB* Create(size_t size, uint32 sequence_num); 179 static TransportDIB* Create(size_t size, uint32 sequence_num);
122 180
123 // Map the referenced transport DIB. The caller owns the returned object. 181 // Map the referenced transport DIB. The caller owns the returned object.
124 // Returns NULL on failure. 182 // Returns NULL on failure.
125 static TransportDIB* Map(Handle transport_dib); 183 static TransportDIB* Map(Handle transport_dib);
126 184
185 // Create a new |TransportDIB| with a handle to the shared memory. This
186 // always returns a valid pointer. The DIB is not mapped.
187 static TransportDIB* CreateWithHandle(Handle handle);
188
127 // Returns true if the handle is valid. 189 // Returns true if the handle is valid.
128 static bool is_valid(Handle dib); 190 static bool is_valid(Handle dib);
129 191
130 // Returns a canvas using the memory of this TransportDIB. The returned 192 // Returns a canvas using the memory of this TransportDIB. The returned
131 // pointer will be owned by the caller. The bitmap will be of the given size, 193 // pointer will be owned by the caller. The bitmap will be of the given size,
132 // which should fit inside this memory. 194 // which should fit inside this memory.
133 // 195 //
196 // On POSIX, this |TransportDIB| will be mapped if not already. On Windows,
197 // this |TransportDIB| will NOT be mapped and should not be mapped prior,
198 // because PlatformCanvas will map the file internally.
199 //
134 // Will return NULL on allocation failure. This could be because the image 200 // Will return NULL on allocation failure. This could be because the image
135 // is too large to map into the current process' address space. 201 // is too large to map into the current process' address space.
136 skia::PlatformCanvas* GetPlatformCanvas(int w, int h); 202 skia::PlatformCanvas* GetPlatformCanvas(int w, int h);
137 203
138 // Return a pointer to the shared memory 204 // Map the DIB into the current process if it is not already. This is used to
205 // map a DIB that has already been created. Returns true if the DIB is mapped.
206 bool Map();
207
208 // Return a handle for use in a specific process. On POSIX, this simply
209 // returns the handle as in the |handle| accessor below. On Windows, this
210 // returns a duplicate handle for use in the given process. This should be
211 // used instead of the |handle| accessor only if the process that will map
212 // this DIB does not have permission to duplicate the handle from the
213 // first process.
214 //
215 // Note: On Windows, if the duplicated handle is not closed by the other side
216 // (or this process fails to transmit the handle), the shared memory will be
217 // leaked.
218 Handle GetHandleForProcess(base::ProcessHandle process_handle) const;
219
220 // Return a pointer to the shared memory.
139 void* memory() const; 221 void* memory() const;
140 222
141 // Return the maximum size of the shared memory. This is not the amount of 223 // Return the maximum size of the shared memory. This is not the amount of
142 // data which is valid, you have to know that via other means, this is simply 224 // data which is valid, you have to know that via other means, this is simply
143 // the maximum amount that /could/ be valid. 225 // the maximum amount that /could/ be valid.
144 size_t size() const { return size_; } 226 size_t size() const { return size_; }
145 227
146 // Return the identifier which can be used to refer to this shared memory 228 // Return the identifier which can be used to refer to this shared memory
147 // on the wire. 229 // on the wire.
148 Id id() const; 230 Id id() const;
(...skipping 19 matching lines...) Expand all
168 void* address_; // mapped address 250 void* address_; // mapped address
169 XSharedMemoryId x_shm_; // X id for the shared segment 251 XSharedMemoryId x_shm_; // X id for the shared segment
170 Display* display_; // connection to the X server 252 Display* display_; // connection to the X server
171 #endif 253 #endif
172 size_t size_; // length, in bytes 254 size_t size_; // length, in bytes
173 255
174 DISALLOW_COPY_AND_ASSIGN(TransportDIB); 256 DISALLOW_COPY_AND_ASSIGN(TransportDIB);
175 }; 257 };
176 258
177 #endif // APP_SURFACE_TRANSPORT_DIB_H_ 259 #endif // APP_SURFACE_TRANSPORT_DIB_H_
OLDNEW
« no previous file with comments | « no previous file | app/surface/transport_dib_linux.cc » ('j') | app/surface/transport_dib_mac.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698