SocketSelector bug fixes. Don't disconnect socket on read/write error.

This commit is contained in:
Fred Nicolson
2018-11-16 16:45:18 +00:00
parent 4377dcc66e
commit 9b22eb4604
4 changed files with 28 additions and 21 deletions

View File

@@ -56,8 +56,7 @@ namespace fr
}
else if(response < 0)
{
close_socket();
return Socket::Status::Disconnected;
return Socket::Status::Error;
}
}
@@ -77,8 +76,7 @@ namespace fr
return Socket::Status::WouldBlock;
}
close_socket();
return Socket::Status::Disconnected;
return Socket::Status::Error;
}
}
else
@@ -97,8 +95,7 @@ namespace fr
continue; //try again, interrupted before anything could be received
}
close_socket();
return Socket::Status::Disconnected;
return Socket::Status::Error;
}
break;
} while(true);

View File

@@ -10,8 +10,9 @@
namespace fr
{
#ifndef _WIN32
SocketSelector::SocketSelector()
: epoll_fd(-1)
: epoll_fd(-1)
{
epoll_fd = epoll_create1(O_CLOEXEC);
if(epoll_fd < 0)
@@ -32,7 +33,8 @@ namespace fr
throw std::logic_error("Can't add disconnected socket");
}
auto add_iter = added_sockets.emplace(socket->get_socket_descriptor(), Opaque(socket->get_socket_descriptor(), socket, opaque));
auto add_iter = added_sockets.emplace(socket->get_socket_descriptor(),
Opaque(socket->get_socket_descriptor(), socket, opaque));
if(!add_iter.second)
{
throw std::logic_error("Can't add duplicate socket: " + std::to_string(socket->get_socket_descriptor()));
@@ -59,17 +61,25 @@ namespace fr
throw std::runtime_error("epoll_wait returned: " + std::to_string(errno));
}
std::vector<std::pair<std::shared_ptr<fr::SocketDescriptor>, void*>> ret;
std::vector<std::pair<std::shared_ptr<fr::SocketDescriptor>, void *>> ret;
for(int a = 0; a < event_count; ++a)
{
auto *opaque = static_cast<Opaque*>(events[a].data.ptr);
auto *opaque = static_cast<Opaque *>(events[a].data.ptr);
ret.emplace_back(opaque->socket, opaque->opaque);
if(events[a].events & EPOLLERR || events[a].events & EPOLLHUP || events[a].events & EPOLLRDHUP)
{
auto iter = added_sockets.find(opaque->descriptor);
if(iter != added_sockets.end())
{
epoll_event event = {0};
auto remove_ret = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, opaque->descriptor, &event);
added_sockets.erase(opaque->descriptor);
if(remove_ret < 0)
{
throw std::runtime_error(
"Failed to remove socket: " + std::to_string(opaque->descriptor) + ". Errno: " +
std::to_string(errno));
}
}
}
}
@@ -83,19 +93,23 @@ namespace fr
{
throw std::runtime_error("Can't remove disconnected socket");
}
auto iter = added_sockets.find(descriptor);
if(iter != added_sockets.end())
if(iter == added_sockets.end())
{
added_sockets.erase(iter);
return;
}
added_sockets.erase(iter);
epoll_event event = {0};
if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, descriptor, &event) < 0)
{
throw std::runtime_error("Failed to remove socket: " + std::to_string(errno));
throw std::runtime_error(
"Failed to remove socket: " + std::to_string(descriptor) + ". Errno: " + std::to_string(errno));
}
delete static_cast<Opaque*>(event.data.ptr);
delete static_cast<Opaque *>(event.data.ptr);
}
#endif
}

View File

@@ -35,8 +35,7 @@ namespace fr
}
else if(errno != EWOULDBLOCK && errno != EAGAIN) //Don't exit if the socket just couldn't block
{
close_socket();
return Socket::Status::Disconnected;
return Socket::Status::Error;
}
}
return Socket::Status::Success;
@@ -68,8 +67,7 @@ namespace fr
continue; //try again, interrupted before anything could be received
}
close_socket();
return Socket::Status::Disconnected;
return Socket::Status::Error;
}
break;
} while(true);

View File

@@ -104,8 +104,7 @@ namespace fr
auto mask = static_cast<bool>((first_2bytes >> 7) & 0x1);
if(mask == socket_->is_client())
{
socket->disconnect();
return fr::Socket::Disconnected;
return fr::Socket::Error;
}
@@ -130,7 +129,6 @@ namespace fr
//Verify that payload length isn't too large
if(socket->get_max_receive_size() && payload_length > socket->get_max_receive_size())
{
socket->disconnect(); //We're forced to disconnect, otherwise we'll be out of sync with the server
return Socket::MaxPacketSizeExceeded;
}