1 // Copyright (c) 2013 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.
5 #ifndef PPAPI_PROXY_SERIALIZED_HANDLES_H_
6 #define PPAPI_PROXY_SERIALIZED_HANDLES_H_
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/memory/shared_memory.h"
14 #include "build/build_config.h"
15 #include "ipc/ipc_platform_file.h"
16 #include "ppapi/proxy/ppapi_proxy_export.h"
23 // SerializedHandle is a unified structure for holding a handle (e.g., a shared
24 // memory handle, socket descriptor, etc). This is useful for passing handles in
25 // resource messages and also makes it easier to translate handles in
26 // NaClIPCAdapter for use in NaCl.
27 class PPAPI_PROXY_EXPORT SerializedHandle {
29 enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE };
31 Header() : type(INVALID), size(0), open_flag(0) {}
32 Header(Type type_arg, uint32 size_arg, int32 open_flag_arg)
33 : type(type_arg), size(size_arg), open_flag(open_flag_arg) {
41 // Create an invalid handle of the given type.
42 explicit SerializedHandle(Type type);
44 // Create a shared memory handle.
45 SerializedHandle(const base::SharedMemoryHandle& handle, uint32 size);
47 // Create a socket, channel or file handle.
48 SerializedHandle(const Type type,
49 const IPC::PlatformFileForTransit& descriptor);
51 Type type() const { return type_; }
52 bool is_shmem() const { return type_ == SHARED_MEMORY; }
53 bool is_socket() const { return type_ == SOCKET; }
54 bool is_channel_handle() const { return type_ == CHANNEL_HANDLE; }
55 bool is_file() const { return type_ == FILE; }
56 const base::SharedMemoryHandle& shmem() const {
64 const IPC::PlatformFileForTransit& descriptor() const {
65 DCHECK(is_socket() || is_channel_handle() || is_file());
68 int32 open_flag() const {
71 void set_shmem(const base::SharedMemoryHandle& handle, uint32 size) {
72 type_ = SHARED_MEMORY;
76 descriptor_ = IPC::InvalidPlatformFileForTransit();
78 void set_socket(const IPC::PlatformFileForTransit& socket) {
82 shm_handle_ = base::SharedMemory::NULLHandle();
85 void set_channel_handle(const IPC::PlatformFileForTransit& descriptor) {
86 type_ = CHANNEL_HANDLE;
88 descriptor_ = descriptor;
89 shm_handle_ = base::SharedMemory::NULLHandle();
92 void set_file_handle(const IPC::PlatformFileForTransit& descriptor,
96 descriptor_ = descriptor;
97 shm_handle_ = base::SharedMemory::NULLHandle();
99 open_flag_ = open_flag;
101 void set_null_shmem() {
102 set_shmem(base::SharedMemory::NULLHandle(), 0);
104 void set_null_socket() {
105 set_socket(IPC::InvalidPlatformFileForTransit());
107 void set_null_channel_handle() {
108 set_channel_handle(IPC::InvalidPlatformFileForTransit());
110 void set_null_file_handle() {
111 set_file_handle(IPC::InvalidPlatformFileForTransit(), 0);
113 bool IsHandleValid() const;
115 Header header() const {
116 return Header(type_, size_, open_flag_);
119 // Closes the handle and sets it to invalid.
122 // Write/Read a Header, which contains all the data except the handle. This
123 // allows us to write the handle in a platform-specific way, as is necessary
124 // in NaClIPCAdapter to share handles with NaCl from Windows.
125 static bool WriteHeader(const Header& hdr, Pickle* pickle);
126 static bool ReadHeader(PickleIterator* iter, Header* hdr);
129 // The kind of handle we're holding.
132 // We hold more members than we really need; we can't easily use a union,
133 // because we hold non-POD types. But these types are pretty light-weight. If
134 // we add more complex things later, we should come up with a more memory-
135 // efficient strategy.
136 // These are valid if type == SHARED_MEMORY.
137 base::SharedMemoryHandle shm_handle_;
140 // This is valid if type == SOCKET || type == CHANNEL_HANDLE || type == FILE.
141 IPC::PlatformFileForTransit descriptor_;
143 // This is valid if type == FILE.
150 #endif // PPAPI_PROXY_SERIALIZED_HANDLES_H_