|
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 #ifndef CHROME_COMMON_TRANSPORT_DIB_H_ |
|
6 #define CHROME_COMMON_TRANSPORT_DIB_H_ |
|
7 |
|
8 #include "base/basictypes.h" |
|
9 |
|
10 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_BSD) |
|
11 #include "base/shared_memory.h" |
|
12 #endif |
|
13 |
|
14 #if defined(OS_WIN) |
|
15 #include <windows.h> |
|
16 #elif defined(OS_LINUX) |
|
17 #include "chrome/common/x11_util.h" |
|
18 #endif |
|
19 |
|
20 // ----------------------------------------------------------------------------- |
|
21 // A TransportDIB is a block of memory that is used to transport pixels |
|
22 // between processes: from the renderer process to the browser, and |
|
23 // between renderer and plugin processes. |
|
24 // ----------------------------------------------------------------------------- |
|
25 class TransportDIB { |
|
26 public: |
|
27 ~TransportDIB(); |
|
28 |
|
29 // Two typedefs are defined. A Handle is the type which can be sent over |
|
30 // the wire so that the remote side can map the transport DIB. The Id typedef |
|
31 // is sufficient to identify the transport DIB when you know that the remote |
|
32 // side already may have it mapped. |
|
33 #if defined(OS_WIN) |
|
34 typedef HANDLE Handle; |
|
35 // On Windows, the Id type includes a sequence number (epoch) to solve an ABA |
|
36 // issue: |
|
37 // 1) Process A creates a transport DIB with HANDLE=1 and sends to B. |
|
38 // 2) Process B maps the transport DIB and caches 1 -> DIB. |
|
39 // 3) Process A closes the transport DIB and creates a new one. The new DIB |
|
40 // is also assigned HANDLE=1. |
|
41 // 4) Process A sends the Handle to B, but B incorrectly believes that it |
|
42 // already has it cached. |
|
43 struct HandleAndSequenceNum { |
|
44 HandleAndSequenceNum() |
|
45 : handle(NULL), |
|
46 sequence_num(0) { |
|
47 } |
|
48 |
|
49 HandleAndSequenceNum(HANDLE h, uint32_t seq_num) |
|
50 : handle(h), |
|
51 sequence_num(seq_num) { |
|
52 } |
|
53 |
|
54 bool operator< (const HandleAndSequenceNum& other) const { |
|
55 // Use the lexicographic order on the tuple <handle, sequence_num>. |
|
56 if (other.handle != handle) |
|
57 return other.handle < handle; |
|
58 return other.sequence_num < sequence_num; |
|
59 } |
|
60 |
|
61 HANDLE handle; |
|
62 uint32_t sequence_num; |
|
63 }; |
|
64 typedef HandleAndSequenceNum Id; |
|
65 #elif defined(OS_MACOSX) || defined(OS_BSD) |
|
66 typedef base::SharedMemoryHandle Handle; |
|
67 // On Mac, the inode number of the backing file is used as an id. |
|
68 typedef base::SharedMemoryId Id; |
|
69 #elif defined(OS_LINUX) |
|
70 typedef int Handle; // These two ints are SysV IPC shared memory keys |
|
71 typedef int Id; |
|
72 #endif |
|
73 |
|
74 // Create a new TransportDIB |
|
75 // size: the minimum size, in bytes |
|
76 // epoch: Windows only: a global counter. See comment above. |
|
77 // returns: NULL on failure |
|
78 static TransportDIB* Create(size_t size, uint32_t sequence_num); |
|
79 |
|
80 // Map the referenced transport DIB. Returns NULL on failure. |
|
81 static TransportDIB* Map(Handle transport_dib); |
|
82 |
|
83 // Return a pointer to the shared memory |
|
84 void* memory() const; |
|
85 |
|
86 // Return the maximum size of the shared memory. This is not the amount of |
|
87 // data which is valid, you have to know that via other means, this is simply |
|
88 // the maximum amount that /could/ be valid. |
|
89 size_t size() const { return size_; } |
|
90 |
|
91 // Return the identifier which can be used to refer to this shared memory |
|
92 // on the wire. |
|
93 Id id() const; |
|
94 |
|
95 // Return a handle to the underlying shared memory. This can be sent over the |
|
96 // wire to give this transport DIB to another process. |
|
97 Handle handle() const; |
|
98 |
|
99 #if defined(OS_LINUX) |
|
100 // Map the shared memory into the X server and return an id for the shared |
|
101 // segment. |
|
102 XID MapToX(Display* connection); |
|
103 #endif |
|
104 |
|
105 private: |
|
106 TransportDIB(); |
|
107 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_BSD) |
|
108 explicit TransportDIB(base::SharedMemoryHandle dib); |
|
109 base::SharedMemory shared_memory_; |
|
110 #elif defined(OS_LINUX) |
|
111 int key_; // SysV shared memory id |
|
112 void* address_; // mapped address |
|
113 XID x_shm_; // X id for the shared segment |
|
114 Display* display_; // connection to the X server |
|
115 #endif |
|
116 #ifdef OS_WIN |
|
117 uint32_t sequence_num_; |
|
118 #endif |
|
119 size_t size_; // length, in bytes |
|
120 }; |
|
121 |
|
122 class MessageLoop; |
|
123 |
|
124 #endif // CHROME_COMMON_TRANSPORT_DIB_H_ |