OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #ifndef CRASHPAD_UTIL_MACH_MACH_MESSAGE_SERVER_H_ | |
16 #define CRASHPAD_UTIL_MACH_MACH_MESSAGE_SERVER_H_ | |
17 | |
18 #include <mach/mach.h> | |
19 | |
20 #include "base/basictypes.h" | |
21 | |
22 namespace crashpad { | |
23 | |
24 //! \brief Runs a Mach message server to handle a Mach RPC request for MIG | |
25 //! servers. | |
26 //! | |
27 //! The principal entry point to this interface is the static Run() method. | |
28 class MachMessageServer { | |
29 public: | |
30 //! \brief A Mach RPC callback interface, called by Run(). | |
31 class Interface { | |
32 public: | |
33 //! \brief Handles a Mach RPC request. | |
34 //! | |
35 //! This method is a stand-in for a MIG-generated Mach RPC server “demux” | |
36 //! function such as `exc_server()` and `mach_exc_server()`. Implementations | |
37 //! may call such a function directly. This method is expected to behave | |
38 //! exactly as these functions behave. | |
39 //! | |
40 //! \param[in] in The request message, received as a Mach message. | |
41 //! \param[out] out The reply message. The caller allocates storage, and the | |
42 //! callee is expected to populate the reply message appropriately. | |
43 //! After returning, the caller will send this reply as a Mach message | |
44 //! via the message’s reply port. | |
45 //! \param[out] destroy_complex_request `true` if a complex request message | |
46 //! is to be destroyed even when handled successfully, `false` | |
47 //! otherwise. The traditional behavior is `false`. In this case, the | |
48 //! caller only destroys the request message in \a in when the reply | |
49 //! message in \a out is not complex and when it indicates a return code | |
50 //! other than `KERN_SUCCESS` or `MIG_NO_REPLY`. The assumption is that | |
51 //! the rights or out-of-line data carried in a complex message may be | |
52 //! retained by the server in this situation, and that it is the | |
53 //! responsibility of the server to release these resources as needed. | |
54 //! However, in many cases, these resources are not needed beyond the | |
55 //! duration of a request-reply transaction, and in such cases, it is | |
56 //! less error-prone to always have the caller, | |
57 //! MachMessageServer::Run(), destroy complex request messages. To | |
58 //! choose this behavior, this parameter should be set to `true`. | |
59 //! | |
60 //! \return `true` on success and `false` on failure, although the caller | |
61 //! ignores the return value. However, the return code to be included in | |
62 //! the reply message should be set as `mig_reply_error_t::RetCode`. The | |
63 //! non-`void` return value is used for increased compatibility with | |
64 //! MIG-generated functions. | |
65 virtual bool MachMessageServerFunction(mach_msg_header_t* in, | |
66 mach_msg_header_t* out, | |
67 bool* destroy_complex_request) = 0; | |
68 | |
69 //! \return The expected or maximum size, in bytes, of a request message to | |
70 //! be received as the \a in parameter of Run(). | |
Robert Sesek
2014/09/09 00:21:58
Run() or MachMessageServerFunction()? Same on line
| |
71 virtual mach_msg_size_t MachMessageServerRequestSize() = 0; | |
72 | |
73 //! \return The maximum size, in bytes, of a reply message to be sent via | |
74 //! the \a out parameter of Run(). This value does not need to include | |
75 //! the size of any trailer to be sent with the message. | |
76 virtual mach_msg_size_t MachMessageServerReplySize() = 0; | |
77 | |
78 protected: | |
79 ~Interface() {} | |
80 }; | |
81 | |
82 //! \brief Informs Run() whether to handle a single request-reply transaction | |
83 //! or to run in a loop. | |
84 enum Persistent { | |
85 //! \brief Handle a single request-reply transaction and then return. | |
86 kOneShot = false, | |
87 | |
88 //! \brief Run in a loop, potentially handling multiple request-reply | |
89 //! transactions. | |
90 kPersistent, | |
91 }; | |
92 | |
93 //! \brief Informs Run() whether or not to block while waiting for requests. | |
94 enum Nonblocking { | |
95 //! \brief Wait for a request message if none is queued. | |
96 kBlocking = false, | |
97 | |
98 //! \brief Return as soon as there no request messages queued. This may | |
99 //! result in an immediate return without handling any requests. | |
100 kNonblocking, | |
101 }; | |
102 | |
103 //! \brief Runs a Mach message server to handle a Mach RPC request for MIG | |
104 //! servers. | |
105 //! | |
106 //! This function listens for a request message and passes it to a callback | |
107 //! interface. A reponse is collected from that interface, and is sent back as | |
108 //! a reply. | |
109 //! | |
110 //! This function is similar to `mach_msg_server()` and | |
111 //! `mach_msg_server_once()`. | |
112 //! | |
113 //! \param[in] interface The MachMessageServerInterface that is responsible | |
114 //! for handling the message. Interface::MachMessageServerRequestSize() is | |
115 //! used as the receive size for the request message, and | |
116 //! Interface::MachMessageServerReplySize() is used as the | |
117 //! maximum size of the reply message. If \a options contains | |
118 //! `MACH_RCV_LARGE`, this function will retry a receive operation that | |
119 //! returns `MACH_RCV_TOO_LARGE` with an appropriately-sized buffer. | |
120 //! MachMessageServerInterface::MachMessageServerFunction() is called to | |
121 //! handle the request and populate the reply. | |
122 //! \param[in] receive_port The port on which to receive the request message. | |
123 //! \param[in] options Options suitable for mach_msg. | |
124 //! \param[in] persistent Chooses between one-shot and persistent operation. | |
125 //! \param[in] nonblocking Chooses between blocking and nonblocking operation. | |
126 //! \param[in] timeout_ms When \a nonblocking is `false`, the the maximum | |
127 //! duration that this entire function will run, in milliseconds, or | |
128 //! `MACH_MSG_TIMEOUT_NONE` to specify no timeout (infinite waiting). When | |
129 //! \a nonblocking is `true`, this parameter has no effect. When \a | |
130 //! persistent is `true`, the timeout applies to the overall duration of | |
131 //! this function, not to any individual `mach_msg()` call. | |
132 //! | |
133 //! \return On success, `KERN_SUCCESS` (when \a persistent is `false`) or | |
134 //! `MACH_RCV_TIMED_OUT` (when \a persistent and \a nonblocking are both | |
135 //! `true`, or when \a persistent is `true`, \a nonblocking is `false`, | |
136 //! and \a timeout is not `MACH_MSG_TIMEOUT_NONE`. This function has no | |
137 //! successful return value when \a persistent is `true`, \a nonblocking | |
138 //! is `false`, and \a timeout is `MACH_MSG_TIMEOUT_NONE`. On failure, | |
139 //! returns a value identifying the nature of the error. | |
140 static mach_msg_return_t Run(Interface* interface, | |
141 mach_port_t receive_port, | |
142 mach_msg_options_t options, | |
143 Persistent persistent, | |
144 Nonblocking nonblocking, | |
145 mach_msg_timeout_t timeout_ms); | |
146 | |
147 private: | |
148 DISALLOW_IMPLICIT_CONSTRUCTORS(MachMessageServer); | |
149 }; | |
150 | |
151 } // namespace crashpad | |
152 | |
153 #endif // CRASHPAD_UTIL_MACH_MACH_MESSAGE_SERVER_H_ | |
OLD | NEW |