Bumping manifests a=b2g-bump
[gecko.git] / ipc / glue / FileDescriptor.h
blob59b5feb98c050eca959ad9b9e141908d60f541cb
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef mozilla_ipc_FileDescriptor_h
6 #define mozilla_ipc_FileDescriptor_h
8 #include "base/basictypes.h"
9 #include "base/process.h"
10 #include "mozilla/DebugOnly.h"
11 #include "nscore.h"
13 #ifdef XP_WIN
14 // Need the HANDLE typedef.
15 #include <winnt.h>
16 #else
17 #include "base/file_descriptor_posix.h"
18 #endif
20 namespace mozilla {
21 namespace ipc {
23 // This class is used by IPDL to share file descriptors across processes. When
24 // sending a FileDescriptor IPDL will first duplicate a platform-specific file
25 // handle type ('PlatformHandleType') into a handle that is valid in the other
26 // process. Then IPDL will convert the duplicated handle into a type suitable
27 // for pickling ('PickleType') and then send that through the IPC pipe. In the
28 // receiving process the pickled data is converted into a platform-specific file
29 // handle and then returned to the receiver.
31 // To use this class add 'FileDescriptor' as an argument in the IPDL protocol
32 // and then pass a file descriptor from C++ to the Call/Send method. The
33 // Answer/Recv method will receive a FileDescriptor& on which PlatformHandle()
34 // can be called to return the platform file handle.
35 class FileDescriptor
37 public:
38 typedef base::ProcessHandle ProcessHandle;
40 #ifdef XP_WIN
41 typedef HANDLE PlatformHandleType;
42 typedef HANDLE PickleType;
43 #else
44 typedef int PlatformHandleType;
45 typedef base::FileDescriptor PickleType;
46 #endif
48 // This should only ever be created by IPDL.
49 struct IPDLPrivate
50 {};
52 FileDescriptor();
54 FileDescriptor(const FileDescriptor& aOther)
55 : mHandleCreatedByOtherProcess(false),
56 mHandleCreatedByOtherProcessWasUsed(false)
58 // Don't use operator= here because that will call
59 // CloseCurrentProcessHandle() on this (uninitialized) object.
60 Assign(aOther);
63 explicit FileDescriptor(PlatformHandleType aHandle);
65 FileDescriptor(const IPDLPrivate&, const PickleType& aPickle)
66 #ifdef XP_WIN
67 : mHandle(aPickle)
68 #else
69 : mHandle(aPickle.fd)
70 #endif
71 , mHandleCreatedByOtherProcess(true)
72 , mHandleCreatedByOtherProcessWasUsed(false)
73 { }
75 ~FileDescriptor()
77 CloseCurrentProcessHandle();
80 FileDescriptor&
81 operator=(const FileDescriptor& aOther)
83 CloseCurrentProcessHandle();
84 Assign(aOther);
85 return *this;
88 // Performs platform-specific actions to duplicate mHandle in the other
89 // process (e.g. dup() on POSIX, DuplicateHandle() on Windows). Returns a
90 // pickled value that can be passed to the other process via IPC.
91 PickleType
92 ShareTo(const IPDLPrivate&, ProcessHandle aOtherProcess) const;
94 // Tests mHandle against a well-known invalid platform-specific file handle
95 // (e.g. -1 on POSIX, INVALID_HANDLE_VALUE on Windows).
96 bool
97 IsValid() const
99 return IsValid(mHandle);
102 PlatformHandleType
103 PlatformHandle() const
105 if (mHandleCreatedByOtherProcess) {
106 mHandleCreatedByOtherProcessWasUsed = true;
108 return mHandle;
111 bool
112 operator==(const FileDescriptor& aOther) const
114 return mHandle == aOther.mHandle;
117 private:
118 void
119 Assign(const FileDescriptor& aOther)
121 if (aOther.mHandleCreatedByOtherProcess) {
122 mHandleCreatedByOtherProcess = true;
123 mHandleCreatedByOtherProcessWasUsed =
124 aOther.mHandleCreatedByOtherProcessWasUsed;
125 mHandle = aOther.PlatformHandle();
126 } else {
127 DuplicateInCurrentProcess(aOther.PlatformHandle());
128 mHandleCreatedByOtherProcess = false;
129 mHandleCreatedByOtherProcessWasUsed = false;
133 static bool
134 IsValid(PlatformHandleType aHandle);
136 void
137 DuplicateInCurrentProcess(PlatformHandleType aHandle);
139 void
140 CloseCurrentProcessHandle();
142 PlatformHandleType mHandle;
144 // If this is true then this instance is created by IPDL to ferry a handle to
145 // its eventual consumer and we never close the handle. If this is false then
146 // we are a RAII wrapper around the handle and we close the handle on
147 // destruction.
148 bool mHandleCreatedByOtherProcess;
150 // This is to ensure that we don't leak the handle (which is only possible
151 // when we're in the receiving process).
152 mutable DebugOnly<bool> mHandleCreatedByOtherProcessWasUsed;
155 } // namespace ipc
156 } // namespace mozilla
158 #endif // mozilla_ipc_FileDescriptor_h