aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/qt/bitcoin.cpp8
-rw-r--r--src/rpcprotocol.h1
-rw-r--r--src/rpcserver.cpp15
-rw-r--r--src/rpcserver.h7
-rw-r--r--src/rpcwallet.cpp2
5 files changed, 30 insertions, 3 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 3cf7e53c02..9b0b1d6e43 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -21,6 +21,7 @@
#include "init.h"
#include "main.h"
+#include "rpcserver.h"
#include "ui_interface.h"
#include "util.h"
#include "wallet.h"
@@ -227,6 +228,13 @@ void BitcoinCore::initialize()
{
LogPrintf("Running AppInit2 in thread\n");
int rv = AppInit2(threadGroup);
+ if(rv)
+ {
+ /* Start a dummy RPC thread if no RPC thread is active yet
+ * to handle timeouts.
+ */
+ StartDummyRPCThread();
+ }
emit initializeResult(rv);
} catch (std::exception& e) {
handleRunawayException(&e);
diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
index 6bf371e759..d3ed48525f 100644
--- a/src/rpcprotocol.h
+++ b/src/rpcprotocol.h
@@ -49,7 +49,6 @@ enum RPCErrorCode
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
RPC_DATABASE_ERROR = -20, // Database error
RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format
- RPC_SERVER_NOT_STARTED = -18, // RPC server was not started (StartRPCThreads() not called)
// P2P client errors
RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 9d34a900ff..0d9e95402b 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -38,6 +38,7 @@ static asio::io_service* rpc_io_service = NULL;
static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
static ssl::context* rpc_ssl_context = NULL;
static boost::thread_group* rpc_worker_group = NULL;
+static boost::asio::io_service::work *rpc_dummy_work = NULL;
void RPCTypeCheck(const Array& params,
const list<Value_type>& typesExpected,
@@ -607,6 +608,19 @@ void StartRPCThreads()
rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
}
+void StartDummyRPCThread()
+{
+ if(rpc_io_service == NULL)
+ {
+ rpc_io_service = new asio::io_service();
+ /* Create dummy "work" to keep the thread from exiting when no timeouts active,
+ * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
+ rpc_dummy_work = new asio::io_service::work(*rpc_io_service);
+ rpc_worker_group = new boost::thread_group();
+ rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
+ }
+}
+
void StopRPCThreads()
{
if (rpc_io_service == NULL) return;
@@ -615,6 +629,7 @@ void StopRPCThreads()
rpc_io_service->stop();
if (rpc_worker_group != NULL)
rpc_worker_group->join_all();
+ delete rpc_dummy_work; rpc_dummy_work = NULL;
delete rpc_worker_group; rpc_worker_group = NULL;
delete rpc_ssl_context; rpc_ssl_context = NULL;
delete rpc_io_service; rpc_io_service = NULL;
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 9087be9e88..9008c32810 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -20,7 +20,14 @@
class CBlockIndex;
+/* Start RPC threads */
void StartRPCThreads();
+/* Alternative to StartRPCThreads for the GUI, when no server is
+ * used. The RPC thread in this case is only used to handle timeouts.
+ * If real RPC threads have already been started this is a no-op.
+ */
+void StartDummyRPCThread();
+/* Stop RPC threads */
void StopRPCThreads();
/*
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 8ad5c9c51d..68f5fe525a 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -1562,8 +1562,6 @@ Value walletpassphrase(const Array& params, bool fHelp)
if (fHelp)
return true;
- if (!fServer)
- throw JSONRPCError(RPC_SERVER_NOT_STARTED, "Error: RPC server was not started, use server=1 to change this.");
if (!pwalletMain->IsCrypted())
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");