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

Side by Side Diff: mojo/services/network/public/cpp/web_socket_read_queue.cc

Issue 1396423002: Move //mojo/services/network/public/interfaces to //mojo/services/network/interfaces. (Closed) Base URL: https://github.com/domokit/monet.git@master
Patch Set: Created 5 years, 2 months 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
OLDNEW
(Empty)
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.
4
5 #include "network/public/cpp/web_socket_read_queue.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11
12 namespace mojo {
13
14 struct WebSocketReadQueue::Operation {
15 uint32_t num_bytes_;
16 base::Callback<void(const char*)> callback_;
17 };
18
19 WebSocketReadQueue::WebSocketReadQueue(DataPipeConsumerHandle handle)
20 : handle_(handle), is_busy_(false), weak_factory_(this) {
21 }
22
23 WebSocketReadQueue::~WebSocketReadQueue() {
24 }
25
26 void WebSocketReadQueue::Read(uint32_t num_bytes,
27 base::Callback<void(const char*)> callback) {
28 Operation* op = new Operation;
29 op->num_bytes_ = num_bytes;
30 op->callback_ = callback;
31 queue_.push_back(op);
32
33 if (is_busy_)
34 return;
35
36 is_busy_ = true;
37 TryToRead();
38 }
39
40 void WebSocketReadQueue::TryToRead() {
41 DCHECK(is_busy_);
42 DCHECK(!queue_.empty());
43 do {
44 Operation* op = queue_[0];
45 // TODO(vtl): We could avoid allocating the buffer in the case that we'll
46 // have to wait by querying first. Or we could preallocate a buffer, etc.
47 std::unique_ptr<char[]> buffer(new char[op->num_bytes_]);
48 uint32_t bytes_read = op->num_bytes_;
49 MojoResult result = ReadDataRaw(handle_, buffer.get(), &bytes_read,
50 MOJO_READ_DATA_FLAG_ALL_OR_NONE);
51 // TODO(vtl): In the "out of range" case (there's data, but not enough
52 // data), this will cause it to spin (via the message loop). There's not
53 // much to be done about that until
54 // https://github.com/domokit/mojo/issues/442 is fixed (unless we want to do
55 // our own buffering).
56 if (result == MOJO_RESULT_SHOULD_WAIT ||
57 result == MOJO_RESULT_OUT_OF_RANGE) {
58 Wait();
59 return;
60 }
61
62 // Ensure |op| is deleted, whether or not |this| goes away.
63 std::unique_ptr<Operation> op_deleter(op);
64 queue_.weak_erase(queue_.begin());
65
66 // http://crbug.com/490193 This should run callback as well. May need to
67 // change the callback signature.
68 if (result != MOJO_RESULT_OK)
69 return;
70
71 uint32_t num_bytes = op_deleter->num_bytes_;
72 DCHECK_LE(num_bytes, bytes_read);
73 DataPipeConsumerHandle handle = handle_;
74
75 base::WeakPtr<WebSocketReadQueue> self(weak_factory_.GetWeakPtr());
76
77 // This call may delete |this|. In that case, |self| will be invalidated.
78 // It may re-enter Read() too. Because |is_busy_| is true during the whole
79 // process, TryToRead() won't be re-entered.
80 op->callback_.Run(buffer.get());
81
82 if (!self)
83 return;
84 } while (!queue_.empty());
85 is_busy_ = false;
86 }
87
88 void WebSocketReadQueue::Wait() {
89 DCHECK(is_busy_);
90 handle_watcher_.Start(
91 handle_,
92 MOJO_HANDLE_SIGNAL_READABLE,
93 MOJO_DEADLINE_INDEFINITE,
94 base::Bind(&WebSocketReadQueue::OnHandleReady, base::Unretained(this)));
95 }
96
97 void WebSocketReadQueue::OnHandleReady(MojoResult result) {
98 DCHECK(is_busy_);
99 TryToRead();
100 }
101
102 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/network/public/cpp/web_socket_read_queue.h ('k') | mojo/services/network/public/cpp/web_socket_write_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698