Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: util/mach/mach_message_server.cc

Issue 756803002: Add a ReceiveLarge parameter to MachMessageServer::Run() (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/mach/mach_message_server.h ('k') | util/mach/mach_message_server_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "util/mach/mach_message_server.h" 15 #include "util/mach/mach_message_server.h"
16 16
17 #include <limits> 17 #include <limits>
18 18
19 #include "base/mac/mach_logging.h"
19 #include "base/mac/scoped_mach_vm.h" 20 #include "base/mac/scoped_mach_vm.h"
20 #include "util/misc/clock.h" 21 #include "util/misc/clock.h"
21 22
22 namespace crashpad { 23 namespace crashpad {
23 24
24 namespace { 25 namespace {
25 26
26 const int kNanosecondsPerMillisecond = 1E6; 27 const int kNanosecondsPerMillisecond = 1E6;
27 28
28 // TimerRunning determines whether |deadline| has passed. If |deadline| is in 29 // TimerRunning determines whether |deadline| has passed. If |deadline| is in
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // mach_msg_server(), the |nonblocking| parameter to control blocking directly, 76 // mach_msg_server(), the |nonblocking| parameter to control blocking directly,
76 // and the |timeout_ms| parameter allowing this function to not block 77 // and the |timeout_ms| parameter allowing this function to not block
77 // indefinitely. 78 // indefinitely.
78 // 79 //
79 // static 80 // static
80 mach_msg_return_t MachMessageServer::Run(Interface* interface, 81 mach_msg_return_t MachMessageServer::Run(Interface* interface,
81 mach_port_t receive_port, 82 mach_port_t receive_port,
82 mach_msg_options_t options, 83 mach_msg_options_t options,
83 Persistent persistent, 84 Persistent persistent,
84 Nonblocking nonblocking, 85 Nonblocking nonblocking,
86 ReceiveLarge receive_large,
85 mach_msg_timeout_t timeout_ms) { 87 mach_msg_timeout_t timeout_ms) {
86 options &= ~(MACH_RCV_MSG | MACH_SEND_MSG); 88 options &= ~(MACH_RCV_MSG | MACH_SEND_MSG);
87 89
88 mach_msg_options_t timeout_options = MACH_RCV_TIMEOUT | MACH_SEND_TIMEOUT | 90 mach_msg_options_t timeout_options = MACH_RCV_TIMEOUT | MACH_SEND_TIMEOUT |
89 MACH_RCV_INTERRUPT | MACH_SEND_INTERRUPT; 91 MACH_RCV_INTERRUPT | MACH_SEND_INTERRUPT;
90 92
91 uint64_t deadline; 93 uint64_t deadline;
92 if (nonblocking == kNonblocking) { 94 if (nonblocking == kNonblocking) {
93 options |= timeout_options; 95 options |= timeout_options;
94 deadline = 0; 96 deadline = 0;
95 } else if (timeout_ms != MACH_MSG_TIMEOUT_NONE) { 97 } else if (timeout_ms != MACH_MSG_TIMEOUT_NONE) {
96 options |= timeout_options; 98 options |= timeout_options;
97 deadline = ClockMonotonicNanoseconds() + 99 deadline = ClockMonotonicNanoseconds() +
98 implicit_cast<uint64_t>(timeout_ms) * kNanosecondsPerMillisecond; 100 implicit_cast<uint64_t>(timeout_ms) * kNanosecondsPerMillisecond;
99 } else { 101 } else {
100 options &= ~timeout_options; 102 options &= ~timeout_options;
101 deadline = 0; 103 deadline = 0;
102 } 104 }
103 105
106 if (receive_large == kReceiveLargeResize) {
107 options |= MACH_RCV_LARGE;
108 } else {
109 options &= ~MACH_RCV_LARGE;
110 }
111
104 mach_msg_size_t trailer_alloc = REQUESTED_TRAILER_SIZE(options); 112 mach_msg_size_t trailer_alloc = REQUESTED_TRAILER_SIZE(options);
105 mach_msg_size_t max_request_size = interface->MachMessageServerRequestSize(); 113 mach_msg_size_t max_request_size = interface->MachMessageServerRequestSize();
106 mach_msg_size_t request_alloc = round_page(max_request_size + trailer_alloc); 114 mach_msg_size_t request_alloc = round_page(max_request_size + trailer_alloc);
107 mach_msg_size_t request_size = (options & MACH_RCV_LARGE) 115 mach_msg_size_t request_size = (receive_large == kReceiveLargeResize)
108 ? request_alloc 116 ? request_alloc
109 : max_request_size + trailer_alloc; 117 : max_request_size + trailer_alloc;
110 118
111 mach_msg_size_t max_reply_size = interface->MachMessageServerReplySize(); 119 mach_msg_size_t max_reply_size = interface->MachMessageServerReplySize();
112 mach_msg_size_t reply_alloc = round_page( 120 mach_msg_size_t reply_alloc = round_page(
113 (options & MACH_SEND_TRAILER) ? (max_reply_size + MAX_TRAILER_SIZE) 121 (options & MACH_SEND_TRAILER) ? (max_reply_size + MAX_TRAILER_SIZE)
114 : max_reply_size); 122 : max_reply_size);
115 123
116 kern_return_t kr; 124 kern_return_t kr;
117 125
(...skipping 10 matching lines...) Expand all
128 &request_addr, 136 &request_addr,
129 this_request_alloc, 137 this_request_alloc,
130 VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_MACH_MSG)); 138 VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_MACH_MSG));
131 if (kr != KERN_SUCCESS) { 139 if (kr != KERN_SUCCESS) {
132 return kr; 140 return kr;
133 } 141 }
134 base::mac::ScopedMachVM trial_request_scoper(request_addr, 142 base::mac::ScopedMachVM trial_request_scoper(request_addr,
135 this_request_alloc); 143 this_request_alloc);
136 request_header = reinterpret_cast<mach_msg_header_t*>(request_addr); 144 request_header = reinterpret_cast<mach_msg_header_t*>(request_addr);
137 145
146 bool run_mach_msg_receive = false;
138 do { 147 do {
139 // If |options| contains MACH_RCV_INTERRUPT, retry mach_msg() in a loop 148 // If |options| contains MACH_RCV_INTERRUPT, retry mach_msg() in a loop
140 // when it returns MACH_RCV_INTERRUPTED to recompute |remaining_ms| 149 // when it returns MACH_RCV_INTERRUPTED to recompute |remaining_ms|
141 // rather than allowing mach_msg() to retry using the original timeout 150 // rather than allowing mach_msg() to retry using the original timeout
142 // value. See 10.9.4 xnu-2422.110.17/libsyscall/mach/mach_msg.c 151 // value. See 10.9.4 xnu-2422.110.17/libsyscall/mach/mach_msg.c
143 // mach_msg(). 152 // mach_msg().
144 mach_msg_timeout_t remaining_ms; 153 mach_msg_timeout_t remaining_ms;
145 if (!TimerRunning(deadline, &remaining_ms)) { 154 if (!TimerRunning(deadline, &remaining_ms)) {
146 return MACH_RCV_TIMED_OUT; 155 return MACH_RCV_TIMED_OUT;
147 } 156 }
148 157
149 kr = mach_msg(request_header, 158 kr = mach_msg(request_header,
150 options | MACH_RCV_MSG, 159 options | MACH_RCV_MSG,
151 0, 160 0,
152 this_request_size, 161 this_request_size,
153 receive_port, 162 receive_port,
154 remaining_ms, 163 remaining_ms,
155 MACH_PORT_NULL); 164 MACH_PORT_NULL);
156 } while (kr == MACH_RCV_INTERRUPTED); 165
166 if (kr == MACH_RCV_TOO_LARGE && receive_large == kReceiveLargeIgnore) {
167 MACH_LOG(WARNING, kr) << "mach_msg: ignoring large message";
168 run_mach_msg_receive = true;
169 } else if (kr == MACH_RCV_INTERRUPTED) {
170 run_mach_msg_receive = true;
171 }
172 } while (run_mach_msg_receive);
157 173
158 if (kr == MACH_MSG_SUCCESS) { 174 if (kr == MACH_MSG_SUCCESS) {
159 request_scoper.swap(trial_request_scoper); 175 request_scoper.swap(trial_request_scoper);
160 } else if (kr == MACH_RCV_TOO_LARGE && options & MACH_RCV_LARGE) { 176 } else if (kr == MACH_RCV_TOO_LARGE &&
177 receive_large == kReceiveLargeResize) {
161 this_request_size = 178 this_request_size =
162 round_page(request_header->msgh_size + trailer_alloc); 179 round_page(request_header->msgh_size + trailer_alloc);
163 this_request_alloc = this_request_size; 180 this_request_alloc = this_request_size;
164 } else { 181 } else {
165 return kr; 182 return kr;
166 } 183 }
167 } 184 }
168 185
169 vm_address_t reply_addr; 186 vm_address_t reply_addr;
170 kr = vm_allocate(mach_task_self(), 187 kr = vm_allocate(mach_task_self(),
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 // persistent mode, and just return success when not in persistent mode. 274 // persistent mode, and just return success when not in persistent mode.
258 return (persistent == kPersistent) ? MACH_RCV_TIMED_OUT : kr; 275 return (persistent == kPersistent) ? MACH_RCV_TIMED_OUT : kr;
259 } 276 }
260 } 277 }
261 } while (persistent == kPersistent); 278 } while (persistent == kPersistent);
262 279
263 return kr; 280 return kr;
264 } 281 }
265 282
266 } // namespace crashpad 283 } // namespace crashpad
OLDNEW
« no previous file with comments | « util/mach/mach_message_server.h ('k') | util/mach/mach_message_server_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698