michael@0: // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef CHROME_COMMON_TRANSPORT_DIB_H_ michael@0: #define CHROME_COMMON_TRANSPORT_DIB_H_ michael@0: michael@0: #include "base/basictypes.h" michael@0: michael@0: #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_BSD) michael@0: #include "base/shared_memory.h" michael@0: #endif michael@0: michael@0: #if defined(OS_WIN) michael@0: #include michael@0: #elif defined(OS_LINUX) michael@0: #include "chrome/common/x11_util.h" michael@0: #endif michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // A TransportDIB is a block of memory that is used to transport pixels michael@0: // between processes: from the renderer process to the browser, and michael@0: // between renderer and plugin processes. michael@0: // ----------------------------------------------------------------------------- michael@0: class TransportDIB { michael@0: public: michael@0: ~TransportDIB(); michael@0: michael@0: // Two typedefs are defined. A Handle is the type which can be sent over michael@0: // the wire so that the remote side can map the transport DIB. The Id typedef michael@0: // is sufficient to identify the transport DIB when you know that the remote michael@0: // side already may have it mapped. michael@0: #if defined(OS_WIN) michael@0: typedef HANDLE Handle; michael@0: // On Windows, the Id type includes a sequence number (epoch) to solve an ABA michael@0: // issue: michael@0: // 1) Process A creates a transport DIB with HANDLE=1 and sends to B. michael@0: // 2) Process B maps the transport DIB and caches 1 -> DIB. michael@0: // 3) Process A closes the transport DIB and creates a new one. The new DIB michael@0: // is also assigned HANDLE=1. michael@0: // 4) Process A sends the Handle to B, but B incorrectly believes that it michael@0: // already has it cached. michael@0: struct HandleAndSequenceNum { michael@0: HandleAndSequenceNum() michael@0: : handle(NULL), michael@0: sequence_num(0) { michael@0: } michael@0: michael@0: HandleAndSequenceNum(HANDLE h, uint32_t seq_num) michael@0: : handle(h), michael@0: sequence_num(seq_num) { michael@0: } michael@0: michael@0: bool operator< (const HandleAndSequenceNum& other) const { michael@0: // Use the lexicographic order on the tuple . michael@0: if (other.handle != handle) michael@0: return other.handle < handle; michael@0: return other.sequence_num < sequence_num; michael@0: } michael@0: michael@0: HANDLE handle; michael@0: uint32_t sequence_num; michael@0: }; michael@0: typedef HandleAndSequenceNum Id; michael@0: #elif defined(OS_MACOSX) || defined(OS_BSD) michael@0: typedef base::SharedMemoryHandle Handle; michael@0: // On Mac, the inode number of the backing file is used as an id. michael@0: typedef base::SharedMemoryId Id; michael@0: #elif defined(OS_LINUX) michael@0: typedef int Handle; // These two ints are SysV IPC shared memory keys michael@0: typedef int Id; michael@0: #endif michael@0: michael@0: // Create a new TransportDIB michael@0: // size: the minimum size, in bytes michael@0: // epoch: Windows only: a global counter. See comment above. michael@0: // returns: NULL on failure michael@0: static TransportDIB* Create(size_t size, uint32_t sequence_num); michael@0: michael@0: // Map the referenced transport DIB. Returns NULL on failure. michael@0: static TransportDIB* Map(Handle transport_dib); michael@0: michael@0: // Return a pointer to the shared memory michael@0: void* memory() const; michael@0: michael@0: // Return the maximum size of the shared memory. This is not the amount of michael@0: // data which is valid, you have to know that via other means, this is simply michael@0: // the maximum amount that /could/ be valid. michael@0: size_t size() const { return size_; } michael@0: michael@0: // Return the identifier which can be used to refer to this shared memory michael@0: // on the wire. michael@0: Id id() const; michael@0: michael@0: // Return a handle to the underlying shared memory. This can be sent over the michael@0: // wire to give this transport DIB to another process. michael@0: Handle handle() const; michael@0: michael@0: #if defined(OS_LINUX) michael@0: // Map the shared memory into the X server and return an id for the shared michael@0: // segment. michael@0: XID MapToX(Display* connection); michael@0: #endif michael@0: michael@0: private: michael@0: TransportDIB(); michael@0: #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_BSD) michael@0: explicit TransportDIB(base::SharedMemoryHandle dib); michael@0: base::SharedMemory shared_memory_; michael@0: #elif defined(OS_LINUX) michael@0: int key_; // SysV shared memory id michael@0: void* address_; // mapped address michael@0: XID x_shm_; // X id for the shared segment michael@0: Display* display_; // connection to the X server michael@0: #endif michael@0: #ifdef OS_WIN michael@0: uint32_t sequence_num_; michael@0: #endif michael@0: size_t size_; // length, in bytes michael@0: }; michael@0: michael@0: class MessageLoop; michael@0: michael@0: #endif // CHROME_COMMON_TRANSPORT_DIB_H_