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 #ifndef MEDIA_AUDIO_ASYNC_SOCKET_IO_HANDLER_H_ 6 #define MEDIA_AUDIO_ASYNC_SOCKET_IO_HANDLER_H_ 7 8 #include "base/message_loop/message_loop.h" 9 #include "base/sync_socket.h" 10 #include "base/threading/non_thread_safe.h" 11 #include "media/base/media_export.h" 12 13 namespace media { 14 15 // The message loop callback interface is different based on platforms. 16 #if defined(OS_WIN) 17 typedef base::MessageLoopForIO::IOHandler MessageLoopIOHandler; 18 #elif defined(OS_POSIX) 19 typedef base::MessageLoopForIO::Watcher MessageLoopIOHandler; 20 #endif 21 22 // Extends the CancelableSyncSocket class to allow reading from a socket 23 // asynchronously on a TYPE_IO message loop thread. This makes it easy to share 24 // a thread that uses a message loop (e.g. for IPC and other things) and not 25 // require a separate thread to read from the socket. 26 // 27 // Example usage (also see the unit tests): 28 // 29 // class SocketReader { 30 // public: 31 // SocketReader(base::CancelableSyncSocket* socket) 32 // : socket_(socket), buffer_() { 33 // io_handler.Initialize(socket_->handle(), 34 // base::Bind(&SocketReader::OnDataAvailable, 35 // base::Unretained(this)); 36 // } 37 // 38 // void AsyncRead() { 39 // CHECK(io_handler.Read(&buffer_[0], sizeof(buffer_))); 40 // } 41 // 42 // private: 43 // void OnDataAvailable(int bytes_read) { 44 // if (ProcessData(&buffer_[0], bytes_read)) { 45 // // Issue another read. 46 // CHECK(io_handler.Read(&buffer_[0], sizeof(buffer_))); 47 // } 48 // } 49 // 50 // media::AsyncSocketIoHandler io_handler; 51 // base::CancelableSyncSocket* socket_; 52 // char buffer_[kBufferSize]; 53 // }; 54 // 55 class MEDIA_EXPORT AsyncSocketIoHandler 56 : public NON_EXPORTED_BASE(base::NonThreadSafe), 57 public NON_EXPORTED_BASE(MessageLoopIOHandler) { 58 public: 59 AsyncSocketIoHandler(); 60 virtual ~AsyncSocketIoHandler(); 61 62 // Type definition for the callback. The parameter tells how many 63 // bytes were read and is 0 if an error occurred. 64 typedef base::Callback<void(int)> ReadCompleteCallback; 65 66 // Initializes the AsyncSocketIoHandler by hooking it up to the current 67 // thread's message loop (must be TYPE_IO), to do async reads from the socket 68 // on the current thread. The |callback| will be invoked whenever a Read() 69 // has completed. 70 bool Initialize(base::SyncSocket::Handle socket, 71 const ReadCompleteCallback& callback); 72 73 // Attempts to read from the socket. The return value will be |false| 74 // if an error occurred and |true| if data was read or a pending read 75 // was issued. Regardless of async or sync operation, the 76 // ReadCompleteCallback (see above) will be called when data is available. 77 bool Read(char* buffer, int buffer_len); 78 79 private: 80 #if defined(OS_WIN) 81 // Implementation of IOHandler on Windows. 82 virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context, 83 DWORD bytes_transfered, 84 DWORD error) OVERRIDE; 85 #elif defined(OS_POSIX) 86 // Implementation of base::MessageLoopForIO::Watcher. 87 virtual void OnFileCanWriteWithoutBlocking(int socket) OVERRIDE {} 88 virtual void OnFileCanReadWithoutBlocking(int socket) OVERRIDE; 89 90 void EnsureWatchingSocket(); 91 #endif 92 93 base::SyncSocket::Handle socket_; 94 #if defined(OS_WIN) 95 base::MessageLoopForIO::IOContext* context_; 96 bool is_pending_; 97 #elif defined(OS_POSIX) 98 base::MessageLoopForIO::FileDescriptorWatcher socket_watcher_; 99 // |pending_buffer_| and |pending_buffer_len_| are valid only between 100 // Read() and OnFileCanReadWithoutBlocking(). 101 char* pending_buffer_; 102 int pending_buffer_len_; 103 // |true| iff the message loop is watching the socket for IO events. 104 bool is_watching_; 105 #endif 106 ReadCompleteCallback read_complete_; 107 108 DISALLOW_COPY_AND_ASSIGN(AsyncSocketIoHandler); 109 }; 110 111 } // namespace media. 112 113 #endif // MEDIA_AUDIO_ASYNC_SOCKET_IO_HANDLER_H_ 114