Debugger stuff. Lots of wasted work :/

This commit is contained in:
Ben Vanik
2015-07-26 22:47:03 -07:00
parent 42ef3f224a
commit 7ecc6362de
52 changed files with 3476 additions and 172 deletions

View File

@@ -45,6 +45,33 @@ class Delegate {
std::vector<Listener> listeners_;
};
template <>
class Delegate<void> {
public:
typedef std::function<void()> Listener;
void AddListener(Listener const& listener) {
std::lock_guard<std::mutex> guard(lock_);
listeners_.push_back(listener);
}
void RemoveAllListeners() {
std::lock_guard<std::mutex> guard(lock_);
listeners_.clear();
}
void operator()() {
std::lock_guard<std::mutex> guard(lock_);
for (auto& listener : listeners_) {
listener();
}
}
private:
std::mutex lock_;
std::vector<Listener> listeners_;
};
} // namespace xe
#endif // XENIA_BASE_DELEGATE_H_

View File

@@ -28,7 +28,8 @@ namespace xe {
// wait handle should be waited on until new data arrives.
class Socket {
public:
// TODO(benvanik): client socket static Connect method.
// Synchronously connects to the given hostname:port.
static std::unique_ptr<Socket> Connect(std::string hostname, uint16_t port);
virtual ~Socket() = default;
@@ -84,6 +85,12 @@ class Socket {
auto buffer_list = std::make_pair(buffer.data(), buffer.size());
return Send(&buffer_list, 1);
}
// Asynchronously sends a string buffer.
// Returns false if the socket is disconnected or the data cannot be sent.
bool Send(const std::string& value) {
return Send(value.data(), value.size());
}
};
// Runs a socket server on the specified local port.

View File

@@ -36,6 +36,51 @@ class Win32Socket : public Socket {
Win32Socket() = default;
~Win32Socket() override { Close(); }
bool Connect(std::string hostname, uint16_t port) {
addrinfo hints = {0};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port.
// May return multiple results, so attempt to connect to an address until
// one succeeds.
addrinfo* result = nullptr;
auto port_string = std::to_string(port);
int ret =
getaddrinfo(hostname.c_str(), port_string.c_str(), &hints, &result);
if (ret != 0) {
XELOGE("getaddrinfo failed with error: %d", ret);
return false;
}
SOCKET try_socket = INVALID_SOCKET;
for (addrinfo* ptr = result; ptr; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server.
try_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (try_socket == INVALID_SOCKET) {
XELOGE("socket failed with error: %ld", WSAGetLastError());
freeaddrinfo(result);
return false;
}
// Connect to server.
ret = connect(try_socket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (ret == SOCKET_ERROR) {
closesocket(try_socket);
try_socket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (try_socket == INVALID_SOCKET) {
XELOGE("Unable to connect to server");
return false;
}
// Piggyback to setup the socket.
return Accept(try_socket);
}
bool Accept(SOCKET socket) {
std::lock_guard<std::recursive_mutex> lock(mutex_);
@@ -142,6 +187,16 @@ class Win32Socket : public Socket {
std::unique_ptr<xe::threading::Event> event_;
};
std::unique_ptr<Socket> Socket::Connect(std::string hostname, uint16_t port) {
InitializeWinsock();
auto socket = std::make_unique<Win32Socket>();
if (!socket->Connect(std::move(hostname), port)) {
return nullptr;
}
return std::unique_ptr<Socket>(socket.release());
}
class Win32SocketServer : public SocketServer {
public:
Win32SocketServer(