OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/tcp_client_socket_pool.h" | 5 #include "net/base/tcp_client_socket_pool.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "net/base/client_socket.h" | 9 #include "net/base/client_socket.h" |
10 #include "net/base/client_socket_factory.h" | 10 #include "net/base/client_socket_factory.h" |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 ScopedHostMapper scoped_host_mapper_; | 225 ScopedHostMapper scoped_host_mapper_; |
226 HostResolver host_resolver_; | 226 HostResolver host_resolver_; |
227 MockClientSocketFactory client_socket_factory_; | 227 MockClientSocketFactory client_socket_factory_; |
228 scoped_refptr<ClientSocketPool> pool_; | 228 scoped_refptr<ClientSocketPool> pool_; |
229 std::vector<TestSocketRequest*> request_order_; | 229 std::vector<TestSocketRequest*> request_order_; |
230 }; | 230 }; |
231 | 231 |
232 TEST_F(TCPClientSocketPoolTest, Basic) { | 232 TEST_F(TCPClientSocketPoolTest, Basic) { |
233 TestCompletionCallback callback; | 233 TestCompletionCallback callback; |
234 ClientSocketHandle handle(pool_.get()); | 234 ClientSocketHandle handle(pool_.get()); |
235 int rv = handle.Init("a", "www.google.com", 80, 0, &callback); | 235 HostResolver::RequestInfo info("www.google.com", 80); |
| 236 int rv = handle.Init("a", info, 0, &callback); |
236 EXPECT_EQ(ERR_IO_PENDING, rv); | 237 EXPECT_EQ(ERR_IO_PENDING, rv); |
237 EXPECT_FALSE(handle.is_initialized()); | 238 EXPECT_FALSE(handle.is_initialized()); |
238 EXPECT_FALSE(handle.socket()); | 239 EXPECT_FALSE(handle.socket()); |
239 | 240 |
240 EXPECT_EQ(OK, callback.WaitForResult()); | 241 EXPECT_EQ(OK, callback.WaitForResult()); |
241 EXPECT_TRUE(handle.is_initialized()); | 242 EXPECT_TRUE(handle.is_initialized()); |
242 EXPECT_TRUE(handle.socket()); | 243 EXPECT_TRUE(handle.socket()); |
243 | 244 |
244 handle.Reset(); | 245 handle.Reset(); |
245 | 246 |
246 // The handle's Reset method may have posted a task. | 247 // The handle's Reset method may have posted a task. |
247 MessageLoop::current()->RunAllPending(); | 248 MessageLoop::current()->RunAllPending(); |
248 } | 249 } |
249 | 250 |
250 TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) { | 251 TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) { |
251 RuleBasedHostMapper* host_mapper = new RuleBasedHostMapper; | 252 RuleBasedHostMapper* host_mapper = new RuleBasedHostMapper; |
252 host_mapper->AddSimulatedFailure("unresolvable.host.name"); | 253 host_mapper->AddSimulatedFailure("unresolvable.host.name"); |
253 ScopedHostMapper scoped_host_mapper(host_mapper); | 254 ScopedHostMapper scoped_host_mapper(host_mapper); |
254 TestSocketRequest req(pool_.get(), &request_order_); | 255 TestSocketRequest req(pool_.get(), &request_order_); |
255 EXPECT_EQ(ERR_IO_PENDING, | 256 HostResolver::RequestInfo info("unresolvable.host.name", 80); |
256 req.handle.Init("a", "unresolvable.host.name", 80, 5, &req)); | 257 EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req)); |
257 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult()); | 258 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult()); |
258 } | 259 } |
259 | 260 |
260 TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) { | 261 TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) { |
261 client_socket_factory_.set_client_socket_type( | 262 client_socket_factory_.set_client_socket_type( |
262 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET); | 263 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET); |
263 TestSocketRequest req(pool_.get(), &request_order_); | 264 TestSocketRequest req(pool_.get(), &request_order_); |
| 265 HostResolver::RequestInfo info("unresolvable.host.name", 80); |
264 EXPECT_EQ(ERR_IO_PENDING, | 266 EXPECT_EQ(ERR_IO_PENDING, |
265 req.handle.Init("a", "unresolvable.host.name", 80, 5, &req)); | 267 req.handle.Init("a", info, 5, &req)); |
266 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); | 268 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); |
267 } | 269 } |
268 | 270 |
269 TEST_F(TCPClientSocketPoolTest, PendingRequests) { | 271 TEST_F(TCPClientSocketPoolTest, PendingRequests) { |
270 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; | 272 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; |
271 | 273 |
272 for (size_t i = 0; i < arraysize(reqs); ++i) | 274 for (size_t i = 0; i < arraysize(reqs); ++i) |
273 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); | 275 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); |
274 | 276 |
275 // Create connections or queue up requests. | 277 // Create connections or queue up requests. |
276 | 278 |
277 // First request finishes asynchronously. | 279 // First request finishes asynchronously. |
278 int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get()); | 280 HostResolver::RequestInfo info("www.google.com", 80); |
| 281 int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get()); |
279 EXPECT_EQ(ERR_IO_PENDING, rv); | 282 EXPECT_EQ(ERR_IO_PENDING, rv); |
280 EXPECT_EQ(OK, reqs[0]->WaitForResult()); | 283 EXPECT_EQ(OK, reqs[0]->WaitForResult()); |
281 | 284 |
282 // Rest of them finish synchronously, since they're in the HostCache. | 285 // Rest of them finish synchronously, since they're in the HostCache. |
283 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { | 286 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { |
284 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get()); | 287 rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get()); |
285 EXPECT_EQ(OK, rv); | 288 EXPECT_EQ(OK, rv); |
286 request_order_.push_back(reqs[i].get()); | 289 request_order_.push_back(reqs[i].get()); |
287 } | 290 } |
288 | 291 |
289 // The rest are pending since we've used all active sockets. | 292 // The rest are pending since we've used all active sockets. |
290 for (int i = 0; i < kNumPendingRequests; ++i) { | 293 for (int i = 0; i < kNumPendingRequests; ++i) { |
291 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( | 294 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( |
292 "a", "www.google.com", 80, kPriorities[i], | 295 "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()); |
293 reqs[kMaxSocketsPerGroup + i].get()); | |
294 EXPECT_EQ(ERR_IO_PENDING, rv); | 296 EXPECT_EQ(ERR_IO_PENDING, rv); |
295 } | 297 } |
296 | 298 |
297 // Release any connections until we have no connections. | 299 // Release any connections until we have no connections. |
298 bool released_one; | 300 bool released_one; |
299 do { | 301 do { |
300 released_one = false; | 302 released_one = false; |
301 for (size_t i = 0; i < arraysize(reqs); ++i) { | 303 for (size_t i = 0; i < arraysize(reqs); ++i) { |
302 if (reqs[i]->handle.is_initialized()) { | 304 if (reqs[i]->handle.is_initialized()) { |
303 reqs[i]->handle.Reset(); | 305 reqs[i]->handle.Reset(); |
(...skipping 25 matching lines...) Expand all Loading... |
329 } | 331 } |
330 | 332 |
331 TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) { | 333 TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) { |
332 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; | 334 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; |
333 for (size_t i = 0; i < arraysize(reqs); ++i) | 335 for (size_t i = 0; i < arraysize(reqs); ++i) |
334 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); | 336 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); |
335 | 337 |
336 // Create connections or queue up requests. | 338 // Create connections or queue up requests. |
337 | 339 |
338 // First request finishes asynchronously. | 340 // First request finishes asynchronously. |
339 int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get()); | 341 HostResolver::RequestInfo info("www.google.com", 80); |
| 342 int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get()); |
340 EXPECT_EQ(ERR_IO_PENDING, rv); | 343 EXPECT_EQ(ERR_IO_PENDING, rv); |
341 EXPECT_EQ(OK, reqs[0]->WaitForResult()); | 344 EXPECT_EQ(OK, reqs[0]->WaitForResult()); |
342 | 345 |
343 // Rest of them finish synchronously, since they're in the HostCache. | 346 // Rest of them finish synchronously, since they're in the HostCache. |
344 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { | 347 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { |
345 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get()); | 348 rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get()); |
346 EXPECT_EQ(OK, rv); | 349 EXPECT_EQ(OK, rv); |
347 request_order_.push_back(reqs[i].get()); | 350 request_order_.push_back(reqs[i].get()); |
348 } | 351 } |
349 | 352 |
350 // The rest are pending since we've used all active sockets. | 353 // The rest are pending since we've used all active sockets. |
351 for (int i = 0; i < kNumPendingRequests; ++i) { | 354 for (int i = 0; i < kNumPendingRequests; ++i) { |
352 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init( | 355 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init( |
353 "a", "www.google.com", 80, 0, reqs[kMaxSocketsPerGroup + i].get())); | 356 "a", info, 0, reqs[kMaxSocketsPerGroup + i].get())); |
354 } | 357 } |
355 | 358 |
356 // Release any connections until we have no connections. | 359 // Release any connections until we have no connections. |
357 bool released_one; | 360 bool released_one; |
358 do { | 361 do { |
359 released_one = false; | 362 released_one = false; |
360 for (size_t i = 0; i < arraysize(reqs); ++i) { | 363 for (size_t i = 0; i < arraysize(reqs); ++i) { |
361 if (reqs[i]->handle.is_initialized()) { | 364 if (reqs[i]->handle.is_initialized()) { |
362 reqs[i]->handle.socket()->Disconnect(); // No keep alive. | 365 reqs[i]->handle.socket()->Disconnect(); // No keep alive. |
363 reqs[i]->handle.Reset(); | 366 reqs[i]->handle.Reset(); |
364 MessageLoop::current()->RunAllPending(); | 367 MessageLoop::current()->RunAllPending(); |
365 released_one = true; | 368 released_one = true; |
366 } | 369 } |
367 } | 370 } |
368 } while (released_one); | 371 } while (released_one); |
369 | 372 |
370 for (int i = kMaxSocketsPerGroup; i < kNumRequests; ++i) | 373 for (int i = kMaxSocketsPerGroup; i < kNumRequests; ++i) |
371 EXPECT_EQ(OK, reqs[i]->WaitForResult()); | 374 EXPECT_EQ(OK, reqs[i]->WaitForResult()); |
372 | 375 |
373 EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count()); | 376 EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count()); |
374 EXPECT_EQ(kNumPendingRequests + 1, TestSocketRequest::completion_count); | 377 EXPECT_EQ(kNumPendingRequests + 1, TestSocketRequest::completion_count); |
375 } | 378 } |
376 | 379 |
377 // This test will start up a RequestSocket() and then immediately Cancel() it. | 380 // This test will start up a RequestSocket() and then immediately Cancel() it. |
378 // The pending host resolution will eventually complete, and destroy the | 381 // The pending host resolution will eventually complete, and destroy the |
379 // ClientSocketPool which will crash if the group was not cleared properly. | 382 // ClientSocketPool which will crash if the group was not cleared properly. |
380 TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) { | 383 TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) { |
381 TestSocketRequest req(pool_.get(), &request_order_); | 384 TestSocketRequest req(pool_.get(), &request_order_); |
382 EXPECT_EQ(ERR_IO_PENDING, | 385 HostResolver::RequestInfo info("www.google.com", 80); |
383 req.handle.Init("a", "www.google.com", 80, 5, &req)); | 386 EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req)); |
384 req.handle.Reset(); | 387 req.handle.Reset(); |
385 | 388 |
386 PlatformThread::Sleep(100); | 389 PlatformThread::Sleep(100); |
387 | 390 |
388 // There is a race condition here. If the worker pool doesn't post the task | 391 // There is a race condition here. If the worker pool doesn't post the task |
389 // before we get here, then this might not run ConnectingSocket::OnIOComplete | 392 // before we get here, then this might not run ConnectingSocket::OnIOComplete |
390 // and therefore leak the canceled ConnectingSocket. However, other tests | 393 // and therefore leak the canceled ConnectingSocket. However, other tests |
391 // after this will call MessageLoop::RunAllPending() which should prevent a | 394 // after this will call MessageLoop::RunAllPending() which should prevent a |
392 // leak, unless the worker thread takes longer than all of them. | 395 // leak, unless the worker thread takes longer than all of them. |
393 MessageLoop::current()->RunAllPending(); | 396 MessageLoop::current()->RunAllPending(); |
394 } | 397 } |
395 | 398 |
396 TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) { | 399 TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) { |
397 TestSocketRequest req(pool_.get(), &request_order_); | 400 TestSocketRequest req(pool_.get(), &request_order_); |
398 TestSocketRequest req2(pool_.get(), &request_order_); | 401 TestSocketRequest req2(pool_.get(), &request_order_); |
399 | 402 |
400 EXPECT_EQ(ERR_IO_PENDING, | 403 HostResolver::RequestInfo info("www.google.com", 80); |
401 req.handle.Init("a", "www.google.com", 80, 5, &req)); | 404 EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req)); |
402 EXPECT_EQ(ERR_IO_PENDING, | 405 EXPECT_EQ(ERR_IO_PENDING, req2.handle.Init("a", info, 5, &req2)); |
403 req2.handle.Init("a", "www.google.com", 80, 5, &req2)); | |
404 | 406 |
405 req.handle.Reset(); | 407 req.handle.Reset(); |
406 | 408 |
407 EXPECT_EQ(OK, req2.WaitForResult()); | 409 EXPECT_EQ(OK, req2.WaitForResult()); |
408 req2.handle.Reset(); | 410 req2.handle.Reset(); |
409 // The handle's Reset method may have posted a task. | 411 // The handle's Reset method may have posted a task. |
410 MessageLoop::current()->RunAllPending(); | 412 MessageLoop::current()->RunAllPending(); |
411 } | 413 } |
412 | 414 |
413 TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) { | 415 TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) { |
414 client_socket_factory_.set_client_socket_type( | 416 client_socket_factory_.set_client_socket_type( |
415 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); | 417 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); |
416 ClientSocketHandle handle(pool_.get()); | 418 ClientSocketHandle handle(pool_.get()); |
417 TestCompletionCallback callback; | 419 TestCompletionCallback callback; |
418 TestSocketRequest req(pool_.get(), &request_order_); | 420 TestSocketRequest req(pool_.get(), &request_order_); |
419 | 421 |
420 EXPECT_EQ(ERR_IO_PENDING, | 422 HostResolver::RequestInfo info("www.google.com", 80); |
421 handle.Init("a", "www.google.com", 80, 5, &callback)); | 423 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback)); |
422 | 424 |
423 handle.Reset(); | 425 handle.Reset(); |
424 | 426 |
425 TestCompletionCallback callback2; | 427 TestCompletionCallback callback2; |
426 EXPECT_EQ(ERR_IO_PENDING, | 428 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback2)); |
427 handle.Init("a", "www.google.com", 80, 5, &callback2)); | |
428 | 429 |
429 // At this point, handle has two ConnectingSockets out for it. Due to the | 430 // At this point, handle has two ConnectingSockets out for it. Due to the |
430 // host cache, the host resolution for both will return in the same loop of | 431 // host cache, the host resolution for both will return in the same loop of |
431 // the MessageLoop. The client socket is a pending socket, so the Connect() | 432 // the MessageLoop. The client socket is a pending socket, so the Connect() |
432 // will asynchronously complete on the next loop of the MessageLoop. That | 433 // will asynchronously complete on the next loop of the MessageLoop. That |
433 // means that the first ConnectingSocket will enter OnIOComplete, and then the | 434 // means that the first ConnectingSocket will enter OnIOComplete, and then the |
434 // second one will. If the first one is not cancelled, it will advance the | 435 // second one will. If the first one is not cancelled, it will advance the |
435 // load state, and then the second one will crash. | 436 // load state, and then the second one will crash. |
436 | 437 |
437 EXPECT_EQ(OK, callback2.WaitForResult()); | 438 EXPECT_EQ(OK, callback2.WaitForResult()); |
438 EXPECT_FALSE(callback.have_result()); | 439 EXPECT_FALSE(callback.have_result()); |
439 | 440 |
440 handle.Reset(); | 441 handle.Reset(); |
441 // The handle's Reset method may have posted a task. | 442 // The handle's Reset method may have posted a task. |
442 MessageLoop::current()->RunAllPending(); | 443 MessageLoop::current()->RunAllPending(); |
443 } | 444 } |
444 | 445 |
445 TEST_F(TCPClientSocketPoolTest, CancelRequest) { | 446 TEST_F(TCPClientSocketPoolTest, CancelRequest) { |
446 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; | 447 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; |
447 | 448 |
448 for (size_t i = 0; i < arraysize(reqs); ++i) | 449 for (size_t i = 0; i < arraysize(reqs); ++i) |
449 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); | 450 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); |
450 | 451 |
451 // Create connections or queue up requests. | 452 // Create connections or queue up requests. |
| 453 HostResolver::RequestInfo info("www.google.com", 80); |
452 | 454 |
453 // First request finishes asynchronously. | 455 // First request finishes asynchronously. |
454 int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get()); | 456 int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get()); |
455 EXPECT_EQ(ERR_IO_PENDING, rv); | 457 EXPECT_EQ(ERR_IO_PENDING, rv); |
456 EXPECT_EQ(OK, reqs[0]->WaitForResult()); | 458 EXPECT_EQ(OK, reqs[0]->WaitForResult()); |
457 | 459 |
458 // Rest of them finish synchronously, since they're in the HostCache. | 460 // Rest of them finish synchronously, since they're in the HostCache. |
459 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { | 461 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { |
460 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get()); | 462 rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get()); |
461 EXPECT_EQ(OK, rv); | 463 EXPECT_EQ(OK, rv); |
462 request_order_.push_back(reqs[i].get()); | 464 request_order_.push_back(reqs[i].get()); |
463 } | 465 } |
464 | 466 |
465 // The rest are pending since we've used all active sockets. | 467 // The rest are pending since we've used all active sockets. |
466 for (int i = 0; i < kNumPendingRequests; ++i) { | 468 for (int i = 0; i < kNumPendingRequests; ++i) { |
467 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init( | 469 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init( |
468 "a", "www.google.com", 80, kPriorities[i], | 470 "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get())); |
469 reqs[kMaxSocketsPerGroup + i].get())); | |
470 } | 471 } |
471 | 472 |
472 // Cancel a request. | 473 // Cancel a request. |
473 size_t index_to_cancel = kMaxSocketsPerGroup + 2; | 474 size_t index_to_cancel = kMaxSocketsPerGroup + 2; |
474 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized()); | 475 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized()); |
475 reqs[index_to_cancel]->handle.Reset(); | 476 reqs[index_to_cancel]->handle.Reset(); |
476 | 477 |
477 // Release any connections until we have no connections. | 478 // Release any connections until we have no connections. |
478 bool released_one; | 479 bool released_one; |
479 do { | 480 do { |
(...skipping 27 matching lines...) Expand all Loading... |
507 | 508 |
508 EXPECT_EQ(request_order_[arraysize(reqs) - 2], | 509 EXPECT_EQ(request_order_[arraysize(reqs) - 2], |
509 reqs[arraysize(reqs) - 1].get()) << | 510 reqs[arraysize(reqs) - 1].get()) << |
510 "The last request with priority 1 should not have been inserted " | 511 "The last request with priority 1 should not have been inserted " |
511 "earlier into the queue."; | 512 "earlier into the queue."; |
512 } | 513 } |
513 | 514 |
514 } // namespace | 515 } // namespace |
515 | 516 |
516 } // namespace net | 517 } // namespace net |
OLD | NEW |