Index: util/mach/composite_mach_message_server.h |
diff --git a/util/mach/composite_mach_message_server.h b/util/mach/composite_mach_message_server.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6da957b7ffb4b236b36946a4eb9fb4e6bfc53edb |
--- /dev/null |
+++ b/util/mach/composite_mach_message_server.h |
@@ -0,0 +1,103 @@ |
+// Copyright 2014 The Crashpad Authors. All rights reserved. |
+// |
+// Licensed under the Apache License, Version 2.0 (the "License"); |
+// you may not use this file except in compliance with the License. |
+// You may obtain a copy of the License at |
+// |
+// http://www.apache.org/licenses/LICENSE-2.0 |
+// |
+// Unless required by applicable law or agreed to in writing, software |
+// distributed under the License is distributed on an "AS IS" BASIS, |
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+// See the License for the specific language governing permissions and |
+// limitations under the License. |
+ |
+#ifndef CRASHPAD_UTIL_MACH_COMPOSITE_MACH_MESSAGE_SERVER_H_ |
+#define CRASHPAD_UTIL_MACH_COMPOSITE_MACH_MESSAGE_SERVER_H_ |
+ |
+#include <mach/mach.h> |
+ |
+#include <map> |
+#include <set> |
+ |
+#include "base/basictypes.h" |
+#include "util/mach/mach_message_server.h" |
+ |
+namespace crashpad { |
+ |
+//! \brief Adapts multiple MachMessageServer::Interface implementations for |
+//! simultaneous use in a single MachMessageServer::Run() call. |
+//! |
+//! This class implements a MachMessageServer::Interface that contains other |
+//! other MachMessageServer::Interface objects. |
+//! |
+//! In some situations, it may be desirable for a Mach message server to handle |
+//! messages from distinct MIG subsystems with distinct |
+//! MachMessageServer::Interface implementations. This may happen if a single |
+//! receive right is shared for multiple subsystems, or if distinct receive |
+//! rights are combined in a Mach port set. In these cases, this class performs |
+//! a first-level demultiplexing to forward request messages to the proper |
+//! subsystem-level demultiplexers. |
+class CompositeMachMessageServer : public MachMessageServer::Interface { |
+ public: |
+ CompositeMachMessageServer(); |
+ ~CompositeMachMessageServer(); |
+ |
+ //! \brief Adds a handler that messages can be dispatched to based on request |
+ //! message ID. |
+ //! |
+ //! \param[in] handler A MachMessageServer handler. Ownership of this object |
+ //! is not taken. Cycles must not be created between objects. It is |
+ //! invalid to add an object as its own handler. |
+ //! |
+ //! If \a handler claims to support any request ID that this object is already |
+ //! able to handle, execution will be terminated. |
+ void AddHandler(MachMessageServer::Interface* handler); |
+ |
+ // MachMessageServer::Interface: |
+ |
+ //! \copydoc MachMessageServer::Interface::MachMessageServerFunction() |
+ //! |
+ //! This implementation forwards the message to an appropriate handler added |
+ //! by AddHandler() on the basis of the \a in request message’s message ID. |
+ //! If no appropriate handler exists, the \a out reply message is treated as |
+ //! a `mig_reply_error_t`, its return code is set to `MIG_BAD_ID`, and `false` |
+ //! is returned. |
+ bool MachMessageServerFunction(const mach_msg_header_t* in, |
+ mach_msg_header_t* out, |
+ bool* destroy_complex_request) override; |
+ |
+ //! \copydoc MachMessageServer::Interface::MachMessageServerRequestIDs() |
+ //! |
+ //! This implementation returns the set of all request message Mach message |
+ //! IDs of all handlers added by AddHandler(). |
+ std::set<mach_msg_id_t> MachMessageServerRequestIDs() override; |
+ |
+ //! \copydoc MachMessageServer::Interface::MachMessageServerRequestSize() |
+ //! |
+ //! This implementation returns the maximum request message size of all |
+ //! handlers added by AddHandler(). If no handlers are present, returns the |
+ //! size of `mach_msg_header_t`, the minimum size of a MIG request message |
+ //! that can be received for demultiplexing purposes. |
+ mach_msg_size_t MachMessageServerRequestSize() override; |
+ |
+ //! \copydoc MachMessageServer::Interface::MachMessageServerReplySize() |
+ //! |
+ //! This implementation returns the maximum reply message size of all handlers |
+ //! added by AddHandler(). If no handlers are present, returns the size of |
+ //! `mig_reply_error_t`, the minimum size of a MIG reply message. |
+ mach_msg_size_t MachMessageServerReplySize() override; |
+ |
+ private: |
+ using HandlerMap = std::map<mach_msg_id_t, MachMessageServer::Interface*>; |
+ |
+ HandlerMap handler_map_; // weak |
+ mach_msg_size_t request_size_; |
+ mach_msg_size_t reply_size_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CompositeMachMessageServer); |
+}; |
+ |
+} // namespace crashpad |
+ |
+#endif // CRASHPAD_UTIL_MACH_COMPOSITE_MACH_MESSAGE_SERVER_H_ |