Compare commits

..

4 Commits

10 changed files with 25 additions and 35 deletions

View File

@ -199,8 +199,6 @@ make install # will install to /usr/local on Unix, on macOS it is a good idea to
Headers and a static library will be installed to the target dir. Headers and a static library will be installed to the target dir.
A [conan](https://conan.io/) file is available at [conan-IXWebSocket](https://github.com/Zinnion/conan-IXWebSocket).
There is a unittest which can be executed by typing `make test`. There is a unittest which can be executed by typing `make test`.
There is a Dockerfile for running some code on Linux. To use docker-compose you must make a docker container first. There is a Dockerfile for running some code on Linux. To use docker-compose you must make a docker container first.

View File

@ -35,6 +35,7 @@ namespace ix
_activeJobs.erase(_id); _activeJobs.erase(_id);
} }
// we want hostname to be copied, not passed as a const reference
struct addrinfo* DNSLookup::getAddrInfo(const std::string& hostname, struct addrinfo* DNSLookup::getAddrInfo(const std::string& hostname,
int port, int port,
std::string& errMsg) std::string& errMsg)

View File

@ -196,25 +196,6 @@ namespace ix
#endif #endif
} }
bool Socket::isWaitNeeded()
{
int err = getErrno();
if (err == EWOULDBLOCK || err == EAGAIN)
{
return true;
}
#ifdef _WIN32
if (err == WSAEWOULDBLOCK || err == WSATRY_AGAIN)
{
return true;
}
#endif
return false;
}
void Socket::closeSocket(int fd) void Socket::closeSocket(int fd)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -247,7 +228,8 @@ namespace ix
return ret == len; return ret == len;
} }
// There is possibly something to be writen, try again // There is possibly something to be writen, try again
else if (ret < 0 && Socket::isWaitNeeded()) else if (ret < 0 && (getErrno() == EWOULDBLOCK ||
getErrno() == EAGAIN))
{ {
continue; continue;
} }
@ -275,7 +257,8 @@ namespace ix
return true; return true;
} }
// There is possibly something to be read, try again // There is possibly something to be read, try again
else if (ret < 0 && Socket::isWaitNeeded()) else if (ret < 0 && (getErrno() == EWOULDBLOCK ||
getErrno() == EAGAIN))
{ {
// Wait with a 1ms timeout until the socket is ready to read. // Wait with a 1ms timeout until the socket is ready to read.
// This way we are not busy looping // This way we are not busy looping
@ -334,12 +317,13 @@ namespace ix
size_t size = std::min(kChunkSize, length - output.size()); size_t size = std::min(kChunkSize, length - output.size());
ssize_t ret = recv((char*)&_readBuffer[0], size); ssize_t ret = recv((char*)&_readBuffer[0], size);
if (ret <= 0 && !Socket::isWaitNeeded()) if (ret <= 0 && (getErrno() != EWOULDBLOCK &&
getErrno() != EAGAIN))
{ {
// Error // Error
return std::make_pair(false, std::string()); return std::make_pair(false, std::string());
} }
else else if (ret > 0)
{ {
output.insert(output.end(), output.insert(output.end(),
_readBuffer.begin(), _readBuffer.begin(),

View File

@ -41,6 +41,8 @@ namespace ix
virtual ~Socket(); virtual ~Socket();
bool init(std::string& errorMsg); bool init(std::string& errorMsg);
void configure();
// Functions to check whether there is activity on the socket // Functions to check whether there is activity on the socket
PollResultType poll(int timeoutSecs = kDefaultPollTimeout); PollResultType poll(int timeoutSecs = kDefaultPollTimeout);
bool wakeUpFromPoll(uint8_t wakeUpCode); bool wakeUpFromPoll(uint8_t wakeUpCode);
@ -74,7 +76,6 @@ namespace ix
const CancellationRequest& isCancellationRequested); const CancellationRequest& isCancellationRequested);
static int getErrno(); static int getErrno();
static bool isWaitNeeded();
// Used as special codes for pipe communication // Used as special codes for pipe communication
static const uint64_t kSendRequest; static const uint64_t kSendRequest;

View File

@ -247,7 +247,7 @@ namespace ix
if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) < 0) if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) < 0)
{ {
if (!Socket::isWaitNeeded()) if (Socket::getErrno() != EWOULDBLOCK)
{ {
// FIXME: that error should be propagated // FIXME: that error should be propagated
std::stringstream ss; std::stringstream ss;

View File

@ -340,7 +340,9 @@ namespace ix
WebSocket::invokeTrafficTrackerCallback(msg.size(), true); WebSocket::invokeTrafficTrackerCallback(msg.size(), true);
}); });
// If we aren't trying to reconnect automatically, exit if we aren't connected // 4. In blocking mode, getting out of this function is triggered by
// an explicit disconnection from the callback, or by the remote end
// closing the connection, ie isConnected() == false.
if (!isConnected() && !_automaticReconnection) return; if (!isConnected() && !_automaticReconnection) return;
} }
} }

View File

@ -154,6 +154,7 @@ namespace ix
static OnTrafficTrackerCallback _onTrafficTrackerCallback; static OnTrafficTrackerCallback _onTrafficTrackerCallback;
std::atomic<bool> _stop; std::atomic<bool> _stop;
std::atomic<bool> _backgroundThreadRunning;
std::atomic<bool> _automaticReconnection; std::atomic<bool> _automaticReconnection;
std::thread _thread; std::thread _thread;
std::mutex _writeMutex; std::mutex _writeMutex;

View File

@ -296,7 +296,8 @@ namespace ix
{ {
ssize_t ret = _socket->recv((char*)&_readbuf[0], _readbuf.size()); ssize_t ret = _socket->recv((char*)&_readbuf[0], _readbuf.size());
if (ret < 0 && Socket::isWaitNeeded()) if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
_socket->getErrno() == EAGAIN))
{ {
break; break;
} }
@ -843,7 +844,8 @@ namespace ix
{ {
ssize_t ret = _socket->send((char*)&_txbuf[0], _txbuf.size()); ssize_t ret = _socket->send((char*)&_txbuf[0], _txbuf.size());
if (ret < 0 && Socket::isWaitNeeded()) if (ret < 0 && (_socket->getErrno() == EWOULDBLOCK ||
_socket->getErrno() == EAGAIN))
{ {
break; break;
} }

View File

@ -8,11 +8,12 @@ project (ixwebsocket_unittest)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
find_package(Sanitizers) find_package(Sanitizers)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
set (CMAKE_CXX_STANDARD 14) set (CMAKE_CXX_STANDARD 14)
if (NOT WIN32) if (NOT WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
option(USE_TLS "Add TLS support" ON) option(USE_TLS "Add TLS support" ON)
endif() endif()