Home | History | Annotate | Download | only in audio
      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