udp_socket fix

This commit is contained in:
Arvid Norberg 2012-10-18 07:34:39 +00:00
parent ed4dfbc8fb
commit 3a2da49516
2 changed files with 31 additions and 0 deletions

View File

@ -209,6 +209,13 @@ namespace libtorrent
udp::socket m_ipv4_sock; udp::socket m_ipv4_sock;
int m_buf_size; int m_buf_size;
// if the buffer size is attempted
// to be changed while the buffer is
// being used, this member is set to
// the desired size, and it's resized
// later
int m_new_buf_size;
char* m_buf; char* m_buf;
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6

View File

@ -57,6 +57,7 @@ udp_socket::udp_socket(asio::io_service& ios
: m_observers_locked(false) : m_observers_locked(false)
, m_ipv4_sock(ios) , m_ipv4_sock(ios)
, m_buf_size(0) , m_buf_size(0)
, m_new_buf_size(0)
, m_buf(0) , m_buf(0)
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
, m_ipv6_sock(ios) , m_ipv6_sock(ios)
@ -89,6 +90,7 @@ udp_socket::udp_socket(asio::io_service& ios
#endif #endif
m_buf_size = 2000; m_buf_size = 2000;
m_new_buf_size = m_buf_size;
m_buf = (char*)malloc(m_buf_size); m_buf = (char*)malloc(m_buf_size);
} }
@ -285,6 +287,8 @@ void udp_socket::call_handler(error_code const& ec, udp::endpoint const& ep, cha
m_added_observers.clear(); m_added_observers.clear();
} }
m_observers_locked = false; m_observers_locked = false;
if (m_new_buf_size != m_buf_size)
set_buf_size(m_new_buf_size);
} }
void udp_socket::call_handler(error_code const& ec, const char* host, char const* buf, int size) void udp_socket::call_handler(error_code const& ec, const char* host, char const* buf, int size)
@ -307,6 +311,8 @@ void udp_socket::call_handler(error_code const& ec, const char* host, char const
m_added_observers.clear(); m_added_observers.clear();
} }
m_observers_locked = false; m_observers_locked = false;
if (m_new_buf_size != m_buf_size)
set_buf_size(m_new_buf_size);
} }
void udp_socket::call_drained_handler() void udp_socket::call_drained_handler()
@ -327,6 +333,8 @@ void udp_socket::call_drained_handler()
m_added_observers.clear(); m_added_observers.clear();
} }
m_observers_locked = false; m_observers_locked = false;
if (m_new_buf_size != m_buf_size)
set_buf_size(m_new_buf_size);
} }
void udp_socket::call_writable_handler() void udp_socket::call_writable_handler()
@ -347,6 +355,8 @@ void udp_socket::call_writable_handler()
m_added_observers.clear(); m_added_observers.clear();
} }
m_observers_locked = false; m_observers_locked = false;
if (m_new_buf_size != m_buf_size)
set_buf_size(m_new_buf_size);
} }
void udp_socket::subscribe(udp_socket_observer* o) void udp_socket::subscribe(udp_socket_observer* o)
@ -595,12 +605,25 @@ void udp_socket::close()
void udp_socket::set_buf_size(int s) void udp_socket::set_buf_size(int s)
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
if (m_observers_locked)
{
// we can't actually reallocate the buffer while
// it's being used by the observers, we have to
// do that once we're done iterating over them
m_new_buf_size = s;
return;
}
if (s == m_buf_size) return;
bool no_mem = false; bool no_mem = false;
void* tmp = realloc(m_buf, s); void* tmp = realloc(m_buf, s);
if (tmp != 0) if (tmp != 0)
{ {
m_buf = (char*)tmp; m_buf = (char*)tmp;
m_buf_size = s; m_buf_size = s;
m_new_buf_size = s;
} }
else else
{ {
@ -612,6 +635,7 @@ void udp_socket::set_buf_size(int s)
free(m_buf); free(m_buf);
m_buf = 0; m_buf = 0;
m_buf_size = 0; m_buf_size = 0;
m_new_buf_size = 0;
udp::endpoint ep; udp::endpoint ep;
call_handler(error::no_memory, ep, 0, 0); call_handler(error::no_memory, ep, 0, 0);
close(); close();