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:
nisse 2016-10-07 05:57:21 -07:00 committed by Commit bot
parent df494b0908
commit c7901c6491
11 changed files with 0 additions and 1298 deletions

View File

@ -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.

View File

@ -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",
]

View File

@ -474,12 +474,6 @@
}],
['OS=="mac"', {
'sources': [
'macasyncsocket.cc',
'macasyncsocket.h',
'maccocoasocketserver.h',
'maccocoasocketserver.mm',
'macsocketserver.cc',
'macsocketserver.h',
'macwindowpicker.cc',
'macwindowpicker.h',
],

View File

@ -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

View File

@ -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__

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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