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_COMPOSITE_MACH_MESSAGE_SERVER_H_ |
| 16 #define CRASHPAD_UTIL_MACH_COMPOSITE_MACH_MESSAGE_SERVER_H_ |
| 17 |
| 18 #include <mach/mach.h> |
| 19 |
| 20 #include <map> |
| 21 #include <set> |
| 22 |
| 23 #include "base/basictypes.h" |
| 24 #include "util/mach/mach_message_server.h" |
| 25 |
| 26 namespace crashpad { |
| 27 |
| 28 //! \brief Adapts multiple MachMessageServer::Interface implementations for |
| 29 //! simultaneous use in a single MachMessageServer::Run() call. |
| 30 //! |
| 31 //! This class implements a MachMessageServer::Interface that contains other |
| 32 //! other MachMessageServer::Interface objects. |
| 33 //! |
| 34 //! In some situations, it may be desirable for a Mach message server to handle |
| 35 //! messages from distinct MIG subsystems with distinct |
| 36 //! MachMessageServer::Interface implementations. This may happen if a single |
| 37 //! receive right is shared for multiple subsystems, or if distinct receive |
| 38 //! rights are combined in a Mach port set. In these cases, this class performs |
| 39 //! a first-level demultiplexing to forward request messages to the proper |
| 40 //! subsystem-level demultiplexers. |
| 41 class CompositeMachMessageServer : public MachMessageServer::Interface { |
| 42 public: |
| 43 CompositeMachMessageServer(); |
| 44 ~CompositeMachMessageServer(); |
| 45 |
| 46 //! \brief Adds a handler that messages can be dispatched to based on request |
| 47 //! message ID. |
| 48 //! |
| 49 //! \param[in] handler A MachMessageServer handler. Ownership of this object |
| 50 //! is not taken. Cycles must not be created between objects. It is |
| 51 //! invalid to add an object as its own handler. |
| 52 //! |
| 53 //! If \a handler claims to support any request ID that this object is already |
| 54 //! able to handle, execution will be terminated. |
| 55 void AddHandler(MachMessageServer::Interface* handler); |
| 56 |
| 57 // MachMessageServer::Interface: |
| 58 |
| 59 //! \copydoc MachMessageServer::Interface::MachMessageServerFunction() |
| 60 //! |
| 61 //! This implementation forwards the message to an appropriate handler added |
| 62 //! by AddHandler() on the basis of the \a in request message’s message ID. |
| 63 //! If no appropriate handler exists, the \a out reply message is treated as |
| 64 //! a `mig_reply_error_t`, its return code is set to `MIG_BAD_ID`, and `false` |
| 65 //! is returned. |
| 66 bool MachMessageServerFunction(const mach_msg_header_t* in, |
| 67 mach_msg_header_t* out, |
| 68 bool* destroy_complex_request) override; |
| 69 |
| 70 //! \copydoc MachMessageServer::Interface::MachMessageServerRequestIDs() |
| 71 //! |
| 72 //! This implementation returns the set of all request message Mach message |
| 73 //! IDs of all handlers added by AddHandler(). |
| 74 std::set<mach_msg_id_t> MachMessageServerRequestIDs() override; |
| 75 |
| 76 //! \copydoc MachMessageServer::Interface::MachMessageServerRequestSize() |
| 77 //! |
| 78 //! This implementation returns the maximum request message size of all |
| 79 //! handlers added by AddHandler(). If no handlers are present, returns the |
| 80 //! size of `mach_msg_header_t`, the minimum size of a MIG request message |
| 81 //! that can be received for demultiplexing purposes. |
| 82 mach_msg_size_t MachMessageServerRequestSize() override; |
| 83 |
| 84 //! \copydoc MachMessageServer::Interface::MachMessageServerReplySize() |
| 85 //! |
| 86 //! This implementation returns the maximum reply message size of all handlers |
| 87 //! added by AddHandler(). If no handlers are present, returns the size of |
| 88 //! `mig_reply_error_t`, the minimum size of a MIG reply message. |
| 89 mach_msg_size_t MachMessageServerReplySize() override; |
| 90 |
| 91 private: |
| 92 using HandlerMap = std::map<mach_msg_id_t, MachMessageServer::Interface*>; |
| 93 |
| 94 HandlerMap handler_map_; // weak |
| 95 mach_msg_size_t request_size_; |
| 96 mach_msg_size_t reply_size_; |
| 97 |
| 98 DISALLOW_COPY_AND_ASSIGN(CompositeMachMessageServer); |
| 99 }; |
| 100 |
| 101 } // namespace crashpad |
| 102 |
| 103 #endif // CRASHPAD_UTIL_MACH_COMPOSITE_MACH_MESSAGE_SERVER_H_ |
OLD | NEW |