| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/message_loop/message_pump_win.h" | 5 #include "base/message_loop/message_pump_win.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 // If |item.has_valid_io_context| is false then |item.context| does not point | 545 // If |item.has_valid_io_context| is false then |item.context| does not point |
| 546 // to a context structure, and so should not be dereferenced, although it may | 546 // to a context structure, and so should not be dereferenced, although it may |
| 547 // still hold valid non-pointer data. | 547 // still hold valid non-pointer data. |
| 548 if (!item.has_valid_io_context || item.context->handler) { | 548 if (!item.has_valid_io_context || item.context->handler) { |
| 549 if (filter && item.handler != filter) { | 549 if (filter && item.handler != filter) { |
| 550 // Save this item for later | 550 // Save this item for later |
| 551 completed_io_.push_back(item); | 551 completed_io_.push_back(item); |
| 552 } else { | 552 } else { |
| 553 DCHECK(!item.has_valid_io_context || | 553 DCHECK(!item.has_valid_io_context || |
| 554 (item.context->handler == item.handler)); | 554 (item.context->handler == item.handler)); |
| 555 WillProcessIOEvent(); | |
| 556 item.handler->OnIOCompleted(item.context, item.bytes_transfered, | 555 item.handler->OnIOCompleted(item.context, item.bytes_transfered, |
| 557 item.error); | 556 item.error); |
| 558 DidProcessIOEvent(); | |
| 559 } | 557 } |
| 560 } else { | 558 } else { |
| 561 // The handler must be gone by now, just cleanup the mess. | 559 // The handler must be gone by now, just cleanup the mess. |
| 562 delete item.context; | 560 delete item.context; |
| 563 } | 561 } |
| 564 return true; | 562 return true; |
| 565 } | 563 } |
| 566 | 564 |
| 567 // Asks the OS for another IO completion result. | 565 // Asks the OS for another IO completion result. |
| 568 bool MessagePumpForIO::GetIOItem(DWORD timeout, IOItem* item) { | 566 bool MessagePumpForIO::GetIOItem(DWORD timeout, IOItem* item) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 it != completed_io_.end(); ++it) { | 598 it != completed_io_.end(); ++it) { |
| 601 if (!filter || it->handler == filter) { | 599 if (!filter || it->handler == filter) { |
| 602 *item = *it; | 600 *item = *it; |
| 603 completed_io_.erase(it); | 601 completed_io_.erase(it); |
| 604 return true; | 602 return true; |
| 605 } | 603 } |
| 606 } | 604 } |
| 607 return false; | 605 return false; |
| 608 } | 606 } |
| 609 | 607 |
| 610 void MessagePumpForIO::AddIOObserver(IOObserver *obs) { | |
| 611 io_observers_.AddObserver(obs); | |
| 612 } | |
| 613 | |
| 614 void MessagePumpForIO::RemoveIOObserver(IOObserver *obs) { | |
| 615 io_observers_.RemoveObserver(obs); | |
| 616 } | |
| 617 | |
| 618 void MessagePumpForIO::WillProcessIOEvent() { | |
| 619 FOR_EACH_OBSERVER(IOObserver, io_observers_, WillProcessIOEvent()); | |
| 620 } | |
| 621 | |
| 622 void MessagePumpForIO::DidProcessIOEvent() { | |
| 623 FOR_EACH_OBSERVER(IOObserver, io_observers_, DidProcessIOEvent()); | |
| 624 } | |
| 625 | |
| 626 // static | 608 // static |
| 627 ULONG_PTR MessagePumpForIO::HandlerToKey(IOHandler* handler, | 609 ULONG_PTR MessagePumpForIO::HandlerToKey(IOHandler* handler, |
| 628 bool has_valid_io_context) { | 610 bool has_valid_io_context) { |
| 629 ULONG_PTR key = reinterpret_cast<ULONG_PTR>(handler); | 611 ULONG_PTR key = reinterpret_cast<ULONG_PTR>(handler); |
| 630 | 612 |
| 631 // |IOHandler| is at least pointer-size aligned, so the lowest two bits are | 613 // |IOHandler| is at least pointer-size aligned, so the lowest two bits are |
| 632 // always cleared. We use the lowest bit to distinguish completion keys with | 614 // always cleared. We use the lowest bit to distinguish completion keys with |
| 633 // and without the associated |IOContext|. | 615 // and without the associated |IOContext|. |
| 634 DCHECK_EQ(key & 1, 0u); | 616 DCHECK_EQ(key & 1, 0u); |
| 635 | 617 |
| 636 // Mark the completion key as context-less. | 618 // Mark the completion key as context-less. |
| 637 if (!has_valid_io_context) | 619 if (!has_valid_io_context) |
| 638 key = key | 1; | 620 key = key | 1; |
| 639 return key; | 621 return key; |
| 640 } | 622 } |
| 641 | 623 |
| 642 // static | 624 // static |
| 643 MessagePumpForIO::IOHandler* MessagePumpForIO::KeyToHandler( | 625 MessagePumpForIO::IOHandler* MessagePumpForIO::KeyToHandler( |
| 644 ULONG_PTR key, | 626 ULONG_PTR key, |
| 645 bool* has_valid_io_context) { | 627 bool* has_valid_io_context) { |
| 646 *has_valid_io_context = ((key & 1) == 0); | 628 *has_valid_io_context = ((key & 1) == 0); |
| 647 return reinterpret_cast<IOHandler*>(key & ~static_cast<ULONG_PTR>(1)); | 629 return reinterpret_cast<IOHandler*>(key & ~static_cast<ULONG_PTR>(1)); |
| 648 } | 630 } |
| 649 | 631 |
| 650 } // namespace base | 632 } // namespace base |
| OLD | NEW |