| Index: util/mach/composite_mach_message_server.cc
|
| diff --git a/util/mach/composite_mach_message_server.cc b/util/mach/composite_mach_message_server.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..abbe5bcf38858cc27934520b0140782701f902f6
|
| --- /dev/null
|
| +++ b/util/mach/composite_mach_message_server.cc
|
| @@ -0,0 +1,86 @@
|
| +// 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.
|
| +
|
| +#include "util/mach/composite_mach_message_server.h"
|
| +
|
| +#include <algorithm>
|
| +#include <utility>
|
| +
|
| +#include "base/logging.h"
|
| +#include "util/mach/mach_message.h"
|
| +
|
| +namespace crashpad {
|
| +
|
| +CompositeMachMessageServer::CompositeMachMessageServer()
|
| + : MachMessageServer::Interface(),
|
| + handler_map_(),
|
| + request_size_(sizeof(mach_msg_header_t)),
|
| + reply_size_(sizeof(mig_reply_error_t)) {
|
| +}
|
| +
|
| +CompositeMachMessageServer::~CompositeMachMessageServer() {
|
| +}
|
| +
|
| +void CompositeMachMessageServer::AddHandler(
|
| + MachMessageServer::Interface* handler) {
|
| + // Other cycles would be invalid as well, but they aren’t currently checked.
|
| + DCHECK_NE(handler, this);
|
| +
|
| + std::set<mach_msg_id_t> request_ids = handler->MachMessageServerRequestIDs();
|
| + for (mach_msg_id_t request_id : request_ids) {
|
| + std::pair<HandlerMap::const_iterator, bool> result =
|
| + handler_map_.insert(std::make_pair(request_id, handler));
|
| + CHECK(result.second) << "duplicate request ID " << request_id;
|
| + }
|
| +
|
| + request_size_ =
|
| + std::max(request_size_, handler->MachMessageServerRequestSize());
|
| + reply_size_ = std::max(reply_size_, handler->MachMessageServerReplySize());
|
| +}
|
| +
|
| +bool CompositeMachMessageServer::MachMessageServerFunction(
|
| + const mach_msg_header_t* in,
|
| + mach_msg_header_t* out,
|
| + bool* destroy_complex_request) {
|
| + HandlerMap::const_iterator iterator = handler_map_.find(in->msgh_id);
|
| + if (iterator == handler_map_.end()) {
|
| + // Do what MIG-generated server routines do when they can’t dispatch a
|
| + // message.
|
| + PrepareMIGReplyFromRequest(in, out);
|
| + SetMIGReplyError(out, MIG_BAD_ID);
|
| + return false;
|
| + }
|
| +
|
| + MachMessageServer::Interface* handler = iterator->second;
|
| + return handler->MachMessageServerFunction(in, out, destroy_complex_request);
|
| +}
|
| +
|
| +std::set<mach_msg_id_t>
|
| +CompositeMachMessageServer::MachMessageServerRequestIDs() {
|
| + std::set<mach_msg_id_t> request_ids;
|
| + for (const auto& entry : handler_map_) {
|
| + request_ids.insert(entry.first);
|
| + }
|
| + return request_ids;
|
| +}
|
| +
|
| +mach_msg_size_t CompositeMachMessageServer::MachMessageServerRequestSize() {
|
| + return request_size_;
|
| +}
|
| +
|
| +mach_msg_size_t CompositeMachMessageServer::MachMessageServerReplySize() {
|
| + return reply_size_;
|
| +}
|
| +
|
| +} // namespace crashpad
|
|
|