mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-27 17:18:34 +00:00
attempt to fix crash bug when cancelling a download
This commit is contained in:
parent
46cd652c7f
commit
bc0273c41a
@ -237,6 +237,7 @@ pending_statistics get_pending_stats()
|
||||
|
||||
manager::manager(size_t min_threads, size_t max_threads) : free_(true)
|
||||
{
|
||||
fprintf(stderr, "NETWORK MANAGER CALLED!\n");
|
||||
// If the network is already being managed
|
||||
if(socket_set) {
|
||||
free_ = false;
|
||||
@ -588,20 +589,12 @@ connection accept_connection()
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool disconnect(connection s, bool force)
|
||||
bool disconnect(connection s)
|
||||
{
|
||||
if(s == 0) {
|
||||
while(sockets.empty() == false) {
|
||||
assert(sockets.back() != 0);
|
||||
size_t n = 0;
|
||||
while(disconnect(sockets.back()) == false) {
|
||||
// force a disconnect
|
||||
if (n > 100) {
|
||||
disconnect(sockets.back(), true);
|
||||
n = 0;
|
||||
continue;
|
||||
}
|
||||
++n;
|
||||
SDL_Delay(1);
|
||||
}
|
||||
}
|
||||
@ -615,7 +608,7 @@ bool disconnect(connection s, bool force)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!network_worker_pool::close_socket(info->second.sock, force)) {
|
||||
if (!network_worker_pool::close_socket(info->second.sock)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ connection accept_connection();
|
||||
* in the middle of sending/receiving data.
|
||||
* The socket will be closed when it has finished its send/receive.
|
||||
*/
|
||||
bool disconnect(connection connection_num=0, bool force=false);
|
||||
bool disconnect(connection connection_num=0);
|
||||
|
||||
/**
|
||||
* Function to queue a disconnection.
|
||||
|
@ -237,9 +237,33 @@ bool receive_with_timeout(TCPsocket s, char* buf, size_t nbytes,
|
||||
#ifdef USE_POLL
|
||||
struct pollfd fd = { ((_TCPsocket*)s)->channel, POLLIN, 0 };
|
||||
int poll_res;
|
||||
|
||||
//we timeout of the poll every 100ms. This lets us check to
|
||||
//see if we have been disconnected, in which case we should
|
||||
//abort the receive.
|
||||
const int poll_timeout = std::min(timeout_ms, 100);
|
||||
do {
|
||||
poll_res = poll(&fd, 1, timeout_ms);
|
||||
} while(poll_res == -1 && errno == EINTR);
|
||||
poll_res = poll(&fd, 1, poll_timeout);
|
||||
|
||||
if(poll_res == 0) {
|
||||
timeout_ms -= poll_timeout;
|
||||
if(timeout_ms <= 0) {
|
||||
//we've been waiting too long; abort the receive
|
||||
//as having failed due to timeout.
|
||||
return false;
|
||||
}
|
||||
|
||||
//check to see if we've been interrupted
|
||||
const size_t shard = get_shard(s);
|
||||
const threading::lock lock(*shard_mutexes[shard]);
|
||||
socket_state_map::iterator lock_it = sockets_locked[shard].find(s);
|
||||
assert(lock_it != sockets_locked[shard].end());
|
||||
if(lock_it->second == SOCKET_INTERRUPT) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} while(poll_res == 0 || poll_res == -1 && errno == EINTR);
|
||||
|
||||
if (poll_res < 1)
|
||||
return false;
|
||||
@ -250,11 +274,31 @@ bool receive_with_timeout(TCPsocket s, char* buf, size_t nbytes,
|
||||
int retval;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = timeout_ms/1000;
|
||||
tv.tv_usec = timeout_ms % 1000;
|
||||
const int select_timeout = std::min(timeout_ms, 100);
|
||||
|
||||
tv.tv_sec = select_timeout/1000;
|
||||
tv.tv_usec = select_timeout % 1000;
|
||||
do {
|
||||
retval = select(((_TCPsocket*)s)->channel + 1, &readfds, NULL, NULL, &tv);
|
||||
} while(retval == -1 && errno == EINTR);
|
||||
|
||||
if(retval == 0) {
|
||||
timeout_ms -= select_timeout;
|
||||
if(timeout_ms <= 0) {
|
||||
//we've been waiting too long; abort the receive
|
||||
//as having failed due to timeout.
|
||||
return false;
|
||||
}
|
||||
|
||||
//check to see if we've been interrupted
|
||||
const size_t shard = get_shard(s);
|
||||
const threading::lock lock(*shard_mutexes[shard]);
|
||||
socket_state_map::iterator lock_it = sockets_locked[shard].find(s);
|
||||
assert(lock_it != sockets_locked[shard].end());
|
||||
if(lock_it->second == SOCKET_INTERRUPT) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} while(retval == 0 || retval == -1 && errno == EINTR);
|
||||
|
||||
if (retval < 1)
|
||||
return false;
|
||||
@ -288,6 +332,7 @@ bool receive_with_timeout(TCPsocket s, char* buf, size_t nbytes,
|
||||
}
|
||||
{
|
||||
const size_t shard = get_shard(s);
|
||||
const threading::lock lock(*shard_mutexes[shard]);
|
||||
socket_state_map::iterator lock_it = sockets_locked[shard].find(s);
|
||||
assert(lock_it != sockets_locked[shard].end());
|
||||
if(lock_it->second == SOCKET_INTERRUPT) {
|
||||
@ -1020,7 +1065,7 @@ bool is_locked(const TCPsocket sock) {
|
||||
return (lock_it->second == SOCKET_LOCKED);
|
||||
}
|
||||
|
||||
bool close_socket(TCPsocket sock, bool force)
|
||||
bool close_socket(TCPsocket sock)
|
||||
{
|
||||
{
|
||||
const size_t shard = get_shard(sock);
|
||||
@ -1037,7 +1082,7 @@ bool close_socket(TCPsocket sock, bool force)
|
||||
remove_buffers(sock);
|
||||
return true;
|
||||
}
|
||||
if (!(lock_it->second == SOCKET_LOCKED || lock_it->second == SOCKET_INTERRUPT) || force) {
|
||||
if (!(lock_it->second == SOCKET_LOCKED || lock_it->second == SOCKET_INTERRUPT)) {
|
||||
sockets_locked[shard].erase(lock_it);
|
||||
remove_buffers(sock);
|
||||
return true;
|
||||
|
@ -62,7 +62,7 @@ void queue_file(TCPsocket sock, const std::string&);
|
||||
void queue_raw_data(TCPsocket sock, const char* buf, int len);
|
||||
size_t queue_data(TCPsocket sock, const config& buf, const bool gzipped, const std::string& packet_type);
|
||||
bool is_locked(const TCPsocket sock);
|
||||
bool close_socket(TCPsocket sock, bool force=false);
|
||||
bool close_socket(TCPsocket sock);
|
||||
TCPsocket detect_error();
|
||||
|
||||
std::pair<network::statistics,network::statistics> get_current_transfer_stats(TCPsocket sock);
|
||||
|
Loading…
x
Reference in New Issue
Block a user