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

Side by Side Diff: mojo/public/bindings/lib/connector.cc

Issue 54743003: Mojo: bindings connector (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Extract SimpleBindingsSupport Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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 "mojo/public/bindings/lib/connector.h"
6
7 #include <assert.h>
8 #include <stdlib.h>
9
10 #include <algorithm>
11
12 namespace mojo {
13
14 // ----------------------------------------------------------------------------
15
16 Connector::Connector(Handle message_pipe)
17 : message_pipe_(message_pipe),
18 incoming_receiver_(NULL),
19 error_(false) {
20 }
21
22 Connector::~Connector() {
23 if (read_callback_.IsPending())
24 read_callback_.Cancel();
25 if (write_callback_.IsPending())
26 write_callback_.Cancel();
27 }
28
29 void Connector::SetIncomingReceiver(MessageReceiver* receiver) {
30 assert(!incoming_receiver_);
31 incoming_receiver_ = receiver;
32 if (incoming_receiver_)
33 WaitToReadMore();
34 }
35
36 bool Connector::Accept(Message* message) {
37 if (error_)
38 return false;
39
40 write_queue_.push(Message());
41 write_queue_.back().Swap(message);
42 WriteMore();
43 return !error_;
44 }
45
46 void Connector::OnHandleReady(Callback* callback, MojoResult result) {
47 if (callback == &read_callback_)
48 ReadMore();
49 if (callback == &write_callback_)
50 WriteMore();
51 }
52
53 void Connector::WaitToReadMore() {
54 read_callback_.SetOwnerToNotify(this);
55
56 bool ok = BindingsSupport::Get()->AsyncWait(message_pipe_,
57 MOJO_WAIT_FLAG_READABLE,
58 MOJO_DEADLINE_INDEFINITE,
59 &read_callback_);
60 if (!ok)
61 error_ = true;
62 }
63
64 void Connector::WaitToWriteMore() {
65 write_callback_.SetOwnerToNotify(this);
66
67 bool ok = BindingsSupport::Get()->AsyncWait(message_pipe_,
68 MOJO_WAIT_FLAG_WRITABLE,
69 MOJO_DEADLINE_INDEFINITE,
70 &write_callback_);
71 if (!ok)
72 error_ = true;
73 }
74
75 void Connector::ReadMore() {
76 for (;;) {
77 MojoResult rv;
78
79 uint32_t num_bytes = 0, num_handles = 0;
80 rv = ReadMessage(message_pipe_,
viettrungluu 2013/11/05 22:45:29 I wonder if it wouldn't be better (mostly for perf
81 NULL,
82 &num_bytes,
83 NULL,
84 &num_handles,
85 MOJO_READ_MESSAGE_FLAG_NONE);
86 if (rv == MOJO_RESULT_NOT_FOUND) {
87 WaitToReadMore();
88 break;
89 }
90 if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) {
91 error_ = true;
92 break;
93 }
94
95 Message message;
96 message.data = static_cast<MessageData*>(malloc(num_bytes));
97 message.handles.resize(num_handles);
98
99 rv = ReadMessage(message_pipe_,
100 message.data,
101 &num_bytes,
102 &message.handles[0],
103 &num_handles,
104 MOJO_READ_MESSAGE_FLAG_NONE);
105 if (rv != MOJO_RESULT_OK) {
106 error_ = true;
107 break;
108 }
109
110 incoming_receiver_->Accept(&message);
111 }
112 }
113
114 void Connector::WriteMore() {
115 while (!write_queue_.empty()) {
116 const Message& message = write_queue_.back();
117
118 MojoResult rv = WriteMessage(message_pipe_,
119 message.data,
120 message.data->header.num_bytes,
121 message.handles.data(),
122 message.handles.size(),
123 MOJO_WRITE_MESSAGE_FLAG_NONE);
124 if (rv == MOJO_RESULT_OK) {
125 write_queue_.pop();
126 continue; // Write another message.
127 }
128
129 error_ = true;
130 break;
131 }
132 }
133
134 // ----------------------------------------------------------------------------
135
136 Connector::Callback::Callback()
137 : owner_(NULL) {
138 }
139
140 void Connector::Callback::Cancel() {
141 owner_ = NULL;
142 BindingsSupport::Get()->CancelWait(this);
143 }
144
145 void Connector::Callback::SetOwnerToNotify(Connector* owner) {
146 assert(!owner_);
147 owner_ = owner;
148 }
149
150 bool Connector::Callback::IsPending() const {
151 return owner_ != NULL;
152 }
153
154 void Connector::Callback::OnHandleReady(MojoResult result) {
155 assert(owner_);
156 Connector* owner = NULL;
157 std::swap(owner, owner_);
158 owner->OnHandleReady(this, result);
159 }
160
161 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698