stopping connection on Linux does not close the socket, which can create problem when re-starting the connection
This commit is contained in:
@ -32,22 +32,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//
|
||||
// Linux/Android has a special type of virtual files. select(2) will react
|
||||
// when reading/writing to those files, unlike closing sockets.
|
||||
//
|
||||
// https://linux.die.net/man/2/eventfd
|
||||
//
|
||||
// eventfd was added in Linux kernel 2.x, and our oldest Android (Kitkat 4.4)
|
||||
// is on Kernel 3.x
|
||||
//
|
||||
// cf Android/Kernel table here
|
||||
// https://android.stackexchange.com/questions/51651/which-android-runs-which-linux-kernel
|
||||
//
|
||||
#ifdef __linux__
|
||||
# include <sys/eventfd.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
// Android needs extra headers for TCP_NODELAY and IPPROTO_TCP
|
||||
#ifdef ANDROID
|
||||
@ -58,22 +43,14 @@
|
||||
namespace ix
|
||||
{
|
||||
Socket::Socket() :
|
||||
_sockfd(-1),
|
||||
_eventfd(-1)
|
||||
_sockfd(-1)
|
||||
{
|
||||
#ifdef __linux__
|
||||
_eventfd = eventfd(0, 0);
|
||||
assert(_eventfd != -1 && "Panic - eventfd not functioning on this platform");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Socket::~Socket()
|
||||
{
|
||||
close();
|
||||
|
||||
#ifdef __linux__
|
||||
::close(_eventfd);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Socket::connectToAddress(const struct addrinfo *address,
|
||||
@ -180,36 +157,20 @@ namespace ix
|
||||
FD_SET(_sockfd, &rfds);
|
||||
|
||||
#ifdef __linux__
|
||||
FD_SET(_eventfd, &rfds);
|
||||
FD_SET(_eventfd.getFd(), &rfds);
|
||||
#endif
|
||||
|
||||
int sockfd = _sockfd;
|
||||
int nfds = (std::max)(sockfd, _eventfd);
|
||||
int nfds = (std::max)(sockfd, _eventfd.getFd());
|
||||
select(nfds + 1, &rfds, nullptr, nullptr, nullptr);
|
||||
|
||||
onPollCallback();
|
||||
}
|
||||
|
||||
void Socket::wakeUpFromPollApple()
|
||||
{
|
||||
close(); // All OS but Linux will wake up select
|
||||
// when closing the file descriptor watched by select
|
||||
}
|
||||
|
||||
void Socket::wakeUpFromPollLinux()
|
||||
{
|
||||
std::string str("\n"); // this will wake up the thread blocked on select
|
||||
const void* buf = reinterpret_cast<const void*>(str.c_str());
|
||||
write(_eventfd, buf, str.size());
|
||||
}
|
||||
|
||||
void Socket::wakeUpFromPoll()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
wakeUpFromPollApple();
|
||||
#elif defined(__linux__)
|
||||
wakeUpFromPollLinux();
|
||||
#endif
|
||||
// this will wake up the thread blocked on select, only needed on Linux
|
||||
_eventfd.notify();
|
||||
}
|
||||
|
||||
bool Socket::connect(const std::string& host,
|
||||
@ -218,12 +179,7 @@ namespace ix
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_socketMutex);
|
||||
|
||||
#ifdef __linux__
|
||||
if (_eventfd == -1)
|
||||
{
|
||||
return false; // impossible to use this socket if eventfd is broken
|
||||
}
|
||||
#endif
|
||||
if (!_eventfd.clear()) return false;
|
||||
|
||||
_sockfd = Socket::hostname_connect(host, port, errMsg);
|
||||
return _sockfd != -1;
|
||||
|
Reference in New Issue
Block a user