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: remoting/jingle_glue/jingle_channel.cc

Issue 2690003: Copy the (early prototype of) remoting in Chrome into the public tree.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « remoting/jingle_glue/jingle_channel.h ('k') | remoting/jingle_glue/jingle_channel_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 "remoting/jingle_glue/jingle_channel.h"
6
7 #include "base/lock.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "base/waitable_event.h"
11 #include "media/base/data_buffer.h"
12 #include "remoting/jingle_glue/jingle_thread.h"
13 #include "talk/base/stream.h"
14
15 using media::DataBuffer;
16
17 namespace remoting {
18
19 const size_t kReadBufferSize = 4096;
20
21 JingleChannel::JingleChannel(Callback* callback)
22 : state_(INITIALIZING),
23 event_handler_(this),
24 callback_(callback),
25 write_buffer_size_(0),
26 current_write_buf_pos_(0) {
27 DCHECK(callback_ != NULL);
28 }
29
30 // This constructor is only used in unit test.
31 JingleChannel::JingleChannel()
32 : state_(CLOSED),
33 write_buffer_size_(0),
34 current_write_buf_pos_(0) {
35 }
36
37 JingleChannel::~JingleChannel() {
38 DCHECK(state_ == CLOSED);
39 }
40
41 void JingleChannel::Init(JingleThread* thread,
42 talk_base::StreamInterface* stream,
43 const std::string& jid) {
44 thread_ = thread;
45 stream_.reset(stream);
46 stream_->SignalEvent.connect(&event_handler_, &EventHandler::OnStreamEvent);
47
48 // Initialize |state_|.
49 switch (stream->GetState()) {
50 case talk_base::SS_CLOSED:
51 SetState(CLOSED);
52 break;
53 case talk_base::SS_OPENING:
54 SetState(CONNECTING);
55 break;
56 case talk_base::SS_OPEN:
57 SetState(OPEN);
58 // Try to read in case there is something in the stream.
59 thread_->message_loop()->PostTask(
60 FROM_HERE, NewRunnableMethod(this, &JingleChannel::DoRead));
61 break;
62 default:
63 NOTREACHED();
64 }
65
66 jid_ = jid;
67 }
68
69 void JingleChannel::Write(scoped_refptr<DataBuffer> data) {
70 // Discard empty packets.
71 if (data->GetDataSize() != 0) {
72 AutoLock auto_lock(write_lock_);
73 write_queue_.push_back(data);
74 write_buffer_size_ += data->GetDataSize();
75 // Post event so that the data gets written in the tunnel thread.
76 thread_->message_loop()->PostTask(
77 FROM_HERE, NewRunnableMethod(this, &JingleChannel::DoWrite));
78 }
79 }
80
81 void JingleChannel::DoRead() {
82 while (true) {
83 size_t bytes_to_read;
84 if (stream_->GetAvailable(&bytes_to_read)) {
85 // Return immediately if we know there is nothing to read.
86 if (bytes_to_read == 0)
87 return;
88 } else {
89 // Try to read kReadBufferSize if the stream doesn't support
90 // GetAvailable().
91 bytes_to_read = kReadBufferSize;
92 }
93
94 scoped_refptr<DataBuffer> buffer(
95 new DataBuffer(new uint8[bytes_to_read], kReadBufferSize));
96 size_t bytes_read;
97 int error;
98 talk_base::StreamResult result = stream_->Read(
99 buffer->GetWritableData(), bytes_to_read, &bytes_read, &error);
100 switch (result) {
101 case talk_base::SR_SUCCESS: {
102 DCHECK(bytes_read > 0);
103 buffer->SetDataSize(bytes_read);
104 callback_->OnPacketReceived(this, buffer);
105 break;
106 }
107 case talk_base::SR_BLOCK: {
108 return;
109 }
110 case talk_base::SR_EOS: {
111 SetState(CLOSED);
112 return;
113 }
114 case talk_base::SR_ERROR: {
115 SetState(FAILED);
116 return;
117 }
118 }
119 }
120 }
121
122 void JingleChannel::DoWrite() {
123 while (true) {
124 if (!current_write_buf_) {
125 AutoLock auto_lock(write_lock_);
126 if (write_queue_.empty())
127 break;
128 current_write_buf_ = write_queue_.front();
129 current_write_buf_pos_ = 0;
130 write_queue_.pop_front();
131 }
132
133 size_t bytes_written;
134 int error;
135 talk_base::StreamResult result = stream_->Write(
136 current_write_buf_->GetData() + current_write_buf_pos_,
137 current_write_buf_->GetDataSize() - current_write_buf_pos_,
138 &bytes_written, &error);
139 switch (result) {
140 case talk_base::SR_SUCCESS: {
141 current_write_buf_pos_ += bytes_written;
142 if (current_write_buf_pos_ >= current_write_buf_->GetDataSize())
143 current_write_buf_ = NULL;
144 {
145 AutoLock auto_lock(write_lock_);
146 write_buffer_size_ -= bytes_written;
147 }
148 break;
149 }
150 case talk_base::SR_BLOCK: {
151 return;
152 }
153 case talk_base::SR_EOS: {
154 SetState(CLOSED);
155 return;
156 }
157 case talk_base::SR_ERROR: {
158 SetState(FAILED);
159 return;
160 }
161 }
162 }
163 }
164
165 void JingleChannel::OnStreamEvent(talk_base::StreamInterface* stream,
166 int events, int error) {
167 if (events & talk_base::SE_OPEN) {
168 SetState(OPEN);
169 }
170
171 if (state_ == OPEN && (events & talk_base::SE_WRITE)) {
172 DoWrite();
173 }
174
175 if (state_ == OPEN && (events & talk_base::SE_READ)) {
176 DoRead();
177 }
178
179 if (events & talk_base::SE_CLOSE) {
180 SetState(CLOSED);
181 }
182 }
183
184 void JingleChannel::SetState(State state) {
185 if (state == state_)
186 return;
187 state_ = state;
188 callback_->OnStateChange(this, state);
189 }
190
191 void JingleChannel::Close() {
192 base::WaitableEvent event(true, false);
193 thread_->message_loop()->PostTask(
194 FROM_HERE, NewRunnableMethod(this, &JingleChannel::DoClose, &event));
195 event.Wait();
196 }
197
198 void JingleChannel::DoClose(base::WaitableEvent* done_event) {
199 if (stream_.get())
200 stream_->Close();
201 SetState(CLOSED);
202 done_event->Signal();
203 }
204
205 size_t JingleChannel::write_buffer_size() {
206 AutoLock auto_lock(write_lock_);
207 return write_buffer_size_;
208 }
209
210 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/jingle_glue/jingle_channel.h ('k') | remoting/jingle_glue/jingle_channel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698