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 |