OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "media/audio/async_socket_io_handler.h" | |
6 | |
7 #include <fcntl.h> | |
8 #include "base/eintr_wrapper.h" | |
9 | |
10 namespace media { | |
11 | |
12 AsyncSocketIoHandler::AsyncSocketIoHandler() | |
13 : socket_(base::SyncSocket::kInvalidHandle), | |
14 is_watching_(false) {} | |
15 | |
16 AsyncSocketIoHandler::~AsyncSocketIoHandler() { | |
17 DCHECK(CalledOnValidThread()); | |
18 } | |
19 | |
20 void AsyncSocketIoHandler::OnFileCanReadWithoutBlocking(int socket) { | |
21 DCHECK(CalledOnValidThread()); | |
22 DCHECK_EQ(socket, socket_); | |
23 if (!read_complete_.is_null()) { | |
24 int bytes_read = HANDLE_EINTR(read(socket_, pending_buffer_, | |
25 pending_buffer_len_)); | |
henrika (OOO until Aug 14)
2012/06/07 12:25:59
nit, fix indentation
tommi (sloooow) - chröme
2012/06/07 12:34:33
Done.
| |
26 DCHECK_GT(bytes_read, 0); | |
27 read_complete_.Run(bytes_read > 0 ? bytes_read : 0); | |
28 read_complete_.Reset(); | |
29 } else { | |
30 // 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, | |
32 // let's stop watching the fd and restart the watch when Read() is called. | |
33 is_watching_ = false; | |
34 socket_watcher_.StopWatchingFileDescriptor(); | |
35 } | |
36 } | |
37 | |
38 bool AsyncSocketIoHandler::Read(char* buffer, int buffer_len, | |
39 const ReadCompleteCallback& callback) { | |
henrika (OOO until Aug 14)
2012/06/07 12:25:59
odd indentation
tommi (sloooow) - chröme
2012/06/07 12:34:33
Done.
| |
40 DCHECK(CalledOnValidThread()); | |
41 DCHECK(read_complete_.is_null()); | |
42 | |
43 EnsureWatchingSocket(); | |
44 | |
45 int bytes_read = HANDLE_EINTR(read(socket_, buffer, buffer_len)); | |
46 if (bytes_read < 0) { | |
47 if (errno == EAGAIN) { | |
48 read_complete_ = callback; | |
49 pending_buffer_ = buffer; | |
50 pending_buffer_len_ = buffer_len; | |
51 } else { | |
52 NOTREACHED() << "read(): " << errno; | |
53 return false; | |
54 } | |
55 } else { | |
56 callback.Run(bytes_read); | |
57 } | |
58 return true; | |
59 } | |
60 | |
61 bool AsyncSocketIoHandler::Initialize(base::SyncSocket::Handle socket) { | |
62 DCHECK_EQ(socket_, base::SyncSocket::kInvalidHandle); | |
63 | |
64 DetachFromThread(); | |
65 | |
66 socket_ = socket; | |
67 | |
68 // SyncSocket is blocking by default, so let's convert it to non-blocking. | |
69 int value = fcntl(socket, F_GETFL); | |
70 if (!(value & O_NONBLOCK)) { | |
71 // Set the socket to be non-blocking so we can do async reads. | |
72 if (fcntl(socket, F_SETFL, O_NONBLOCK) == -1) { | |
73 NOTREACHED(); | |
74 return false; | |
75 } | |
76 } | |
77 | |
78 return true; | |
79 } | |
80 | |
81 void AsyncSocketIoHandler::EnsureWatchingSocket() { | |
82 DCHECK(CalledOnValidThread()); | |
83 if (!is_watching_ && socket_ != base::SyncSocket::kInvalidHandle) { | |
84 is_watching_ = MessageLoopForIO::current()->WatchFileDescriptor( | |
85 socket_, true, MessageLoopForIO::WATCH_READ, &socket_watcher_, this); | |
86 } | |
87 } | |
88 | |
89 } // namespace media. | |
OLD | NEW |