| OLD | NEW |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 UniversalMachExcServer::Interface* exception_interface) | 34 UniversalMachExcServer::Interface* exception_interface) |
| 35 : UniversalMachExcServer::Interface(), | 35 : UniversalMachExcServer::Interface(), |
| 36 NotifyServer::Interface(), | 36 NotifyServer::Interface(), |
| 37 mach_exc_server_(this), | 37 mach_exc_server_(this), |
| 38 notify_server_(this), | 38 notify_server_(this), |
| 39 composite_mach_message_server_(), | 39 composite_mach_message_server_(), |
| 40 exception_interface_(exception_interface), | 40 exception_interface_(exception_interface), |
| 41 exception_port_(exception_port), | 41 exception_port_(exception_port), |
| 42 notify_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)), | 42 notify_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)), |
| 43 running_(true) { | 43 running_(true) { |
| 44 CHECK_NE(notify_port_, kMachPortNull); | 44 CHECK(notify_port_.is_valid()); |
| 45 | 45 |
| 46 composite_mach_message_server_.AddHandler(&mach_exc_server_); | 46 composite_mach_message_server_.AddHandler(&mach_exc_server_); |
| 47 composite_mach_message_server_.AddHandler(¬ify_server_); | 47 composite_mach_message_server_.AddHandler(¬ify_server_); |
| 48 } | 48 } |
| 49 | 49 |
| 50 ~ExceptionHandlerServerRun() { | 50 ~ExceptionHandlerServerRun() { |
| 51 } | 51 } |
| 52 | 52 |
| 53 void Run() { | 53 void Run() { |
| 54 DCHECK(running_); | 54 DCHECK(running_); |
| 55 | 55 |
| 56 // Request that a no-senders notification for exception_port_ be sent to | 56 // Request that a no-senders notification for exception_port_ be sent to |
| 57 // notify_port_. | 57 // notify_port_. |
| 58 mach_port_t previous; | 58 mach_port_t previous; |
| 59 kern_return_t kr = | 59 kern_return_t kr = |
| 60 mach_port_request_notification(mach_task_self(), | 60 mach_port_request_notification(mach_task_self(), |
| 61 exception_port_, | 61 exception_port_, |
| 62 MACH_NOTIFY_NO_SENDERS, | 62 MACH_NOTIFY_NO_SENDERS, |
| 63 0, | 63 0, |
| 64 notify_port_, | 64 notify_port_.get(), |
| 65 MACH_MSG_TYPE_MAKE_SEND_ONCE, | 65 MACH_MSG_TYPE_MAKE_SEND_ONCE, |
| 66 &previous); | 66 &previous); |
| 67 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_request_notification"; | 67 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_request_notification"; |
| 68 | 68 |
| 69 if (previous != MACH_PORT_NULL) { | 69 if (previous != MACH_PORT_NULL) { |
| 70 kr = mach_port_deallocate(mach_task_self(), previous); | 70 kr = mach_port_deallocate(mach_task_self(), previous); |
| 71 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_deallocate"; | 71 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_deallocate"; |
| 72 } | 72 } |
| 73 | 73 |
| 74 // A single CompositeMachMessageServer will dispatch both exception messages | 74 // A single CompositeMachMessageServer will dispatch both exception messages |
| 75 // and the no-senders notification. Put both receive rights into a port set. | 75 // and the no-senders notification. Put both receive rights into a port set. |
| 76 // | 76 // |
| 77 // A single receive right can’t be used because the notification request | 77 // A single receive right can’t be used because the notification request |
| 78 // requires a send-once right, which would prevent the no-senders condition | 78 // requires a send-once right, which would prevent the no-senders condition |
| 79 // from ever existing. Using distinct receive rights also allows the handler | 79 // from ever existing. Using distinct receive rights also allows the handler |
| 80 // methods to ensure that the messages they process were sent by a holder of | 80 // methods to ensure that the messages they process were sent by a holder of |
| 81 // the proper send right. | 81 // the proper send right. |
| 82 base::mac::ScopedMachPortSet server_port_set( | 82 base::mac::ScopedMachPortSet server_port_set( |
| 83 NewMachPort(MACH_PORT_RIGHT_PORT_SET)); | 83 NewMachPort(MACH_PORT_RIGHT_PORT_SET)); |
| 84 | 84 |
| 85 kr = mach_port_insert_member( | 85 kr = mach_port_insert_member( |
| 86 mach_task_self(), exception_port_, server_port_set); | 86 mach_task_self(), exception_port_, server_port_set.get()); |
| 87 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member"; | 87 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member"; |
| 88 | 88 |
| 89 kr = mach_port_insert_member( | 89 kr = mach_port_insert_member( |
| 90 mach_task_self(), notify_port_, server_port_set); | 90 mach_task_self(), notify_port_.get(), server_port_set.get()); |
| 91 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member"; | 91 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member"; |
| 92 | 92 |
| 93 // Run the server in kOneShot mode so that running_ can be reevaluated after | 93 // Run the server in kOneShot mode so that running_ can be reevaluated after |
| 94 // each message. Receipt of a valid no-senders notification causes it to be | 94 // each message. Receipt of a valid no-senders notification causes it to be |
| 95 // set to false. | 95 // set to false. |
| 96 while (running_) { | 96 while (running_) { |
| 97 // This will result in a call to CatchMachException() or | 97 // This will result in a call to CatchMachException() or |
| 98 // DoMachNotifyNoSenders() as appropriate. | 98 // DoMachNotifyNoSenders() as appropriate. |
| 99 mach_msg_return_t mr = | 99 mach_msg_return_t mr = |
| 100 MachMessageServer::Run(&composite_mach_message_server_, | 100 MachMessageServer::Run(&composite_mach_message_server_, |
| 101 server_port_set, | 101 server_port_set.get(), |
| 102 kMachMessageReceiveAuditTrailer, | 102 kMachMessageReceiveAuditTrailer, |
| 103 MachMessageServer::kOneShot, | 103 MachMessageServer::kOneShot, |
| 104 MachMessageServer::kReceiveLargeIgnore, | 104 MachMessageServer::kReceiveLargeIgnore, |
| 105 kMachMessageTimeoutWaitIndefinitely); | 105 kMachMessageTimeoutWaitIndefinitely); |
| 106 MACH_CHECK(mr == MACH_MSG_SUCCESS, mr) << "MachMessageServer::Run"; | 106 MACH_CHECK(mr == MACH_MSG_SUCCESS, mr) << "MachMessageServer::Run"; |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 | 109 |
| 110 // UniversalMachExcServer::Interface: | 110 // UniversalMachExcServer::Interface: |
| 111 | 111 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 base::mac::ScopedMachReceiveRight notify_port_; | 214 base::mac::ScopedMachReceiveRight notify_port_; |
| 215 bool running_; | 215 bool running_; |
| 216 | 216 |
| 217 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServerRun); | 217 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServerRun); |
| 218 }; | 218 }; |
| 219 | 219 |
| 220 } // namespace | 220 } // namespace |
| 221 | 221 |
| 222 ExceptionHandlerServer::ExceptionHandlerServer() | 222 ExceptionHandlerServer::ExceptionHandlerServer() |
| 223 : receive_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)) { | 223 : receive_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)) { |
| 224 CHECK_NE(receive_port_, kMachPortNull); | 224 CHECK(receive_port_.is_valid()); |
| 225 } | 225 } |
| 226 | 226 |
| 227 ExceptionHandlerServer::~ExceptionHandlerServer() { | 227 ExceptionHandlerServer::~ExceptionHandlerServer() { |
| 228 } | 228 } |
| 229 | 229 |
| 230 void ExceptionHandlerServer::Run( | 230 void ExceptionHandlerServer::Run( |
| 231 UniversalMachExcServer::Interface* exception_interface) { | 231 UniversalMachExcServer::Interface* exception_interface) { |
| 232 ExceptionHandlerServerRun run(receive_port_, exception_interface); | 232 ExceptionHandlerServerRun run(receive_port_.get(), exception_interface); |
| 233 run.Run(); | 233 run.Run(); |
| 234 } | 234 } |
| 235 | 235 |
| 236 } // namespace crashpad | 236 } // namespace crashpad |
| OLD | NEW |