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_NOTIFY_SERVER_H_ |
| 16 #define CRASHPAD_UTIL_MACH_NOTIFY_SERVER_H_ |
| 17 |
| 18 #include <mach/mach.h> |
| 19 |
| 20 #include <set> |
| 21 |
| 22 #include "base/basictypes.h" |
| 23 #include "util/mach/mach_message_server.h" |
| 24 |
| 25 namespace crashpad { |
| 26 |
| 27 //! \brief A server interface for the `notify` Mach subsystem. |
| 28 //! |
| 29 //! The <a |
| 30 //! href="https://lists.apple.com/archives/darwin-development/2001/Sep/msg00451.
html">mach |
| 31 //! port notifications</a> thread on the <a |
| 32 //! href="https://lists.apple.com/archives/darwin-development/">darwin-developme
nt</a> |
| 33 //! mailing list (now known as <a |
| 34 //! href="https://lists.apple.com/mailman/listinfo/darwin-dev">darwin-dev</a>) |
| 35 //! is good background for the various notification types. |
| 36 class NotifyServer : public MachMessageServer::Interface { |
| 37 public: |
| 38 //! \brief An interface that the different request messages that are a part of |
| 39 //! the `notify` Mach subsystem can be dispatched to. |
| 40 class Interface { |
| 41 public: |
| 42 //! \brief Handles port-deleted notifications sent by |
| 43 //! `mach_notify_port_deleted()`. |
| 44 //! |
| 45 //! A port-deleted notification is generated when a port with a dead-name |
| 46 //! notification request is destroyed and the port name becomes available |
| 47 //! for reuse. |
| 48 //! |
| 49 //! This behaves equivalently to a `do_mach_notify_port_deleted()` function |
| 50 //! used with `notify_server()`. |
| 51 //! |
| 52 //! \param[in] notify The Mach port that the notification was sent to. |
| 53 //! \param[in] name The name that formerly referenced the deleted port. When |
| 54 //! this method is called, \a name no longer corresponds to the port |
| 55 //! that has been deleted, and may be reused for another purpose. |
| 56 //! \param[in] trailer The trailer received with the notification message. |
| 57 virtual kern_return_t DoMachNotifyPortDeleted( |
| 58 notify_port_t notify, |
| 59 mach_port_name_t name, |
| 60 const mach_msg_trailer_t* trailer) = 0; |
| 61 |
| 62 //! \brief Handles port-destroyed notifications sent by |
| 63 //! `mach_notify_port_destroyed()`. |
| 64 //! |
| 65 //! A port-destroyed notification is generated when a receive right with a |
| 66 //! port-destroyed notification request is destroyed. Rather than destroying |
| 67 //! the receive right, it is transferred via this notification’s \a rights |
| 68 //! parameter. |
| 69 //! |
| 70 //! This behaves equivalently to a `do_mach_notify_port_destroyed()` |
| 71 //! function used with `notify_server()`. |
| 72 //! |
| 73 //! \param[in] notify The Mach port that the notification was sent to. |
| 74 //! \param[in] rights A receive right for the port that would have been |
| 75 //! destroyed. The callee takes ownership of this port, however, if the |
| 76 //! callee does not wish to take ownership, it may set \a |
| 77 //! destroy_request to `true`. |
| 78 //! \param[in] trailer The trailer received with the notification message. |
| 79 //! \param[out] destroy_request `true` if the request message is to be |
| 80 //! destroyed even when this method returns success. See |
| 81 //! MachMessageServer::Interface. |
| 82 virtual kern_return_t DoMachNotifyPortDestroyed( |
| 83 notify_port_t notify, |
| 84 mach_port_t rights, |
| 85 const mach_msg_trailer_t* trailer, |
| 86 bool* destroy_request) = 0; |
| 87 |
| 88 //! \brief Handles no-senders notifications sent by |
| 89 //! `mach_notify_no_senders()`. |
| 90 //! |
| 91 //! A no-senders notification is generated when a receive right with a |
| 92 //! no-senders notification request loses its last corresponding send right. |
| 93 //! |
| 94 //! This behaves equivalently to a `do_mach_notify_no_senders()` function |
| 95 //! used with `notify_server()`. |
| 96 //! |
| 97 //! \param[in] notify The Mach port that the notification was sent to. |
| 98 //! \param[in] mscount The value of the sender-less port’s make-send count |
| 99 //! at the time the notification was generated. |
| 100 //! \param[in] trailer The trailer received with the notification message. |
| 101 virtual kern_return_t DoMachNotifyNoSenders( |
| 102 notify_port_t notify, |
| 103 mach_port_mscount_t mscount, |
| 104 const mach_msg_trailer_t* trailer) = 0; |
| 105 |
| 106 //! \brief Handles send-once notifications sent by |
| 107 //! `mach_notify_send_once()`. |
| 108 //! |
| 109 //! A send-once notification is generated when a send-once right is |
| 110 //! destroyed without being used. |
| 111 //! |
| 112 //! This behaves equivalently to a `do_mach_notify_send_once()` function |
| 113 //! used with `notify_server()`. |
| 114 //! |
| 115 //! \param[in] notify The Mach port that the notification was sent to. |
| 116 //! \param[in] trailer The trailer received with the notification message. |
| 117 //! |
| 118 //! \note Unlike the other notifications in the `notify` subsystem, |
| 119 //! send-once notifications are not generated as a result of a |
| 120 //! notification request, but are generated any time a send-once right |
| 121 //! is destroyed rather than being used. The notification is sent via |
| 122 //! the send-once right to its receiver. These notifications are more |
| 123 //! useful for clients, not servers. Send-once notifications are |
| 124 //! normally handled by MIG-generated client routines, which make |
| 125 //! send-once rights for their reply ports and interpret send-once |
| 126 //! notifications as a signal that there will be no reply. Although not |
| 127 //! expected to be primarily useful for servers, this method is provided |
| 128 //! because send-once notifications are defined as a part of the |
| 129 //! `notify` subsystem. |
| 130 virtual kern_return_t DoMachNotifySendOnce( |
| 131 notify_port_t notify, |
| 132 const mach_msg_trailer_t* trailer) = 0; |
| 133 |
| 134 //! \brief Handles dead-name notifications sent by |
| 135 //! `mach_notify_dead_name()`. |
| 136 //! |
| 137 //! A dead-name notification is generated when a port with a dead-name |
| 138 //! notification request is destroyed and the right becomes a dead name. |
| 139 //! |
| 140 //! This behaves equivalently to a `do_mach_notify_dead_name()` function |
| 141 //! used with `notify_server()`. |
| 142 //! |
| 143 //! \param[in] notify The Mach port that the notification was sent to. |
| 144 //! \param[in] name The dead name. Although this is transferred as a |
| 145 //! `mach_port_name_t` and not a `mach_port_t`, the callee assumes an |
| 146 //! additional reference to this port when this method is called. See |
| 147 //! the note below. |
| 148 //! \param[in] trailer The trailer received with the notification message. |
| 149 //! |
| 150 //! \note When a dead-name notification is generated, the user reference |
| 151 //! count of the dead name is incremented. A send right with one |
| 152 //! reference that becomes a dead name will have one dead-name |
| 153 //! reference, and the dead-name notification will add another dead-name |
| 154 //! reference, for a total of 2. DoMachNotifyDeadName() implementations |
| 155 //! must take care to deallocate this extra reference. There is no \a |
| 156 //! destroy_request parameter to simplify this operation because |
| 157 //! dead-name notifications carry a port name only (\a name is of type |
| 158 //! `mach_port_name_t`) without transferring port rights, and are thus |
| 159 //! not complex Mach messages. |
| 160 virtual kern_return_t DoMachNotifyDeadName( |
| 161 notify_port_t notify, |
| 162 mach_port_name_t name, |
| 163 const mach_msg_trailer_t* trailer) = 0; |
| 164 |
| 165 protected: |
| 166 ~Interface() {} |
| 167 }; |
| 168 |
| 169 //! \brief Constructs an object of this class. |
| 170 //! |
| 171 //! \param[in] interface The interface to dispatch requests to. Weak. |
| 172 explicit NotifyServer(Interface* interface); |
| 173 |
| 174 // MachMessageServer::Interface: |
| 175 |
| 176 bool MachMessageServerFunction(const mach_msg_header_t* in_header, |
| 177 mach_msg_header_t* out_header, |
| 178 bool* destroy_complex_request) override; |
| 179 |
| 180 std::set<mach_msg_id_t> MachMessageServerRequestIDs() override; |
| 181 |
| 182 mach_msg_size_t MachMessageServerRequestSize() override; |
| 183 mach_msg_size_t MachMessageServerReplySize() override; |
| 184 |
| 185 private: |
| 186 Interface* interface_; // weak |
| 187 |
| 188 DISALLOW_COPY_AND_ASSIGN(NotifyServer); |
| 189 }; |
| 190 |
| 191 } // namespace crashpad |
| 192 |
| 193 #endif // CRASHPAD_UTIL_MACH_NOTIFY_SERVER_H_ |
OLD | NEW |