diff options
author | qsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-22 12:39:33 +0000 |
---|---|---|
committer | qsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-22 12:39:33 +0000 |
commit | 39cb64f5ad4bfaebf5edcab4d0ae0bbecd697e00 (patch) | |
tree | 42b90c16359867fc483ab02fb32bc49875f70789 /base/async_socket_io_handler.h | |
parent | 7794f0f531df0cd2b8232bfc40e52d785ee0ecf6 (diff) | |
download | chromium_src-39cb64f5ad4bfaebf5edcab4d0ae0bbecd697e00.zip chromium_src-39cb64f5ad4bfaebf5edcab4d0ae0bbecd697e00.tar.gz chromium_src-39cb64f5ad4bfaebf5edcab4d0ae0bbecd697e00.tar.bz2 |
Move async_socket_io_handler.* from media/ to base/
TBR=darin
Review URL: https://chromiumcodereview.appspot.com/23137015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@219000 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/async_socket_io_handler.h')
-rw-r--r-- | base/async_socket_io_handler.h | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/base/async_socket_io_handler.h b/base/async_socket_io_handler.h new file mode 100644 index 0000000..562ae25 --- /dev/null +++ b/base/async_socket_io_handler.h @@ -0,0 +1,112 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_ASYNC_SOCKET_IO_HANDLER_H_ +#define BASE_ASYNC_SOCKET_IO_HANDLER_H_ + +#include "base/message_loop/message_loop.h" +#include "base/sync_socket.h" +#include "base/threading/non_thread_safe.h" + +namespace media { + +// The message loop callback interface is different based on platforms. +#if defined(OS_WIN) +typedef base::MessageLoopForIO::IOHandler MessageLoopIOHandler; +#elif defined(OS_POSIX) +typedef base::MessageLoopForIO::Watcher MessageLoopIOHandler; +#endif + +// Extends the CancelableSyncSocket class to allow reading from a socket +// asynchronously on a TYPE_IO message loop thread. This makes it easy to share +// a thread that uses a message loop (e.g. for IPC and other things) and not +// require a separate thread to read from the socket. +// +// Example usage (also see the unit tests): +// +// class SocketReader { +// public: +// SocketReader(base::CancelableSyncSocket* socket) +// : socket_(socket), buffer_() { +// io_handler.Initialize(socket_->handle(), +// base::Bind(&SocketReader::OnDataAvailable, +// base::Unretained(this)); +// } +// +// void AsyncRead() { +// CHECK(io_handler.Read(&buffer_[0], sizeof(buffer_))); +// } +// +// private: +// void OnDataAvailable(int bytes_read) { +// if (ProcessData(&buffer_[0], bytes_read)) { +// // Issue another read. +// CHECK(io_handler.Read(&buffer_[0], sizeof(buffer_))); +// } +// } +// +// media::AsyncSocketIoHandler io_handler; +// base::CancelableSyncSocket* socket_; +// char buffer_[kBufferSize]; +// }; +// +class BASE_EXPORT AsyncSocketIoHandler + : public NON_EXPORTED_BASE(base::NonThreadSafe), + public NON_EXPORTED_BASE(MessageLoopIOHandler) { + public: + AsyncSocketIoHandler(); + virtual ~AsyncSocketIoHandler(); + + // Type definition for the callback. The parameter tells how many + // bytes were read and is 0 if an error occurred. + typedef base::Callback<void(int)> ReadCompleteCallback; + + // Initializes the AsyncSocketIoHandler by hooking it up to the current + // thread's message loop (must be TYPE_IO), to do async reads from the socket + // on the current thread. The |callback| will be invoked whenever a Read() + // has completed. + bool Initialize(base::SyncSocket::Handle socket, + const ReadCompleteCallback& callback); + + // Attempts to read from the socket. The return value will be |false| + // if an error occurred and |true| if data was read or a pending read + // was issued. Regardless of async or sync operation, the + // ReadCompleteCallback (see above) will be called when data is available. + bool Read(char* buffer, int buffer_len); + + private: +#if defined(OS_WIN) + // Implementation of IOHandler on Windows. + virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context, + DWORD bytes_transfered, + DWORD error) OVERRIDE; +#elif defined(OS_POSIX) + // Implementation of base::MessageLoopForIO::Watcher. + virtual void OnFileCanWriteWithoutBlocking(int socket) OVERRIDE {} + virtual void OnFileCanReadWithoutBlocking(int socket) OVERRIDE; + + void EnsureWatchingSocket(); +#endif + + base::SyncSocket::Handle socket_; +#if defined(OS_WIN) + base::MessageLoopForIO::IOContext* context_; + bool is_pending_; +#elif defined(OS_POSIX) + base::MessageLoopForIO::FileDescriptorWatcher socket_watcher_; + // |pending_buffer_| and |pending_buffer_len_| are valid only between + // Read() and OnFileCanReadWithoutBlocking(). + char* pending_buffer_; + int pending_buffer_len_; + // |true| iff the message loop is watching the socket for IO events. + bool is_watching_; +#endif + ReadCompleteCallback read_complete_; + + DISALLOW_COPY_AND_ASSIGN(AsyncSocketIoHandler); +}; + +} // namespace media. + +#endif // BASE_ASYNC_SOCKET_IO_HANDLER_H_ |