Delete macsocketserver.h and related files.
BUG=webrtc:6424 Review-Url: https://codereview.webrtc.org/2369013002 Cr-Commit-Position: refs/heads/master@{#14571}
This commit is contained in:
parent
df494b0908
commit
c7901c6491
@ -773,9 +773,6 @@ if (rtc_include_tests) {
|
||||
shard_timeout = 900
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
sources += [ "base/macsocketserver_unittest.cc" ]
|
||||
}
|
||||
if (is_clang) {
|
||||
# Suppress warnings from the Chromium Clang plugin.
|
||||
# See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
|
||||
|
||||
@ -582,12 +582,6 @@ rtc_static_library("rtc_base") {
|
||||
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"macasyncsocket.cc",
|
||||
"macasyncsocket.h",
|
||||
"maccocoasocketserver.h",
|
||||
"maccocoasocketserver.mm",
|
||||
"macsocketserver.cc",
|
||||
"macsocketserver.h",
|
||||
"macwindowpicker.cc",
|
||||
"macwindowpicker.h",
|
||||
]
|
||||
|
||||
@ -474,12 +474,6 @@
|
||||
}],
|
||||
['OS=="mac"', {
|
||||
'sources': [
|
||||
'macasyncsocket.cc',
|
||||
'macasyncsocket.h',
|
||||
'maccocoasocketserver.h',
|
||||
'maccocoasocketserver.mm',
|
||||
'macsocketserver.cc',
|
||||
'macsocketserver.h',
|
||||
'macwindowpicker.cc',
|
||||
'macwindowpicker.h',
|
||||
],
|
||||
|
||||
@ -1,485 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
//
|
||||
// MacAsyncSocket is a kind of AsyncSocket. It does not support the SOCK_DGRAM
|
||||
// type (yet). It works asynchronously, which means that users of this socket
|
||||
// should connect to the various events declared in asyncsocket.h to receive
|
||||
// notifications about this socket. It uses CFSockets for signals, but prefers
|
||||
// the basic bsd socket operations rather than their CFSocket wrappers when
|
||||
// possible.
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "webrtc/base/macasyncsocket.h"
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/macsocketserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
static const int kCallbackFlags = kCFSocketReadCallBack |
|
||||
kCFSocketConnectCallBack |
|
||||
kCFSocketWriteCallBack;
|
||||
|
||||
MacAsyncSocket::MacAsyncSocket(MacBaseSocketServer* ss, int family)
|
||||
: ss_(ss),
|
||||
socket_(NULL),
|
||||
native_socket_(INVALID_SOCKET),
|
||||
source_(NULL),
|
||||
current_callbacks_(0),
|
||||
disabled_(false),
|
||||
error_(0),
|
||||
state_(CS_CLOSED),
|
||||
resolver_(NULL) {
|
||||
Initialize(family);
|
||||
}
|
||||
|
||||
MacAsyncSocket::~MacAsyncSocket() {
|
||||
Close();
|
||||
}
|
||||
|
||||
// Returns the address to which the socket is bound. If the socket is not
|
||||
// bound, then the any-address is returned.
|
||||
SocketAddress MacAsyncSocket::GetLocalAddress() const {
|
||||
SocketAddress address;
|
||||
|
||||
// The CFSocket doesn't pick up on implicit binds from the connect call.
|
||||
// Calling bind in before connect explicitly causes errors, so just query
|
||||
// the underlying bsd socket.
|
||||
sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
int result = ::getsockname(native_socket_,
|
||||
reinterpret_cast<sockaddr*>(&addr), &addrlen);
|
||||
if (result >= 0) {
|
||||
SocketAddressFromSockAddrStorage(addr, &address);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
// Returns the address to which the socket is connected. If the socket is not
|
||||
// connected, then the any-address is returned.
|
||||
SocketAddress MacAsyncSocket::GetRemoteAddress() const {
|
||||
SocketAddress address;
|
||||
|
||||
// Use native_socket for consistency with GetLocalAddress.
|
||||
sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
int result = ::getpeername(native_socket_,
|
||||
reinterpret_cast<sockaddr*>(&addr), &addrlen);
|
||||
if (result >= 0) {
|
||||
SocketAddressFromSockAddrStorage(addr, &address);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
// Bind the socket to a local address.
|
||||
int MacAsyncSocket::Bind(const SocketAddress& address) {
|
||||
sockaddr_storage saddr = {0};
|
||||
size_t len = address.ToSockAddrStorage(&saddr);
|
||||
int err = ::bind(native_socket_, reinterpret_cast<sockaddr*>(&saddr), len);
|
||||
if (err == SOCKET_ERROR) error_ = errno;
|
||||
return err;
|
||||
}
|
||||
|
||||
void MacAsyncSocket::OnResolveResult(SignalThread* thread) {
|
||||
if (thread != resolver_) {
|
||||
return;
|
||||
}
|
||||
int error = resolver_->GetError();
|
||||
if (error == 0) {
|
||||
error = DoConnect(resolver_->address());
|
||||
} else {
|
||||
Close();
|
||||
}
|
||||
if (error) {
|
||||
error_ = error;
|
||||
SignalCloseEvent(this, error_);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect to a remote address.
|
||||
int MacAsyncSocket::Connect(const SocketAddress& addr) {
|
||||
// TODO(djw): Consolidate all the connect->resolve->doconnect implementations.
|
||||
if (state_ != CS_CLOSED) {
|
||||
SetError(EALREADY);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
if (addr.IsUnresolvedIP()) {
|
||||
LOG(LS_VERBOSE) << "Resolving addr in MacAsyncSocket::Connect";
|
||||
resolver_ = new AsyncResolver();
|
||||
resolver_->SignalWorkDone.connect(this,
|
||||
&MacAsyncSocket::OnResolveResult);
|
||||
resolver_->Start(addr);
|
||||
state_ = CS_CONNECTING;
|
||||
return 0;
|
||||
}
|
||||
return DoConnect(addr);
|
||||
}
|
||||
|
||||
int MacAsyncSocket::DoConnect(const SocketAddress& addr) {
|
||||
if (!valid()) {
|
||||
Initialize(addr.family());
|
||||
if (!valid())
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
sockaddr_storage saddr;
|
||||
size_t len = addr.ToSockAddrStorage(&saddr);
|
||||
int result = ::connect(native_socket_, reinterpret_cast<sockaddr*>(&saddr),
|
||||
len);
|
||||
|
||||
if (result != SOCKET_ERROR) {
|
||||
state_ = CS_CONNECTED;
|
||||
} else {
|
||||
error_ = errno;
|
||||
if (error_ == EINPROGRESS) {
|
||||
state_ = CS_CONNECTING;
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Send to the remote end we're connected to.
|
||||
int MacAsyncSocket::Send(const void* buffer, size_t length) {
|
||||
if (!valid()) {
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
int sent = ::send(native_socket_, buffer, length, 0);
|
||||
|
||||
if (sent == SOCKET_ERROR) {
|
||||
error_ = errno;
|
||||
|
||||
if (IsBlocking()) {
|
||||
// Reenable the writable callback (once), since we are flow controlled.
|
||||
CFSocketEnableCallBacks(socket_, kCallbackFlags);
|
||||
current_callbacks_ = kCallbackFlags;
|
||||
}
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
// Send to the given address. We may or may not be connected to anyone.
|
||||
int MacAsyncSocket::SendTo(const void* buffer, size_t length,
|
||||
const SocketAddress& address) {
|
||||
if (!valid()) {
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
sockaddr_storage saddr;
|
||||
size_t len = address.ToSockAddrStorage(&saddr);
|
||||
int sent = ::sendto(native_socket_, buffer, length, 0,
|
||||
reinterpret_cast<sockaddr*>(&saddr), len);
|
||||
|
||||
if (sent == SOCKET_ERROR) {
|
||||
error_ = errno;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
// Read data received from the remote end we're connected to.
|
||||
int MacAsyncSocket::Recv(void* buffer, size_t length, int64_t* timestamp) {
|
||||
if (timestamp) {
|
||||
*timestamp = -1;
|
||||
}
|
||||
int received = ::recv(native_socket_, reinterpret_cast<char*>(buffer),
|
||||
length, 0);
|
||||
if (received == SOCKET_ERROR) error_ = errno;
|
||||
|
||||
// Recv should only be called when there is data to read
|
||||
ASSERT((received != 0) || (length == 0));
|
||||
return received;
|
||||
}
|
||||
|
||||
// Read data received from any remote party
|
||||
int MacAsyncSocket::RecvFrom(void* buffer,
|
||||
size_t length,
|
||||
SocketAddress* out_addr,
|
||||
int64_t* timestamp) {
|
||||
if (timestamp) {
|
||||
*timestamp = -1;
|
||||
}
|
||||
sockaddr_storage saddr;
|
||||
socklen_t addr_len = sizeof(saddr);
|
||||
int received = ::recvfrom(native_socket_, reinterpret_cast<char*>(buffer),
|
||||
length, 0, reinterpret_cast<sockaddr*>(&saddr),
|
||||
&addr_len);
|
||||
if (received >= 0 && out_addr != NULL) {
|
||||
SocketAddressFromSockAddrStorage(saddr, out_addr);
|
||||
} else if (received == SOCKET_ERROR) {
|
||||
error_ = errno;
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
int MacAsyncSocket::Listen(int backlog) {
|
||||
if (!valid()) {
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
int res = ::listen(native_socket_, backlog);
|
||||
if (res != SOCKET_ERROR)
|
||||
state_ = CS_CONNECTING;
|
||||
else
|
||||
error_ = errno;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
MacAsyncSocket* MacAsyncSocket::Accept(SocketAddress* out_addr) {
|
||||
sockaddr_storage saddr;
|
||||
socklen_t addr_len = sizeof(saddr);
|
||||
|
||||
int socket_fd = ::accept(native_socket_, reinterpret_cast<sockaddr*>(&saddr),
|
||||
&addr_len);
|
||||
if (socket_fd == INVALID_SOCKET) {
|
||||
error_ = errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MacAsyncSocket* s = new MacAsyncSocket(ss_, saddr.ss_family, socket_fd);
|
||||
if (s && s->valid()) {
|
||||
s->state_ = CS_CONNECTED;
|
||||
if (out_addr)
|
||||
SocketAddressFromSockAddrStorage(saddr, out_addr);
|
||||
} else {
|
||||
delete s;
|
||||
s = NULL;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int MacAsyncSocket::Close() {
|
||||
if (source_ != NULL) {
|
||||
CFRunLoopSourceInvalidate(source_);
|
||||
CFRelease(source_);
|
||||
if (ss_) ss_->UnregisterSocket(this);
|
||||
source_ = NULL;
|
||||
}
|
||||
|
||||
if (socket_ != NULL) {
|
||||
CFSocketInvalidate(socket_);
|
||||
CFRelease(socket_);
|
||||
socket_ = NULL;
|
||||
}
|
||||
|
||||
if (resolver_) {
|
||||
resolver_->Destroy(false);
|
||||
resolver_ = NULL;
|
||||
}
|
||||
|
||||
native_socket_ = INVALID_SOCKET; // invalidates the socket
|
||||
error_ = 0;
|
||||
state_ = CS_CLOSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MacAsyncSocket::EstimateMTU(uint16_t* mtu) {
|
||||
ASSERT(false && "NYI");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MacAsyncSocket::GetError() const {
|
||||
return error_;
|
||||
}
|
||||
|
||||
void MacAsyncSocket::SetError(int error) {
|
||||
error_ = error;
|
||||
}
|
||||
|
||||
Socket::ConnState MacAsyncSocket::GetState() const {
|
||||
return state_;
|
||||
}
|
||||
|
||||
int MacAsyncSocket::GetOption(Option opt, int* value) {
|
||||
ASSERT(false && "NYI");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MacAsyncSocket::SetOption(Option opt, int value) {
|
||||
ASSERT(false && "NYI");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MacAsyncSocket::EnableCallbacks() {
|
||||
if (valid()) {
|
||||
disabled_ = false;
|
||||
CFSocketEnableCallBacks(socket_, current_callbacks_);
|
||||
}
|
||||
}
|
||||
|
||||
void MacAsyncSocket::DisableCallbacks() {
|
||||
if (valid()) {
|
||||
disabled_ = true;
|
||||
CFSocketDisableCallBacks(socket_, kCallbackFlags);
|
||||
}
|
||||
}
|
||||
|
||||
MacAsyncSocket::MacAsyncSocket(MacBaseSocketServer* ss, int family,
|
||||
int native_socket)
|
||||
: ss_(ss),
|
||||
socket_(NULL),
|
||||
native_socket_(native_socket),
|
||||
source_(NULL),
|
||||
current_callbacks_(0),
|
||||
disabled_(false),
|
||||
error_(0),
|
||||
state_(CS_CLOSED),
|
||||
resolver_(NULL) {
|
||||
Initialize(family);
|
||||
}
|
||||
|
||||
// Create a new socket, wrapping the native socket if provided or creating one
|
||||
// otherwise. In case of any failure, consume the native socket. We assume the
|
||||
// wrapped socket is in the closed state. If this is not the case you must
|
||||
// update the state_ field for this socket yourself.
|
||||
void MacAsyncSocket::Initialize(int family) {
|
||||
CFSocketContext ctx = { 0 };
|
||||
ctx.info = this;
|
||||
|
||||
// First create the CFSocket
|
||||
CFSocketRef cf_socket = NULL;
|
||||
bool res = false;
|
||||
if (native_socket_ == INVALID_SOCKET) {
|
||||
cf_socket = CFSocketCreate(kCFAllocatorDefault,
|
||||
family, SOCK_STREAM, IPPROTO_TCP,
|
||||
kCallbackFlags, MacAsyncSocketCallBack, &ctx);
|
||||
} else {
|
||||
cf_socket = CFSocketCreateWithNative(kCFAllocatorDefault,
|
||||
native_socket_, kCallbackFlags,
|
||||
MacAsyncSocketCallBack, &ctx);
|
||||
}
|
||||
|
||||
if (cf_socket) {
|
||||
res = true;
|
||||
socket_ = cf_socket;
|
||||
native_socket_ = CFSocketGetNative(cf_socket);
|
||||
current_callbacks_ = kCallbackFlags;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
// Make the underlying socket asynchronous
|
||||
res = (-1 != ::fcntl(native_socket_, F_SETFL,
|
||||
::fcntl(native_socket_, F_GETFL, 0) | O_NONBLOCK));
|
||||
}
|
||||
|
||||
if (res) {
|
||||
// Add this socket to the run loop, at priority 1 so that it will be
|
||||
// queued behind any pending signals.
|
||||
source_ = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 1);
|
||||
res = (source_ != NULL);
|
||||
if (!res) errno = EINVAL;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
if (ss_) ss_->RegisterSocket(this);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
int error = errno;
|
||||
Close(); // Clears error_.
|
||||
error_ = error;
|
||||
}
|
||||
}
|
||||
|
||||
// Call CFRelease on the result when done using it
|
||||
CFDataRef MacAsyncSocket::CopyCFAddress(const SocketAddress& address) {
|
||||
sockaddr_storage saddr;
|
||||
size_t len = address.ToSockAddrStorage(&saddr);
|
||||
|
||||
const UInt8* bytes = reinterpret_cast<UInt8*>(&saddr);
|
||||
|
||||
CFDataRef cf_address = CFDataCreate(kCFAllocatorDefault,
|
||||
bytes, len);
|
||||
|
||||
ASSERT(cf_address != NULL);
|
||||
return cf_address;
|
||||
}
|
||||
|
||||
void MacAsyncSocket::MacAsyncSocketCallBack(CFSocketRef s,
|
||||
CFSocketCallBackType callbackType,
|
||||
CFDataRef address,
|
||||
const void* data,
|
||||
void* info) {
|
||||
MacAsyncSocket* this_socket =
|
||||
reinterpret_cast<MacAsyncSocket*>(info);
|
||||
ASSERT(this_socket != NULL && this_socket->socket_ == s);
|
||||
|
||||
// Don't signal any socket messages if the socketserver is not listening on
|
||||
// them. When we are reenabled they will be requeued and will fire again.
|
||||
if (this_socket->disabled_)
|
||||
return;
|
||||
|
||||
switch (callbackType) {
|
||||
case kCFSocketReadCallBack:
|
||||
// This callback is invoked in one of 3 situations:
|
||||
// 1. A new connection is waiting to be accepted.
|
||||
// 2. The remote end closed the connection (a recv will return 0).
|
||||
// 3. Data is available to read.
|
||||
// 4. The connection closed unhappily (recv will return -1).
|
||||
if (this_socket->state_ == CS_CONNECTING) {
|
||||
// Case 1.
|
||||
this_socket->SignalReadEvent(this_socket);
|
||||
} else {
|
||||
char ch, amt;
|
||||
amt = ::recv(this_socket->native_socket_, &ch, 1, MSG_PEEK);
|
||||
if (amt == 0) {
|
||||
// Case 2.
|
||||
this_socket->state_ = CS_CLOSED;
|
||||
|
||||
// Disable additional callbacks or we will signal close twice.
|
||||
CFSocketDisableCallBacks(this_socket->socket_, kCFSocketReadCallBack);
|
||||
this_socket->current_callbacks_ &= ~kCFSocketReadCallBack;
|
||||
this_socket->SignalCloseEvent(this_socket, 0);
|
||||
} else if (amt > 0) {
|
||||
// Case 3.
|
||||
this_socket->SignalReadEvent(this_socket);
|
||||
} else {
|
||||
// Case 4.
|
||||
int error = errno;
|
||||
if (error == EAGAIN) {
|
||||
// Observed in practice. Let's hope it's a spurious or out of date
|
||||
// signal, since we just eat it.
|
||||
} else {
|
||||
this_socket->error_ = error;
|
||||
this_socket->SignalCloseEvent(this_socket, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kCFSocketConnectCallBack:
|
||||
if (data != NULL) {
|
||||
// An error occured in the background while connecting
|
||||
this_socket->error_ = errno;
|
||||
this_socket->state_ = CS_CLOSED;
|
||||
this_socket->SignalCloseEvent(this_socket, this_socket->error_);
|
||||
} else {
|
||||
this_socket->state_ = CS_CONNECTED;
|
||||
this_socket->SignalConnectEvent(this_socket);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCFSocketWriteCallBack:
|
||||
// Update our callback tracking. Write doesn't reenable, so it's off now.
|
||||
this_socket->current_callbacks_ &= ~kCFSocketWriteCallBack;
|
||||
this_socket->SignalWriteEvent(this_socket);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(false && "Invalid callback type for socket");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
// MacAsyncSocket is a kind of AsyncSocket. It only creates sockets
|
||||
// of the TCP type, and does not (yet) support listen and accept. It works
|
||||
// asynchronously, which means that users of this socket should connect to
|
||||
// the various events declared in asyncsocket.h to receive notifications about
|
||||
// this socket.
|
||||
|
||||
#ifndef WEBRTC_BASE_MACASYNCSOCKET_H__
|
||||
#define WEBRTC_BASE_MACASYNCSOCKET_H__
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include "webrtc/base/asyncsocket.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/nethelpers.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class MacBaseSocketServer;
|
||||
|
||||
class MacAsyncSocket : public AsyncSocket, public sigslot::has_slots<> {
|
||||
public:
|
||||
MacAsyncSocket(MacBaseSocketServer* ss, int family);
|
||||
~MacAsyncSocket() override;
|
||||
|
||||
bool valid() const { return source_ != NULL; }
|
||||
|
||||
// Socket interface
|
||||
SocketAddress GetLocalAddress() const override;
|
||||
SocketAddress GetRemoteAddress() const override;
|
||||
int Bind(const SocketAddress& addr) override;
|
||||
int Connect(const SocketAddress& addr) override;
|
||||
int Send(const void* buffer, size_t length) override;
|
||||
int SendTo(const void* buffer,
|
||||
size_t length,
|
||||
const SocketAddress& addr) override;
|
||||
int Recv(void* buffer, size_t length, int64_t* timestamp) override;
|
||||
int RecvFrom(void* buffer,
|
||||
size_t length,
|
||||
SocketAddress* out_addr,
|
||||
int64_t* timestamp) override;
|
||||
int Listen(int backlog) override;
|
||||
MacAsyncSocket* Accept(SocketAddress* out_addr) override;
|
||||
int Close() override;
|
||||
int GetError() const override;
|
||||
void SetError(int error) override;
|
||||
ConnState GetState() const override;
|
||||
int EstimateMTU(uint16_t* mtu) override;
|
||||
int GetOption(Option opt, int* value) override;
|
||||
int SetOption(Option opt, int value) override;
|
||||
|
||||
// For the MacBaseSocketServer to disable callbacks when process_io is false.
|
||||
void EnableCallbacks();
|
||||
void DisableCallbacks();
|
||||
|
||||
protected:
|
||||
void OnResolveResult(SignalThread* thread);
|
||||
int DoConnect(const SocketAddress& addr);
|
||||
|
||||
private:
|
||||
// Creates an async socket from an existing bsd socket
|
||||
MacAsyncSocket(MacBaseSocketServer* ss, int family, int native_socket);
|
||||
|
||||
// Attaches the socket to the CFRunloop and sets the wrapped bsd socket
|
||||
// to async mode
|
||||
void Initialize(int family);
|
||||
|
||||
// Translate the SocketAddress into a CFDataRef to pass to CF socket
|
||||
// functions. Caller must call CFRelease on the result when done.
|
||||
static CFDataRef CopyCFAddress(const SocketAddress& address);
|
||||
|
||||
// Callback for the underlying CFSocketRef.
|
||||
static void MacAsyncSocketCallBack(CFSocketRef s,
|
||||
CFSocketCallBackType callbackType,
|
||||
CFDataRef address,
|
||||
const void* data,
|
||||
void* info);
|
||||
|
||||
MacBaseSocketServer* ss_;
|
||||
CFSocketRef socket_;
|
||||
int native_socket_;
|
||||
CFRunLoopSourceRef source_;
|
||||
int current_callbacks_;
|
||||
bool disabled_;
|
||||
int error_;
|
||||
ConnState state_;
|
||||
AsyncResolver* resolver_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(MacAsyncSocket);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_MACASYNCSOCKET_H__
|
||||
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// A libjingle compatible SocketServer for OSX/iOS/Cocoa.
|
||||
|
||||
#ifndef WEBRTC_BASE_MACCOCOASOCKETSERVER_H_
|
||||
#define WEBRTC_BASE_MACCOCOASOCKETSERVER_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/macsocketserver.h"
|
||||
|
||||
#ifdef __OBJC__
|
||||
@class NSTimer, MacCocoaSocketServerHelperRtc;
|
||||
#else
|
||||
class NSTimer;
|
||||
class MacCocoaSocketServerHelperRtc;
|
||||
#endif
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// A socketserver implementation that wraps the main cocoa
|
||||
// application loop accessed through [NSApp run].
|
||||
class MacCocoaSocketServer : public MacBaseSocketServer {
|
||||
public:
|
||||
explicit MacCocoaSocketServer();
|
||||
~MacCocoaSocketServer() override;
|
||||
|
||||
bool Wait(int cms, bool process_io) override;
|
||||
void WakeUp() override;
|
||||
|
||||
private:
|
||||
MacCocoaSocketServerHelperRtc* helper_;
|
||||
NSTimer* timer_; // Weak.
|
||||
// The count of how many times we're inside the NSApplication main loop.
|
||||
int run_count_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(MacCocoaSocketServer);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_MACCOCOASOCKETSERVER_H_
|
||||
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#import "webrtc/base/maccocoasocketserver.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "webrtc/base/scoped_autorelease_pool.h"
|
||||
|
||||
// MacCocoaSocketServerHelperRtc serves as a delegate to NSMachPort or a target for
|
||||
// a timeout.
|
||||
@interface MacCocoaSocketServerHelperRtc : NSObject {
|
||||
// This is a weak reference. This works fine since the
|
||||
// rtc::MacCocoaSocketServer owns this object.
|
||||
rtc::MacCocoaSocketServer* socketServer_; // Weak.
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MacCocoaSocketServerHelperRtc
|
||||
- (id)initWithSocketServer:(rtc::MacCocoaSocketServer*)ss {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
socketServer_ = ss;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)timerFired:(NSTimer*)timer {
|
||||
socketServer_->WakeUp();
|
||||
}
|
||||
|
||||
- (void)breakMainloop {
|
||||
[NSApp stop:self];
|
||||
// NSApp stop only exits after finishing processing of the
|
||||
// current event. Since we're potentially in a timer callback
|
||||
// and not an NSEvent handler, we need to trigger a dummy one
|
||||
// and turn the loop over. We may be able to skip this if we're
|
||||
// on the ss' thread and not inside the app loop already.
|
||||
NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined
|
||||
location:NSMakePoint(0,0)
|
||||
modifierFlags:0
|
||||
timestamp:0
|
||||
windowNumber:0
|
||||
context:nil
|
||||
subtype:0
|
||||
data1:0
|
||||
data2:0];
|
||||
[NSApp postEvent:event atStart:NO];
|
||||
}
|
||||
@end
|
||||
|
||||
namespace rtc {
|
||||
|
||||
MacCocoaSocketServer::MacCocoaSocketServer() {
|
||||
helper_ = [[MacCocoaSocketServerHelperRtc alloc] initWithSocketServer:this];
|
||||
timer_ = nil;
|
||||
run_count_ = 0;
|
||||
|
||||
// Initialize the shared NSApplication
|
||||
[NSApplication sharedApplication];
|
||||
}
|
||||
|
||||
MacCocoaSocketServer::~MacCocoaSocketServer() {
|
||||
[timer_ invalidate];
|
||||
[timer_ release];
|
||||
[helper_ release];
|
||||
}
|
||||
|
||||
// ::Wait is reentrant, for example when blocking on another thread while
|
||||
// responding to I/O. Calls to [NSApp] MUST be made from the main thread
|
||||
// only!
|
||||
bool MacCocoaSocketServer::Wait(int cms, bool process_io) {
|
||||
rtc::ScopedAutoreleasePool pool;
|
||||
if (!process_io && cms == 0) {
|
||||
// No op.
|
||||
return true;
|
||||
}
|
||||
if ([NSApp isRunning]) {
|
||||
// Only allow reentrant waiting if we're in a blocking send.
|
||||
ASSERT(!process_io && cms == kForever);
|
||||
}
|
||||
|
||||
if (!process_io) {
|
||||
// No way to listen to common modes and not get socket events, unless
|
||||
// we disable each one's callbacks.
|
||||
EnableSocketCallbacks(false);
|
||||
}
|
||||
|
||||
if (kForever != cms) {
|
||||
// Install a timer that fires wakeup after cms has elapsed.
|
||||
timer_ =
|
||||
[NSTimer scheduledTimerWithTimeInterval:cms / 1000.0
|
||||
target:helper_
|
||||
selector:@selector(timerFired:)
|
||||
userInfo:nil
|
||||
repeats:NO];
|
||||
[timer_ retain];
|
||||
}
|
||||
|
||||
// Run until WakeUp is called, which will call stop and exit this loop.
|
||||
run_count_++;
|
||||
[NSApp run];
|
||||
run_count_--;
|
||||
|
||||
if (!process_io) {
|
||||
// Reenable them. Hopefully this won't cause spurious callbacks or
|
||||
// missing ones while they were disabled.
|
||||
EnableSocketCallbacks(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can be called from any thread. Post a message back to the main thread to
|
||||
// break out of the NSApp loop.
|
||||
void MacCocoaSocketServer::WakeUp() {
|
||||
if (timer_ != nil) {
|
||||
[timer_ invalidate];
|
||||
[timer_ release];
|
||||
timer_ = nil;
|
||||
}
|
||||
|
||||
// [NSApp isRunning] returns unexpected results when called from another
|
||||
// thread. Maintain our own count of how many times to break the main loop.
|
||||
if (run_count_ > 0) {
|
||||
[helper_ performSelectorOnMainThread:@selector(breakMainloop)
|
||||
withObject:nil
|
||||
waitUntilDone:false];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/base/maccocoasocketserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class WakeThread : public Thread {
|
||||
public:
|
||||
WakeThread(SocketServer* ss) : ss_(ss) {
|
||||
}
|
||||
virtual ~WakeThread() {
|
||||
Stop();
|
||||
}
|
||||
void Run() {
|
||||
ss_->WakeUp();
|
||||
}
|
||||
private:
|
||||
SocketServer* ss_;
|
||||
};
|
||||
|
||||
// Test that MacCocoaSocketServer::Wait works as expected.
|
||||
TEST(MacCocoaSocketServer, TestWait) {
|
||||
MacCocoaSocketServer server;
|
||||
uint32_t start = Time();
|
||||
server.Wait(1000, true);
|
||||
EXPECT_GE(TimeSince(start), 1000);
|
||||
}
|
||||
|
||||
// Test that MacCocoaSocketServer::Wakeup works as expected.
|
||||
TEST(MacCocoaSocketServer, TestWakeup) {
|
||||
MacCFSocketServer server;
|
||||
WakeThread thread(&server);
|
||||
uint32_t start = Time();
|
||||
thread.Start();
|
||||
server.Wait(10000, true);
|
||||
EXPECT_LT(TimeSince(start), 10000);
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
#include "webrtc/base/macsocketserver.h"
|
||||
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/macasyncsocket.h"
|
||||
#include "webrtc/base/macutils.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MacBaseSocketServer
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MacBaseSocketServer::MacBaseSocketServer() {
|
||||
}
|
||||
|
||||
MacBaseSocketServer::~MacBaseSocketServer() {
|
||||
}
|
||||
|
||||
Socket* MacBaseSocketServer::CreateSocket(int type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Socket* MacBaseSocketServer::CreateSocket(int family, int type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AsyncSocket* MacBaseSocketServer::CreateAsyncSocket(int type) {
|
||||
return CreateAsyncSocket(AF_INET, type);
|
||||
}
|
||||
|
||||
AsyncSocket* MacBaseSocketServer::CreateAsyncSocket(int family, int type) {
|
||||
if (SOCK_STREAM != type)
|
||||
return NULL;
|
||||
|
||||
MacAsyncSocket* socket = new MacAsyncSocket(this, family);
|
||||
if (!socket->valid()) {
|
||||
delete socket;
|
||||
return NULL;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
void MacBaseSocketServer::RegisterSocket(MacAsyncSocket* s) {
|
||||
sockets_.insert(s);
|
||||
}
|
||||
|
||||
void MacBaseSocketServer::UnregisterSocket(MacAsyncSocket* s) {
|
||||
VERIFY(1 == sockets_.erase(s)); // found 1
|
||||
}
|
||||
|
||||
bool MacBaseSocketServer::SetPosixSignalHandler(int signum,
|
||||
void (*handler)(int)) {
|
||||
Dispatcher* dispatcher = signal_dispatcher();
|
||||
if (!PhysicalSocketServer::SetPosixSignalHandler(signum, handler)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only register the FD once, when the first custom handler is installed.
|
||||
if (!dispatcher && (dispatcher = signal_dispatcher())) {
|
||||
CFFileDescriptorContext ctx = { 0 };
|
||||
ctx.info = this;
|
||||
|
||||
CFFileDescriptorRef desc = CFFileDescriptorCreate(
|
||||
kCFAllocatorDefault,
|
||||
dispatcher->GetDescriptor(),
|
||||
false,
|
||||
&MacBaseSocketServer::FileDescriptorCallback,
|
||||
&ctx);
|
||||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CFFileDescriptorEnableCallBacks(desc, kCFFileDescriptorReadCallBack);
|
||||
CFRunLoopSourceRef ref =
|
||||
CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, desc, 0);
|
||||
|
||||
if (!ref) {
|
||||
CFRelease(desc);
|
||||
return false;
|
||||
}
|
||||
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), ref, kCFRunLoopCommonModes);
|
||||
CFRelease(desc);
|
||||
CFRelease(ref);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Used to disable socket events from waking our message queue when
|
||||
// process_io is false. Does not disable signal event handling though.
|
||||
void MacBaseSocketServer::EnableSocketCallbacks(bool enable) {
|
||||
for (std::set<MacAsyncSocket*>::iterator it = sockets().begin();
|
||||
it != sockets().end(); ++it) {
|
||||
if (enable) {
|
||||
(*it)->EnableCallbacks();
|
||||
} else {
|
||||
(*it)->DisableCallbacks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MacBaseSocketServer::FileDescriptorCallback(CFFileDescriptorRef fd,
|
||||
CFOptionFlags flags,
|
||||
void* context) {
|
||||
MacBaseSocketServer* this_ss =
|
||||
reinterpret_cast<MacBaseSocketServer*>(context);
|
||||
ASSERT(this_ss);
|
||||
Dispatcher* signal_dispatcher = this_ss->signal_dispatcher();
|
||||
ASSERT(signal_dispatcher);
|
||||
|
||||
signal_dispatcher->OnPreEvent(DE_READ);
|
||||
signal_dispatcher->OnEvent(DE_READ, 0);
|
||||
CFFileDescriptorEnableCallBacks(fd, kCFFileDescriptorReadCallBack);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MacCFSocketServer
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void WakeUpCallback(void* info) {
|
||||
MacCFSocketServer* server = static_cast<MacCFSocketServer*>(info);
|
||||
ASSERT(NULL != server);
|
||||
server->OnWakeUpCallback();
|
||||
}
|
||||
|
||||
MacCFSocketServer::MacCFSocketServer()
|
||||
: run_loop_(CFRunLoopGetCurrent()),
|
||||
wake_up_(NULL) {
|
||||
CFRunLoopSourceContext ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.info = this;
|
||||
ctx.perform = &WakeUpCallback;
|
||||
wake_up_ = CFRunLoopSourceCreate(NULL, 0, &ctx);
|
||||
ASSERT(NULL != wake_up_);
|
||||
if (wake_up_) {
|
||||
CFRunLoopAddSource(run_loop_, wake_up_, kCFRunLoopCommonModes);
|
||||
}
|
||||
}
|
||||
|
||||
MacCFSocketServer::~MacCFSocketServer() {
|
||||
if (wake_up_) {
|
||||
CFRunLoopSourceInvalidate(wake_up_);
|
||||
CFRelease(wake_up_);
|
||||
}
|
||||
}
|
||||
|
||||
bool MacCFSocketServer::Wait(int cms, bool process_io) {
|
||||
ASSERT(CFRunLoopGetCurrent() == run_loop_);
|
||||
|
||||
if (!process_io && cms == 0) {
|
||||
// No op.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!process_io) {
|
||||
// No way to listen to common modes and not get socket events, unless
|
||||
// we disable each one's callbacks.
|
||||
EnableSocketCallbacks(false);
|
||||
}
|
||||
|
||||
SInt32 result;
|
||||
if (kForever == cms) {
|
||||
do {
|
||||
// Would prefer to run in a custom mode that only listens to wake_up,
|
||||
// but we have qtkit sending work to the main thread which is effectively
|
||||
// blocked here, causing deadlock. Thus listen to the common modes.
|
||||
// TODO: If QTKit becomes thread safe, do the above.
|
||||
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10000000, false);
|
||||
} while (result != kCFRunLoopRunFinished && result != kCFRunLoopRunStopped);
|
||||
} else {
|
||||
// TODO: In the case of 0ms wait, this will only process one event, so we
|
||||
// may want to loop until it returns TimedOut.
|
||||
CFTimeInterval seconds = cms / 1000.0;
|
||||
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, false);
|
||||
}
|
||||
|
||||
if (!process_io) {
|
||||
// Reenable them. Hopefully this won't cause spurious callbacks or
|
||||
// missing ones while they were disabled.
|
||||
EnableSocketCallbacks(true);
|
||||
}
|
||||
|
||||
if (kCFRunLoopRunFinished == result) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacCFSocketServer::WakeUp() {
|
||||
if (wake_up_) {
|
||||
CFRunLoopSourceSignal(wake_up_);
|
||||
CFRunLoopWakeUp(run_loop_);
|
||||
}
|
||||
}
|
||||
|
||||
void MacCFSocketServer::OnWakeUpCallback() {
|
||||
ASSERT(run_loop_ == CFRunLoopGetCurrent());
|
||||
CFRunLoopStop(run_loop_);
|
||||
}
|
||||
} // namespace rtc
|
||||
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef WEBRTC_BASE_MACSOCKETSERVER_H__
|
||||
#define WEBRTC_BASE_MACSOCKETSERVER_H__
|
||||
|
||||
#include <set>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "webrtc/base/physicalsocketserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MacBaseSocketServer
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class MacAsyncSocket;
|
||||
|
||||
class MacBaseSocketServer : public PhysicalSocketServer {
|
||||
public:
|
||||
MacBaseSocketServer();
|
||||
~MacBaseSocketServer() override;
|
||||
|
||||
// SocketServer Interface
|
||||
Socket* CreateSocket(int type) override;
|
||||
Socket* CreateSocket(int family, int type) override;
|
||||
|
||||
AsyncSocket* CreateAsyncSocket(int type) override;
|
||||
AsyncSocket* CreateAsyncSocket(int family, int type) override;
|
||||
|
||||
bool Wait(int cms, bool process_io) override = 0;
|
||||
void WakeUp() override = 0;
|
||||
|
||||
void RegisterSocket(MacAsyncSocket* socket);
|
||||
void UnregisterSocket(MacAsyncSocket* socket);
|
||||
|
||||
// PhysicalSocketServer Overrides
|
||||
bool SetPosixSignalHandler(int signum, void (*handler)(int)) override;
|
||||
|
||||
protected:
|
||||
void EnableSocketCallbacks(bool enable);
|
||||
const std::set<MacAsyncSocket*>& sockets() {
|
||||
return sockets_;
|
||||
}
|
||||
|
||||
private:
|
||||
static void FileDescriptorCallback(CFFileDescriptorRef ref,
|
||||
CFOptionFlags flags,
|
||||
void* context);
|
||||
|
||||
std::set<MacAsyncSocket*> sockets_;
|
||||
};
|
||||
|
||||
// Core Foundation implementation of the socket server. While idle it
|
||||
// will run the current CF run loop. When the socket server has work
|
||||
// to do the run loop will be paused. Does not support Carbon or Cocoa
|
||||
// UI interaction.
|
||||
class MacCFSocketServer : public MacBaseSocketServer {
|
||||
public:
|
||||
MacCFSocketServer();
|
||||
~MacCFSocketServer() override;
|
||||
|
||||
// SocketServer Interface
|
||||
bool Wait(int cms, bool process_io) override;
|
||||
void WakeUp() override;
|
||||
void OnWakeUpCallback();
|
||||
|
||||
private:
|
||||
CFRunLoopRef run_loop_;
|
||||
CFRunLoopSourceRef wake_up_;
|
||||
};
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_MACSOCKETSERVER_H__
|
||||
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/base/socket_unittest.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/base/macsocketserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class WakeThread : public Thread {
|
||||
public:
|
||||
WakeThread(SocketServer* ss) : ss_(ss) {
|
||||
}
|
||||
virtual ~WakeThread() {
|
||||
Stop();
|
||||
}
|
||||
void Run() {
|
||||
ss_->WakeUp();
|
||||
}
|
||||
private:
|
||||
SocketServer* ss_;
|
||||
};
|
||||
|
||||
// Test that MacAsyncSocket passes all the generic Socket tests.
|
||||
class MacAsyncSocketTest : public SocketTest {
|
||||
protected:
|
||||
MacAsyncSocketTest()
|
||||
: server_(CreateSocketServer()),
|
||||
scope_(server_.get()) {}
|
||||
// Override for other implementations of MacBaseSocketServer.
|
||||
virtual MacBaseSocketServer* CreateSocketServer() {
|
||||
return new MacCFSocketServer();
|
||||
};
|
||||
std::unique_ptr<MacBaseSocketServer> server_;
|
||||
SocketServerScope scope_;
|
||||
};
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestConnectIPv4) {
|
||||
SocketTest::TestConnectIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestConnectIPv6) {
|
||||
SocketTest::TestConnectIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestConnectWithDnsLookupIPv4) {
|
||||
SocketTest::TestConnectWithDnsLookupIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestConnectWithDnsLookupIPv6) {
|
||||
SocketTest::TestConnectWithDnsLookupIPv6();
|
||||
}
|
||||
|
||||
// BUG=https://code.google.com/p/webrtc/issues/detail?id=2272
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestConnectFailIPv4) {
|
||||
SocketTest::TestConnectFailIPv4();
|
||||
}
|
||||
|
||||
// Flaky. See webrtc:4738.
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestConnectFailIPv6) {
|
||||
SocketTest::TestConnectFailIPv6();
|
||||
}
|
||||
|
||||
// Reenable once we have mac async dns
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestConnectWithDnsLookupFailIPv4) {
|
||||
SocketTest::TestConnectWithDnsLookupFailIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestConnectWithDnsLookupFailIPv6) {
|
||||
SocketTest::TestConnectWithDnsLookupFailIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestConnectWithClosedSocketIPv4) {
|
||||
SocketTest::TestConnectWithClosedSocketIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestConnectWithClosedSocketIPv6) {
|
||||
SocketTest::TestConnectWithClosedSocketIPv6();
|
||||
}
|
||||
|
||||
// Flaky at the moment (10% failure rate). Seems the client doesn't get
|
||||
// signalled in a timely manner...
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestServerCloseDuringConnectIPv4) {
|
||||
SocketTest::TestServerCloseDuringConnectIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestServerCloseDuringConnectIPv6) {
|
||||
SocketTest::TestServerCloseDuringConnectIPv6();
|
||||
}
|
||||
// Flaky at the moment (0.5% failure rate). Seems the client doesn't get
|
||||
// signalled in a timely manner...
|
||||
TEST_F(MacAsyncSocketTest, TestClientCloseDuringConnectIPv4) {
|
||||
SocketTest::TestClientCloseDuringConnectIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestClientCloseDuringConnectIPv6) {
|
||||
SocketTest::TestClientCloseDuringConnectIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestServerCloseIPv4) {
|
||||
SocketTest::TestServerCloseIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestServerCloseIPv6) {
|
||||
SocketTest::TestServerCloseIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestCloseInClosedCallbackIPv4) {
|
||||
SocketTest::TestCloseInClosedCallbackIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestCloseInClosedCallbackIPv6) {
|
||||
SocketTest::TestCloseInClosedCallbackIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestSocketServerWaitIPv4) {
|
||||
SocketTest::TestSocketServerWaitIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestSocketServerWaitIPv6) {
|
||||
SocketTest::TestSocketServerWaitIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestTcpIPv4) {
|
||||
SocketTest::TestTcpIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestTcpIPv6) {
|
||||
SocketTest::TestTcpIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestSingleFlowControlCallbackIPv4) {
|
||||
SocketTest::TestSingleFlowControlCallbackIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, TestSingleFlowControlCallbackIPv6) {
|
||||
SocketTest::TestSingleFlowControlCallbackIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestUdpIPv4) {
|
||||
SocketTest::TestUdpIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestUdpIPv6) {
|
||||
SocketTest::TestUdpIPv6();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestGetSetOptionsIPv4) {
|
||||
SocketTest::TestGetSetOptionsIPv4();
|
||||
}
|
||||
|
||||
TEST_F(MacAsyncSocketTest, DISABLED_TestGetSetOptionsIPv6) {
|
||||
SocketTest::TestGetSetOptionsIPv6();
|
||||
}
|
||||
} // namespace rtc
|
||||
Loading…
x
Reference in New Issue
Block a user