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: media/audio/async_socket_io_handler_posix.cc

Issue 10697069: Move the callback out of the Read method and into Initialize to make Read loops simpler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix expectations for the synchronous test Created 8 years, 5 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/async_socket_io_handler.h" 5 #include "media/audio/async_socket_io_handler.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include "base/eintr_wrapper.h" 8 #include "base/eintr_wrapper.h"
9 9
10 namespace media { 10 namespace media {
11 11
12 AsyncSocketIoHandler::AsyncSocketIoHandler() 12 AsyncSocketIoHandler::AsyncSocketIoHandler()
13 : socket_(base::SyncSocket::kInvalidHandle), 13 : socket_(base::SyncSocket::kInvalidHandle),
14 is_watching_(false) {} 14 is_watching_(false) {}
15 15
16 AsyncSocketIoHandler::~AsyncSocketIoHandler() { 16 AsyncSocketIoHandler::~AsyncSocketIoHandler() {
17 DCHECK(CalledOnValidThread()); 17 DCHECK(CalledOnValidThread());
18 } 18 }
19 19
20 void AsyncSocketIoHandler::OnFileCanReadWithoutBlocking(int socket) { 20 void AsyncSocketIoHandler::OnFileCanReadWithoutBlocking(int socket) {
21 DCHECK(CalledOnValidThread()); 21 DCHECK(CalledOnValidThread());
22 DCHECK_EQ(socket, socket_); 22 DCHECK_EQ(socket, socket_);
23 if (!read_complete_.is_null()) { 23 DCHECK(!read_complete_.is_null());
24
25 if (pending_buffer_) {
24 int bytes_read = HANDLE_EINTR(read(socket_, pending_buffer_, 26 int bytes_read = HANDLE_EINTR(read(socket_, pending_buffer_,
25 pending_buffer_len_)); 27 pending_buffer_len_));
26 DCHECK_GT(bytes_read, 0); 28 DCHECK_GT(bytes_read, 0);
29 pending_buffer_ = NULL;
30 pending_buffer_len_ = 0;
27 read_complete_.Run(bytes_read > 0 ? bytes_read : 0); 31 read_complete_.Run(bytes_read > 0 ? bytes_read : 0);
28 read_complete_.Reset();
29 } else { 32 } else {
30 // We're getting notifications that we can read from the socket while 33 // We're getting notifications that we can read from the socket while
31 // we're not waiting for data. In order to not starve the message loop, 34 // we're not waiting for data. In order to not starve the message loop,
32 // let's stop watching the fd and restart the watch when Read() is called. 35 // let's stop watching the fd and restart the watch when Read() is called.
33 is_watching_ = false; 36 is_watching_ = false;
34 socket_watcher_.StopWatchingFileDescriptor(); 37 socket_watcher_.StopWatchingFileDescriptor();
35 } 38 }
36 } 39 }
37 40
38 bool AsyncSocketIoHandler::Read(char* buffer, int buffer_len, 41 bool AsyncSocketIoHandler::Read(char* buffer, int buffer_len) {
39 const ReadCompleteCallback& callback) {
40 DCHECK(CalledOnValidThread()); 42 DCHECK(CalledOnValidThread());
41 DCHECK(read_complete_.is_null()); 43 DCHECK(!read_complete_.is_null());
44 DCHECK(!pending_buffer_);
42 45
43 EnsureWatchingSocket(); 46 EnsureWatchingSocket();
44 47
45 int bytes_read = HANDLE_EINTR(read(socket_, buffer, buffer_len)); 48 int bytes_read = HANDLE_EINTR(read(socket_, buffer, buffer_len));
46 if (bytes_read < 0) { 49 if (bytes_read < 0) {
47 if (errno == EAGAIN) { 50 if (errno == EAGAIN) {
48 read_complete_ = callback;
49 pending_buffer_ = buffer; 51 pending_buffer_ = buffer;
50 pending_buffer_len_ = buffer_len; 52 pending_buffer_len_ = buffer_len;
51 } else { 53 } else {
52 NOTREACHED() << "read(): " << errno; 54 NOTREACHED() << "read(): " << errno;
53 return false; 55 return false;
54 } 56 }
55 } else { 57 } else {
56 callback.Run(bytes_read); 58 read_complete_.Run(bytes_read);
57 } 59 }
58 return true; 60 return true;
59 } 61 }
60 62
61 bool AsyncSocketIoHandler::Initialize(base::SyncSocket::Handle socket) { 63 bool AsyncSocketIoHandler::Initialize(base::SyncSocket::Handle socket,
64 const ReadCompleteCallback& callback) {
62 DCHECK_EQ(socket_, base::SyncSocket::kInvalidHandle); 65 DCHECK_EQ(socket_, base::SyncSocket::kInvalidHandle);
63 66
64 DetachFromThread(); 67 DetachFromThread();
65 68
66 socket_ = socket; 69 socket_ = socket;
70 read_complete_ = callback;
67 71
68 // SyncSocket is blocking by default, so let's convert it to non-blocking. 72 // SyncSocket is blocking by default, so let's convert it to non-blocking.
69 int value = fcntl(socket, F_GETFL); 73 int value = fcntl(socket, F_GETFL);
70 if (!(value & O_NONBLOCK)) { 74 if (!(value & O_NONBLOCK)) {
71 // Set the socket to be non-blocking so we can do async reads. 75 // Set the socket to be non-blocking so we can do async reads.
72 if (fcntl(socket, F_SETFL, O_NONBLOCK) == -1) { 76 if (fcntl(socket, F_SETFL, O_NONBLOCK) == -1) {
73 NOTREACHED(); 77 NOTREACHED();
74 return false; 78 return false;
75 } 79 }
76 } 80 }
77 81
78 return true; 82 return true;
79 } 83 }
80 84
81 void AsyncSocketIoHandler::EnsureWatchingSocket() { 85 void AsyncSocketIoHandler::EnsureWatchingSocket() {
82 DCHECK(CalledOnValidThread()); 86 DCHECK(CalledOnValidThread());
83 if (!is_watching_ && socket_ != base::SyncSocket::kInvalidHandle) { 87 if (!is_watching_ && socket_ != base::SyncSocket::kInvalidHandle) {
84 is_watching_ = MessageLoopForIO::current()->WatchFileDescriptor( 88 is_watching_ = MessageLoopForIO::current()->WatchFileDescriptor(
85 socket_, true, MessageLoopForIO::WATCH_READ, &socket_watcher_, this); 89 socket_, true, MessageLoopForIO::WATCH_READ, &socket_watcher_, this);
86 } 90 }
87 } 91 }
88 92
89 } // namespace media. 93 } // namespace media.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698