barrier/lib/net/CTCPListenSocket.cpp
crs f65921bc3f Refactored some platform dependent code into a new library,
lib/arch.  This should make porting easier.  Will probably
continue to refactor a little more, moving platform dependent
event handling stuff into lib/platform.
2003-01-04 22:01:32 +00:00

99 lines
2.0 KiB
C++

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "CTCPListenSocket.h"
#include "CTCPSocket.h"
#include "CNetworkAddress.h"
#include "XIO.h"
#include "XSocket.h"
#include "CThread.h"
#include "CArch.h"
#include "XArch.h"
//
// CTCPListenSocket
//
CTCPListenSocket::CTCPListenSocket()
{
try {
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM);
}
catch (XArchNetwork& e) {
throw XSocketCreate(e.what());
}
}
CTCPListenSocket::~CTCPListenSocket()
{
try {
ARCH->closeSocket(m_socket);
}
catch (...) {
// ignore
}
}
void
CTCPListenSocket::bind(const CNetworkAddress& addr)
{
try {
ARCH->bindSocket(m_socket, addr.getAddress());
ARCH->listenOnSocket(m_socket);
}
catch (XArchNetworkAddressInUse& e) {
throw XSocketAddressInUse(e.what());
}
catch (XArchNetwork& e) {
throw XSocketBind(e.what());
}
}
IDataSocket*
CTCPListenSocket::accept()
{
// accept asynchronously so we can check for cancellation
IArchNetwork::CPollEntry pfds[1];
pfds[0].m_socket = m_socket;
pfds[0].m_events = IArchNetwork::kPOLLIN;
for (;;) {
ARCH->testCancelThread();
try {
const int status = ARCH->pollSocket(pfds, 1, 0.01);
if (status > 0 &&
(pfds[0].m_revents & IArchNetwork::kPOLLIN) != 0) {
return new CTCPSocket(ARCH->acceptSocket(m_socket, NULL));
}
}
catch (XArchNetwork&) {
// ignore and retry
}
}
}
void
CTCPListenSocket::close()
{
if (m_socket == NULL) {
throw XIOClosed();
}
try {
ARCH->closeSocket(m_socket);
m_socket = NULL;
}
catch (XArchNetwork& e) {
throw XSocketIOClose(e.what());
}
}