1 // Copyright 2014 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 "network/public/cpp/web_socket_write_queue.h"
8 #include "base/logging.h"
12 struct WebSocketWriteQueue::Operation
{
14 base::Callback
<void(const char*)> callback_
;
17 // Only initialized if the initial Write fails. This saves a copy in
19 std::vector
<char> data_copy_
;
22 WebSocketWriteQueue::WebSocketWriteQueue(DataPipeProducerHandle handle
)
23 : handle_(handle
), is_busy_(false), weak_factory_(this) {
26 WebSocketWriteQueue::~WebSocketWriteQueue() {
29 void WebSocketWriteQueue::Write(const char* data
,
31 base::Callback
<void(const char*)> callback
) {
32 Operation
* op
= new Operation
;
33 op
->num_bytes_
= num_bytes
;
34 op
->callback_
= callback
;
40 // This call may reset |is_busy_| to false.
45 // If we have to wait, make a local copy of the data so we know it will
46 // live until we need it.
47 op
->data_copy_
.resize(num_bytes
);
48 memcpy(&op
->data_copy_
[0], data
, num_bytes
);
49 op
->data_
= &op
->data_copy_
[0];
53 void WebSocketWriteQueue::TryToWrite() {
55 DCHECK(!queue_
.empty());
57 Operation
* op
= queue_
[0];
58 uint32_t bytes_written
= op
->num_bytes_
;
59 MojoResult result
= WriteDataRaw(
60 handle_
, op
->data_
, &bytes_written
, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE
);
61 if (result
== MOJO_RESULT_SHOULD_WAIT
) {
66 // Ensure |op| is deleted, whether or not |this| goes away.
67 scoped_ptr
<Operation
> op_deleter(op
);
68 queue_
.weak_erase(queue_
.begin());
70 // http://crbug.com/490193 This should run callback as well. May need to
71 // change the callback signature.
72 if (result
!= MOJO_RESULT_OK
)
75 base::WeakPtr
<WebSocketWriteQueue
> self(weak_factory_
.GetWeakPtr());
77 // This call may delete |this|. In that case, |self| will be invalidated.
78 // It may re-enter Write() too. Because |is_busy_| is true during the whole
79 // process, TryToWrite() won't be re-entered.
80 op
->callback_
.Run(op
->data_
);
84 } while (!queue_
.empty());
88 void WebSocketWriteQueue::Wait() {
90 handle_watcher_
.Start(handle_
,
91 MOJO_HANDLE_SIGNAL_WRITABLE
,
92 MOJO_DEADLINE_INDEFINITE
,
93 base::Bind(&WebSocketWriteQueue::OnHandleReady
,
94 base::Unretained(this)));
97 void WebSocketWriteQueue::OnHandleReady(MojoResult result
) {