1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/shared_memory_received_data_factory.h"
9 #include "content/common/resource_messages.h"
10 #include "ipc/ipc_sender.h"
14 class SharedMemoryReceivedDataFactory::SharedMemoryReceivedData final
15 : public RequestPeer::ReceivedData
{
17 SharedMemoryReceivedData(
21 scoped_refptr
<SharedMemoryReceivedDataFactory
> factory
,
22 SharedMemoryReceivedDataFactory::TicketId id
)
25 encoded_length_(encoded_length
),
29 ~SharedMemoryReceivedData() override
{ factory_
->Reclaim(id_
); }
31 const char* payload() const override
{ return payload_
; }
32 int length() const override
{ return length_
; }
33 int encoded_length() const override
{ return encoded_length_
; }
36 const char* const payload_
;
38 const int encoded_length_
;
40 scoped_refptr
<SharedMemoryReceivedDataFactory
> factory_
;
41 SharedMemoryReceivedDataFactory::TicketId id_
;
43 DISALLOW_COPY_AND_ASSIGN(SharedMemoryReceivedData
);
46 SharedMemoryReceivedDataFactory::SharedMemoryReceivedDataFactory(
47 IPC::Sender
* message_sender
,
49 linked_ptr
<base::SharedMemory
> memory
)
52 message_sender_(message_sender
),
53 request_id_(request_id
),
58 SharedMemoryReceivedDataFactory::~SharedMemoryReceivedDataFactory() {
60 SendAck(released_tickets_
.size());
63 scoped_ptr
<RequestPeer::ReceivedData
> SharedMemoryReceivedDataFactory::Create(
67 const char* start
= static_cast<char*>(memory_
->memory());
68 const char* payload
= start
+ offset
;
71 return make_scoped_ptr(
72 new SharedMemoryReceivedData(payload
, length
, encoded_length
, this, id
));
75 void SharedMemoryReceivedDataFactory::Stop() {
77 released_tickets_
.clear();
78 message_sender_
= nullptr;
81 class SharedMemoryReceivedDataFactory::TicketComparator final
{
83 explicit TicketComparator(TicketId oldest
) : oldest_(oldest
) {}
84 bool operator()(TicketId x
, TicketId y
) const {
85 if ((oldest_
<= x
) == (oldest_
<= y
))
88 return (oldest_
<= x
);
95 void SharedMemoryReceivedDataFactory::Reclaim(TicketId id
) {
99 released_tickets_
.push_back(id
);
105 if (released_tickets_
.empty()) {
106 // Fast path: (hopefully) the most typical case.
109 std::sort(released_tickets_
.begin(), released_tickets_
.end(),
110 TicketComparator(oldest_
));
112 for (size_t i
= 0;; ++i
) {
113 if (i
== released_tickets_
.size() ||
114 released_tickets_
[i
] != static_cast<TicketId
>(id
+ i
+ 1)) {
119 released_tickets_
.erase(released_tickets_
.begin(),
120 released_tickets_
.begin() + count
);
125 void SharedMemoryReceivedDataFactory::SendAck(size_t count
) {
126 for (size_t i
= 0; i
< count
; ++i
) {
127 message_sender_
->Send(new ResourceHostMsg_DataReceived_ACK(request_id_
));
131 } // namespace content