147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_ASYNCSOCKET_H_
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_ASYNCSOCKET_H_
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h"
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/sigslot.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socket.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO: Remove Socket and rename AsyncSocket to Socket.
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Provides the ability to perform socket I/O asynchronously.
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass AsyncSocket : public Socket {
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket();
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~AsyncSocket();
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual AsyncSocket* Accept(SocketAddress* paddr) = 0;
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // SignalReadEvent and SignalWriteEvent use multi_threaded_local to allow
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // access concurrently from different thread.
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // For example SignalReadEvent::connect will be called in AsyncUDPSocket ctor
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // but at the same time the SocketDispatcher maybe signaling the read event.
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // ready to read
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal1<AsyncSocket*,
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   sigslot::multi_threaded_local> SignalReadEvent;
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // ready to write
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal1<AsyncSocket*,
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   sigslot::multi_threaded_local> SignalWriteEvent;
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal1<AsyncSocket*> SignalConnectEvent;     // connected
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal2<AsyncSocket*, int> SignalCloseEvent;  // closed
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass AsyncSocketAdapter : public AsyncSocket, public sigslot::has_slots<> {
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The adapted socket may explicitly be NULL, and later assigned using Attach.
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // However, subclasses which support detached mode must override any methods
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // that will be called during the detached period (usually GetState()), to
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // avoid dereferencing a null pointer.
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit AsyncSocketAdapter(AsyncSocket* socket);
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~AsyncSocketAdapter();
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Attach(AsyncSocket* socket);
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual SocketAddress GetLocalAddress() const {
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->GetLocalAddress();
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual SocketAddress GetRemoteAddress() const {
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->GetRemoteAddress();
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Bind(const SocketAddress& addr) {
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Bind(addr);
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Connect(const SocketAddress& addr) {
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Connect(addr);
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Send(const void* pv, size_t cb) {
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Send(pv, cb);
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) {
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->SendTo(pv, cb, addr);
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Recv(void* pv, size_t cb) {
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Recv(pv, cb);
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr) {
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->RecvFrom(pv, cb, paddr);
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Listen(int backlog) {
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Listen(backlog);
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual AsyncSocket* Accept(SocketAddress* paddr) {
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Accept(paddr);
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Close() {
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->Close();
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int GetError() const {
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->GetError();
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void SetError(int error) {
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->SetError(error);
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ConnState GetState() const {
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->GetState();
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int EstimateMTU(uint16* mtu) {
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->EstimateMTU(mtu);
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int GetOption(Option opt, int* value) {
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->GetOption(opt, value);
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int SetOption(Option opt, int value) {
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return socket_->SetOption(opt, value);
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected:
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void OnConnectEvent(AsyncSocket* socket) {
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalConnectEvent(this);
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void OnReadEvent(AsyncSocket* socket) {
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalReadEvent(this);
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void OnWriteEvent(AsyncSocket* socket) {
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalWriteEvent(this);
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void OnCloseEvent(AsyncSocket* socket, int err) {
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalCloseEvent(this, err);
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* socket_;
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_BASE_ASYNCSOCKET_H_
125