serialized_handle.h revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
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.
4
5#ifndef PPAPI_PROXY_SERIALIZED_HANDLES_H_
6#define PPAPI_PROXY_SERIALIZED_HANDLES_H_
7
8#include <string>
9#include <vector>
10
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"
17
18class Pickle;
19
20namespace ppapi {
21namespace proxy {
22
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.
27class PPAPI_PROXY_EXPORT SerializedHandle {
28 public:
29  enum Type { INVALID, SHARED_MEMORY, SOCKET, CHANNEL_HANDLE, FILE };
30  struct Header {
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) {
34    }
35    Type type;
36    uint32 size;
37    int32 open_flag;
38  };
39
40  SerializedHandle();
41  // Create an invalid handle of the given type.
42  explicit SerializedHandle(Type type);
43
44  // Create a shared memory handle.
45  SerializedHandle(const base::SharedMemoryHandle& handle, uint32 size);
46
47  // Create a socket, channel or file handle.
48  SerializedHandle(const Type type,
49                   const IPC::PlatformFileForTransit& descriptor);
50
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 {
57    DCHECK(is_shmem());
58    return shm_handle_;
59  }
60  uint32 size() const {
61    DCHECK(is_shmem());
62    return size_;
63  }
64  const IPC::PlatformFileForTransit& descriptor() const {
65    DCHECK(is_socket() || is_channel_handle() || is_file());
66    return descriptor_;
67  }
68  int32 open_flag() const {
69    return open_flag_;
70  }
71  void set_shmem(const base::SharedMemoryHandle& handle, uint32 size) {
72    type_ = SHARED_MEMORY;
73    shm_handle_ = handle;
74    size_ = size;
75
76    descriptor_ = IPC::InvalidPlatformFileForTransit();
77  }
78  void set_socket(const IPC::PlatformFileForTransit& socket) {
79    type_ = SOCKET;
80    descriptor_ = socket;
81
82    shm_handle_ = base::SharedMemory::NULLHandle();
83    size_ = 0;
84  }
85  void set_channel_handle(const IPC::PlatformFileForTransit& descriptor) {
86    type_ = CHANNEL_HANDLE;
87
88    descriptor_ = descriptor;
89    shm_handle_ = base::SharedMemory::NULLHandle();
90    size_ = 0;
91  }
92  void set_file_handle(const IPC::PlatformFileForTransit& descriptor,
93                       int32 open_flag) {
94    type_ = FILE;
95
96    descriptor_ = descriptor;
97    shm_handle_ = base::SharedMemory::NULLHandle();
98    size_ = 0;
99    open_flag_ = open_flag;
100  }
101  void set_null_shmem() {
102    set_shmem(base::SharedMemory::NULLHandle(), 0);
103  }
104  void set_null_socket() {
105    set_socket(IPC::InvalidPlatformFileForTransit());
106  }
107  void set_null_channel_handle() {
108    set_channel_handle(IPC::InvalidPlatformFileForTransit());
109  }
110  void set_null_file_handle() {
111    set_file_handle(IPC::InvalidPlatformFileForTransit(), 0);
112  }
113  bool IsHandleValid() const;
114
115  Header header() const {
116    return Header(type_, size_, open_flag_);
117  }
118
119  // Closes the handle and sets it to invalid.
120  void Close();
121
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);
127
128 private:
129  // The kind of handle we're holding.
130  Type type_;
131
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_;
138  uint32 size_;
139
140  // This is valid if type == SOCKET || type == CHANNEL_HANDLE || type == FILE.
141  IPC::PlatformFileForTransit descriptor_;
142
143  // This is valid if type == FILE.
144  int32 open_flag_;
145};
146
147}  // namespace proxy
148}  // namespace ppapi
149
150#endif  // PPAPI_PROXY_SERIALIZED_HANDLES_H_
151