fix json rpc server memory leak
This commit is contained in:
parent
a5a88a50c7
commit
38f97ef61a
7 changed files with 31 additions and 14 deletions
|
|
@ -2,8 +2,7 @@
|
||||||
* @file fc/cmt/asio.hpp
|
* @file fc/cmt/asio.hpp
|
||||||
* @brief defines wrappers for boost::asio functions
|
* @brief defines wrappers for boost::asio functions
|
||||||
*/
|
*/
|
||||||
#ifndef _FC_ASIO_HPP_
|
#pragma once
|
||||||
#define _FC_ASIO_HPP_
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <fc/future.hpp>
|
#include <fc/future.hpp>
|
||||||
|
|
@ -262,4 +261,3 @@ namespace asio {
|
||||||
|
|
||||||
} } // namespace fc::asio
|
} } // namespace fc::asio
|
||||||
|
|
||||||
#endif // _BOOST_CMT_ASIO_HPP_
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace fc {
|
||||||
|
|
||||||
uint32_t ip()const { return _ip; }
|
uint32_t ip()const { return _ip; }
|
||||||
|
|
||||||
d
|
|
||||||
private:
|
private:
|
||||||
uint32_t _ip;
|
uint32_t _ip;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef _FC_TCP_SOCKET_HPP_
|
#pragma once
|
||||||
#define _FC_TCP_SOCKET_HPP_
|
|
||||||
#include <fc/utility.hpp>
|
#include <fc/utility.hpp>
|
||||||
#include <fc/fwd.hpp>
|
#include <fc/fwd.hpp>
|
||||||
#include <fc/iostream.hpp>
|
#include <fc/iostream.hpp>
|
||||||
|
|
@ -55,4 +54,3 @@ namespace fc {
|
||||||
|
|
||||||
} // namesapce fc
|
} // namesapce fc
|
||||||
|
|
||||||
#endif // _FC_TCP_SOCKET_HPP_
|
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,12 @@ namespace fc { namespace json {
|
||||||
|
|
||||||
~impl() {
|
~impl() {
|
||||||
try {
|
try {
|
||||||
|
// slog( "..." );
|
||||||
self.cancel_pending_requests();
|
self.cancel_pending_requests();
|
||||||
_read_loop_complete.cancel();
|
_read_loop_complete.cancel();
|
||||||
|
// slog( "wait..." );
|
||||||
_read_loop_complete.wait();
|
_read_loop_complete.wait();
|
||||||
|
// slog( "DONE ..." );
|
||||||
} catch ( ... ) {}
|
} catch ( ... ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +51,9 @@ namespace fc { namespace json {
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
wlog( "%s", fc::except_str().c_str() );
|
wlog( "%s", fc::except_str().c_str() );
|
||||||
}
|
}
|
||||||
|
// slog( "cancel...");
|
||||||
self.cancel_pending_requests();
|
self.cancel_pending_requests();
|
||||||
|
// slog( "close!" );
|
||||||
if( !!on_close ) on_close();
|
if( !!on_close ) on_close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -56,9 +61,10 @@ namespace fc { namespace json {
|
||||||
rpc_stream_connection::rpc_stream_connection( fc::istream& i, fc::ostream& o )
|
rpc_stream_connection::rpc_stream_connection( fc::istream& i, fc::ostream& o )
|
||||||
:my( new impl(i,o,*this) ){
|
:my( new impl(i,o,*this) ){
|
||||||
}
|
}
|
||||||
rpc_stream_connection::rpc_stream_connection(){ slog( "%p...",this); }
|
rpc_stream_connection::rpc_stream_connection(){ }
|
||||||
rpc_stream_connection::rpc_stream_connection(const rpc_stream_connection& c):my(c.my){ slog( "%p",this); }
|
rpc_stream_connection::rpc_stream_connection(const rpc_stream_connection& c):my(c.my){ }
|
||||||
rpc_stream_connection::~rpc_stream_connection(){
|
rpc_stream_connection::~rpc_stream_connection(){
|
||||||
|
wlog( "%p", this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// the life of the streams must exceed the life of all copies
|
// the life of the streams must exceed the life of all copies
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,20 @@ namespace fc {
|
||||||
slog( "new connection!" );
|
slog( "new connection!" );
|
||||||
my->on_con( *con );
|
my->on_con( *con );
|
||||||
con->start();
|
con->start();
|
||||||
|
rpc_tcp_connection* tcpc = con.get();
|
||||||
my->cons.push_back(con);
|
my->cons.push_back(con);
|
||||||
|
con->on_close( [=]() {
|
||||||
|
for( int i = 0; i < my->cons.size(); ++i ) {
|
||||||
|
if( my->cons[i].get() == tcpc ) {
|
||||||
|
fc_swap( my->cons[i], my->cons.back() );
|
||||||
|
auto tmp = my->cons.back();
|
||||||
|
my->cons.pop_back();
|
||||||
|
fc::async([tmp](){slog("free con");});
|
||||||
|
// TODO: swap to end, pop back
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
con.reset(new rpc_tcp_connection() );
|
con.reset(new rpc_tcp_connection() );
|
||||||
}
|
}
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ namespace fc {
|
||||||
return my->_sock.is_open();
|
return my->_sock.is_open();
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp_socket::tcp_socket(){}
|
tcp_socket::tcp_socket(){};
|
||||||
|
|
||||||
tcp_socket::~tcp_socket(){ }
|
tcp_socket::~tcp_socket(){};
|
||||||
|
|
||||||
void tcp_socket::flush() {}
|
void tcp_socket::flush() {}
|
||||||
void tcp_socket::close() {
|
void tcp_socket::close() {
|
||||||
my->_sock.close();
|
if( is_open() ) my->_sock.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tcp_socket::eof()const {
|
bool tcp_socket::eof()const {
|
||||||
|
|
@ -63,14 +63,16 @@ namespace fc {
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
size_t w = my->_sock.read_some( boost::asio::buffer( buf, len ), ec );
|
size_t w = my->_sock.read_some( boost::asio::buffer( buf, len ), ec );
|
||||||
if( ec == boost::asio::error::would_block ) {
|
if( ec == boost::asio::error::would_block ) {
|
||||||
promise<size_t>::ptr p(new promise<size_t>("tcp_socket::write"));
|
promise<size_t>::ptr p(new promise<size_t>("tcp_socket::readsome"));
|
||||||
my->_sock.async_read_some( boost::asio::buffer(buf, len),
|
my->_sock.async_read_some( boost::asio::buffer(buf, len),
|
||||||
[=]( const boost::system::error_code& ec, size_t bt ) {
|
[=]( const boost::system::error_code& ec, size_t bt ) {
|
||||||
|
slog( "%d ec: %s", bt, boost::system::system_error(ec).what() );
|
||||||
if( !ec ) p->set_value(bt);
|
if( !ec ) p->set_value(bt);
|
||||||
else p->set_exception( fc::copy_exception( boost::system::system_error(ec) ) );
|
else p->set_exception( fc::copy_exception( boost::system::system_error(ec) ) );
|
||||||
});
|
});
|
||||||
return p->wait();
|
return p->wait();
|
||||||
} else if (ec ) {
|
} else if (ec ) {
|
||||||
|
slog( "throw!" );
|
||||||
throw boost::system::system_error(ec);
|
throw boost::system::system_error(ec);
|
||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
|
|
|
||||||
2
vendor/CMakeLists.txt
vendored
2
vendor/CMakeLists.txt
vendored
|
|
@ -1,3 +1,3 @@
|
||||||
add_subdirectory( libssh2-1.4.2 )
|
add_subdirectory( libssh2-1.4.2 )
|
||||||
#add_subdirectory( zlib-1.2.7)
|
#add_subdirectory( zlib-1.2.7)
|
||||||
add_subdirectory( sigar )
|
#add_subdirectory( sigar )
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue