Roll google-toolbax-for-mac a095262:17eee69 (svn 685:703).
[chromium-blink-merge.git] / ipc / ipc_message_attachment_set.h
bloba143570c4f92665379b5260334a67f6ccc38a4e2
1 // Copyright (c) 2011 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 IPC_IPC_MESSAGE_ATTACHMENT_SET_H_
6 #define IPC_IPC_MESSAGE_ATTACHMENT_SET_H_
8 #include <vector>
10 #include "base/basictypes.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_vector.h"
13 #include "ipc/ipc_export.h"
15 #if defined(OS_POSIX)
16 #include "base/files/file.h"
17 #endif
19 namespace IPC {
21 class MessageAttachment;
23 // -----------------------------------------------------------------------------
24 // A MessageAttachmentSet is an ordered set of POSIX file descriptors. These are
25 // associated with IPC messages so that descriptors can be transmitted over a
26 // UNIX domain socket.
27 // -----------------------------------------------------------------------------
28 class IPC_EXPORT MessageAttachmentSet
29 : public base::RefCountedThreadSafe<MessageAttachmentSet> {
30 public:
31 MessageAttachmentSet();
33 // Return the number of attachments
34 unsigned size() const;
35 // Return the number of file descriptors
36 unsigned num_descriptors() const;
37 // Return true if no unconsumed descriptors remain
38 bool empty() const { return 0 == size(); }
40 void AddAttachment(scoped_refptr<MessageAttachment> attachment);
41 scoped_refptr<MessageAttachment> GetAttachmentAt(unsigned index);
43 #if defined(OS_POSIX)
44 // This is the maximum number of descriptors per message. We need to know this
45 // because the control message kernel interface has to be given a buffer which
46 // is large enough to store all the descriptor numbers. Otherwise the kernel
47 // tells us that it truncated the control data and the extra descriptors are
48 // lost.
50 // In debugging mode, it's a fatal error to try and add more than this number
51 // of descriptors to a MessageAttachmentSet.
52 static const size_t kMaxDescriptorsPerMessage = 7;
54 // ---------------------------------------------------------------------------
55 // Interfaces for building during message serialisation...
57 // Add a descriptor to the end of the set. Returns false iff the set is full.
58 bool AddToBorrow(base::PlatformFile fd);
59 // Add a descriptor to the end of the set and automatically close it after
60 // transmission. Returns false iff the set is full.
61 bool AddToOwn(base::ScopedFD fd);
63 // ---------------------------------------------------------------------------
64 // ---------------------------------------------------------------------------
65 // Interfaces for accessing during message deserialisation...
67 // Take the nth descriptor from the beginning of the set,
68 // transferring the ownership of the descriptor taken. Code using this
69 // /must/ access the descriptors in order, and must do it at most once.
71 // This interface is designed for the deserialising code as it doesn't
72 // support close flags.
73 // returns: file descriptor, or -1 on error
74 base::PlatformFile TakeDescriptorAt(unsigned n);
76 // ---------------------------------------------------------------------------
78 // ---------------------------------------------------------------------------
79 // Interfaces for transmission...
81 // Fill an array with file descriptors without 'consuming' them. CommitAll
82 // must be called after these descriptors have been transmitted.
83 // buffer: (output) a buffer of, at least, size() integers.
84 void PeekDescriptors(base::PlatformFile* buffer) const;
85 // This must be called after transmitting the descriptors returned by
86 // PeekDescriptors. It marks all the descriptors as consumed and closes those
87 // which are auto-close.
88 void CommitAll();
89 // Returns true if any contained file descriptors appear to be handles to a
90 // directory.
91 bool ContainsDirectoryDescriptor() const;
92 // Fetch all filedescriptors with the "auto close" property.
93 // Used instead of CommitAll() when closing must be handled manually.
94 void ReleaseFDsToClose(std::vector<base::PlatformFile>* fds);
96 // ---------------------------------------------------------------------------
98 // ---------------------------------------------------------------------------
99 // Interfaces for receiving...
101 // Set the contents of the set from the given buffer. This set must be empty
102 // before calling. The auto-close flag is set on all the descriptors so that
103 // unconsumed descriptors are closed on destruction.
104 void AddDescriptorsToOwn(const base::PlatformFile* buffer, unsigned count);
106 #endif // OS_POSIX
108 // ---------------------------------------------------------------------------
110 private:
111 friend class base::RefCountedThreadSafe<MessageAttachmentSet>;
113 ~MessageAttachmentSet();
115 // A vector of attachments of the message, which might be |PlatformFile| or
116 // |MessagePipe|.
117 std::vector<scoped_refptr<MessageAttachment>> attachments_;
119 #if defined(OS_POSIX)
120 // A vector of owning descriptors. If this message is sent, then file
121 // descriptors are sent as control data. After sending, any owning descriptors
122 // are closed. If this message has been received then all received
123 // descriptors are owned by this message.
124 ScopedVector<base::ScopedFD> owned_descriptors_;
125 #endif
127 // This contains the index of the next descriptor which should be consumed.
128 // It's used in a couple of ways. Firstly, at destruction we can check that
129 // all the descriptors have been read (with GetNthDescriptor). Secondly, we
130 // can check that they are read in order.
131 mutable unsigned consumed_descriptor_highwater_;
133 DISALLOW_COPY_AND_ASSIGN(MessageAttachmentSet);
136 } // namespace IPC
138 #endif // IPC_IPC_MESSAGE_ATTACHMENT_SET_H_