diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bd2a4f45c..8cc6f9bdc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [3.7.4.0] 2018-01-20 +### Fixed + - Fix RPC resource leak regression. This also reduces RPC overhead, + making calls ~25-35% faster, #848 (@denravonska). + - Fix incorrect return code when forking, #832 (@denravonska). + +### Removed + - Remove upgrader option until rewritten, #836 (@Foggyx420). + ## [3.7.3.0] 2018-01-13 ### Fixed - Fix for UI getting stuck in splash screen (@denravonska). diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 1eb6348f5b..7352591720 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -42,8 +42,6 @@ static asio::io_service* rpc_io_service = NULL; const Object emptyobj; -void ThreadRPCServer3(void* parg); - static inline unsigned short GetDefaultRPCPort() { return GetBoolArg("-testnet", false) ? 25715 : 15715; @@ -669,6 +667,8 @@ class AcceptedConnectionImpl : public AcceptedConnection iostreams::stream< SSLIOStreamDevice > _stream; }; +void ServiceConnection(AcceptedConnection *conn); + void StopRPCThreads() { printf("Stop RPC IO service\n"); @@ -742,37 +742,30 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor AcceptedConnection* conn, const boost::system::error_code& error) { - // Immediately start accepting new connections, except when we're cancelled or our socket is closed. - if (error != asio::error::operation_aborted - && acceptor->is_open()) + if (error != asio::error::operation_aborted && acceptor->is_open()) RPCListen(acceptor, context, fUseSSL); - AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn); - // TODO : Actually handle errors - if (error) - { - delete conn; - } + if (!error) + { + // Restrict callers by IP. It is important to + // do this before starting client thread, to filter out + // certain DoS and misbehaving clients. + AcceptedConnectionImpl* tcp_conn = dynamic_cast< AcceptedConnectionImpl* >(conn); + if (tcp_conn && !ClientAllowed(tcp_conn->peer.address())) + { + // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. + if (!fUseSSL) + conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; + } + else + ServiceConnection(conn); - // Restrict callers by IP. It is important to - // do this before starting client thread, to filter out - // certain DoS and misbehaving clients. - else if (tcp_conn - && !ClientAllowed(tcp_conn->peer.address())) - { - // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. - if (!fUseSSL) - conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; - delete conn; + conn->close(); } - // start HTTP client thread - else if (!netThreads->createThread(ThreadRPCServer3, conn,"ThreadRPCServer3")) { - printf("Failed to create RPC server client thread\r\n"); - delete conn; - } + delete conn; } void ThreadRPCServer2(void* parg) @@ -985,30 +978,17 @@ static string JSONRPCExecBatch(const Array& vReq) return write_string(Value(ret), false) + "\n"; } -static CCriticalSection cs_THREAD_RPCHANDLER; - -void ThreadRPCServer3(void* parg) +void ServiceConnection(AcceptedConnection *conn) { // Make this thread recognisable as the RPC handler RenameThread("grc-rpchand"); - { - LOCK(cs_THREAD_RPCHANDLER); - } - AcceptedConnection *conn = (AcceptedConnection *) parg; - bool fRun = true; while (true) { if (fShutdown || !fRun) - { - conn->close(); - delete conn; - { - LOCK(cs_THREAD_RPCHANDLER); - } - return; - } + break; + map mapHeaders; string strRequest; @@ -1073,11 +1053,6 @@ void ThreadRPCServer3(void* parg) break; } } - - delete conn; - { - LOCK(cs_THREAD_RPCHANDLER); - } } json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const diff --git a/src/init.cpp b/src/init.cpp index d6b2574585..887e5d3ba2 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -608,11 +608,10 @@ bool AppInit2(ThreadHandlerPtr threads) { CreatePidFile(GetPidFile(), pid); - // While this is technically successful we need to return false - // in order to shut down the parent process. This can be improved - // by either returning an enum or checking if the current process - // is a child process. - return false; + // Now that we are forked we can request a shutdown so the parent + // exits while the child lives on. + StartShutdown(); + return true; } pid_t sid = setsid(); @@ -885,7 +884,7 @@ bool AppInit2(ThreadHandlerPtr threads) strErrors << _("Error loading wallet.dat") << "\n"; } - if (GetBoolArg("-upgradewallet", fFirstRun)) +/* if (GetBoolArg("-upgradewallet", fFirstRun)) { int nMaxVersion = GetArg("-upgradewallet", 0); if (nMaxVersion == 0) // the -upgradewallet without argument case @@ -899,7 +898,7 @@ bool AppInit2(ThreadHandlerPtr threads) if (nMaxVersion < pwalletMain->GetVersion()) strErrors << _("Cannot downgrade wallet") << "\n"; pwalletMain->SetMaxVersion(nMaxVersion); - } + }*/ if (fFirstRun) { diff --git a/src/main.cpp b/src/main.cpp index 27db3ee6bb..4f5421ae58 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4436,7 +4436,7 @@ void GridcoinServices() if (TimerMain("gather_cpids",480)) msNeuralResponse.clear(); -#ifdef QT_GUI +/*#ifdef QT_GUI // Check for updates once per day. if(GetAdjustedTime() - nLastCheckedForUpdate > 24 * 60 * 60) { @@ -4453,7 +4453,7 @@ void GridcoinServices() } } } -#endif +#endif*/ if (fDebug10) printf(" {/SVC} "); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index faea561e2b..181241d5c1 100755 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -232,13 +232,14 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): rpcConsole = new RPCConsole(this); connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); - upgrader = new UpgradeDialog(this); - connect(upgradeAction, SIGNAL(triggered()), upgrader, SLOT(show())); - connect(upgradeAction, SIGNAL(triggered()), upgrader, SLOT(upgrade())); - connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(show())); - connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(blocks())); - - diagnosticsDialog = new DiagnosticsDialog(this); + upgrader = new UpgradeDialog(this); + connect(upgradeAction, SIGNAL(triggered()), upgrader, SLOT(show())); + connect(upgradeAction, SIGNAL(triggered()), upgrader, SLOT(upgrade())); + upgradeAction->setVisible(false); + connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(show())); + connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(blocks())); + + diagnosticsDialog = new DiagnosticsDialog(this); // Clicking on "Verify Message" in the address book sends you to the verify message tab diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 44bf3531dd..a919b4c900 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -491,7 +491,8 @@ Value downloadstate(const Array& params, bool fHelp) Value upgrade(const Array& params, bool fHelp) { - if (fHelp || params.size() != 0) + throw runtime_error("upgrader disabled"); + /*if (fHelp || params.size() != 0) throw runtime_error( "upgrade \n" "Upgrades client to the latest version.\n" @@ -517,7 +518,7 @@ Value upgrade(const Array& params, bool fHelp) QMetaObject::invokeMethod(&checker, "check", Qt::QueuedConnection); #endif return "Initiated download of client"; - } + }*/ }