blob: 562ae25cb771136a0b82d710e9984f09addd9857 [file] [log] [blame]
[email protected]39cb64f2013-08-22 12:39:331// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]a0e3f0f2012-06-07 12:45:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]39cb64f2013-08-22 12:39:335#ifndef BASE_ASYNC_SOCKET_IO_HANDLER_H_
6#define BASE_ASYNC_SOCKET_IO_HANDLER_H_
[email protected]a0e3f0f2012-06-07 12:45:517
[email protected]5821fa0e2013-07-18 04:32:358#include "base/message_loop/message_loop.h"
[email protected]a0e3f0f2012-06-07 12:45:519#include "base/sync_socket.h"
10#include "base/threading/non_thread_safe.h"
[email protected]a0e3f0f2012-06-07 12:45:5111
12namespace media {
13
14// The message loop callback interface is different based on platforms.
15#if defined(OS_WIN)
[email protected]fb5af232013-04-22 22:40:0316typedef base::MessageLoopForIO::IOHandler MessageLoopIOHandler;
[email protected]a0e3f0f2012-06-07 12:45:5117#elif defined(OS_POSIX)
[email protected]fb5af232013-04-22 22:40:0318typedef base::MessageLoopForIO::Watcher MessageLoopIOHandler;
[email protected]a0e3f0f2012-06-07 12:45:5119#endif
20
21// Extends the CancelableSyncSocket class to allow reading from a socket
22// asynchronously on a TYPE_IO message loop thread. This makes it easy to share
23// a thread that uses a message loop (e.g. for IPC and other things) and not
24// require a separate thread to read from the socket.
25//
26// Example usage (also see the unit tests):
27//
28// class SocketReader {
29// public:
30// SocketReader(base::CancelableSyncSocket* socket)
31// : socket_(socket), buffer_() {
[email protected]26195ea2012-07-04 13:34:2132// io_handler.Initialize(socket_->handle(),
33// base::Bind(&SocketReader::OnDataAvailable,
34// base::Unretained(this));
[email protected]a0e3f0f2012-06-07 12:45:5135// }
36//
37// void AsyncRead() {
[email protected]26195ea2012-07-04 13:34:2138// CHECK(io_handler.Read(&buffer_[0], sizeof(buffer_)));
[email protected]a0e3f0f2012-06-07 12:45:5139// }
40//
41// private:
42// void OnDataAvailable(int bytes_read) {
[email protected]26195ea2012-07-04 13:34:2143// if (ProcessData(&buffer_[0], bytes_read)) {
44// // Issue another read.
45// CHECK(io_handler.Read(&buffer_[0], sizeof(buffer_)));
46// }
[email protected]a0e3f0f2012-06-07 12:45:5147// }
48//
49// media::AsyncSocketIoHandler io_handler;
50// base::CancelableSyncSocket* socket_;
51// char buffer_[kBufferSize];
52// };
53//
[email protected]39cb64f2013-08-22 12:39:3354class BASE_EXPORT AsyncSocketIoHandler
[email protected]00994922012-06-07 12:59:5055 : public NON_EXPORTED_BASE(base::NonThreadSafe),
56 public NON_EXPORTED_BASE(MessageLoopIOHandler) {
[email protected]a0e3f0f2012-06-07 12:45:5157 public:
58 AsyncSocketIoHandler();
59 virtual ~AsyncSocketIoHandler();
60
[email protected]a0e3f0f2012-06-07 12:45:5161 // Type definition for the callback. The parameter tells how many
62 // bytes were read and is 0 if an error occurred.
63 typedef base::Callback<void(int)> ReadCompleteCallback;
64
[email protected]26195ea2012-07-04 13:34:2165 // Initializes the AsyncSocketIoHandler by hooking it up to the current
66 // thread's message loop (must be TYPE_IO), to do async reads from the socket
67 // on the current thread. The |callback| will be invoked whenever a Read()
68 // has completed.
69 bool Initialize(base::SyncSocket::Handle socket,
70 const ReadCompleteCallback& callback);
71
[email protected]a0e3f0f2012-06-07 12:45:5172 // Attempts to read from the socket. The return value will be |false|
73 // if an error occurred and |true| if data was read or a pending read
[email protected]26195ea2012-07-04 13:34:2174 // was issued. Regardless of async or sync operation, the
75 // ReadCompleteCallback (see above) will be called when data is available.
76 bool Read(char* buffer, int buffer_len);
[email protected]a0e3f0f2012-06-07 12:45:5177
78 private:
79#if defined(OS_WIN)
80 // Implementation of IOHandler on Windows.
[email protected]fb5af232013-04-22 22:40:0381 virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
[email protected]a0e3f0f2012-06-07 12:45:5182 DWORD bytes_transfered,
83 DWORD error) OVERRIDE;
84#elif defined(OS_POSIX)
[email protected]fb5af232013-04-22 22:40:0385 // Implementation of base::MessageLoopForIO::Watcher.
[email protected]a0e3f0f2012-06-07 12:45:5186 virtual void OnFileCanWriteWithoutBlocking(int socket) OVERRIDE {}
87 virtual void OnFileCanReadWithoutBlocking(int socket) OVERRIDE;
88
89 void EnsureWatchingSocket();
90#endif
91
92 base::SyncSocket::Handle socket_;
93#if defined(OS_WIN)
[email protected]fb5af232013-04-22 22:40:0394 base::MessageLoopForIO::IOContext* context_;
[email protected]26195ea2012-07-04 13:34:2195 bool is_pending_;
[email protected]a0e3f0f2012-06-07 12:45:5196#elif defined(OS_POSIX)
[email protected]fb5af232013-04-22 22:40:0397 base::MessageLoopForIO::FileDescriptorWatcher socket_watcher_;
[email protected]a0e3f0f2012-06-07 12:45:5198 // |pending_buffer_| and |pending_buffer_len_| are valid only between
99 // Read() and OnFileCanReadWithoutBlocking().
100 char* pending_buffer_;
101 int pending_buffer_len_;
102 // |true| iff the message loop is watching the socket for IO events.
103 bool is_watching_;
104#endif
105 ReadCompleteCallback read_complete_;
106
107 DISALLOW_COPY_AND_ASSIGN(AsyncSocketIoHandler);
108};
109
110} // namespace media.
111
[email protected]39cb64f2013-08-22 12:39:33112#endif // BASE_ASYNC_SOCKET_IO_HANDLER_H_