From db198d51a651086744871c972637f3856675a2ed Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 8 Jan 2016 10:11:25 +0100 Subject: Fix RPCTimerInterface ordering issue Dispatching a QThread from a non Qt thread is not allowed. Always use the HTTPRPCTimerInterface (non QT) to dispatch RPCRunLater threads. --- src/rpcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rpcserver.cpp') diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index bc419d14d9..de60bb6b1e 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -563,7 +563,7 @@ void RPCRunLater(const std::string& name, boost::function func, int6 if (timerInterfaces.empty()) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); - RPCTimerInterface* timerInterface = timerInterfaces[0]; + RPCTimerInterface* timerInterface = timerInterfaces.back(); LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } -- cgit v1.2.3 From 8a7f0001be88122256b1a8dc29b066210dc85625 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 8 Jan 2016 11:03:52 +0100 Subject: [RPC] remove the option of having multiple timer interfaces --- src/rpcserver.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/rpcserver.cpp') diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index de60bb6b1e..78d6898bc3 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -33,7 +33,7 @@ static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; /* Timer-creating functions */ -static std::vector timerInterfaces; +static RPCTimerInterface* timerInterface = NULL; /* Map of name to timer. * @note Can be changed to std::unique_ptr when C++11 */ static std::map > deadlineTimers; @@ -546,24 +546,28 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; } -void RPCRegisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface) { - timerInterfaces.push_back(iface); + if (!timerInterface) + timerInterface = iface; } -void RPCUnregisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterface(RPCTimerInterface *iface) { - std::vector::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface); - assert(i != timerInterfaces.end()); - timerInterfaces.erase(i); + timerInterface = iface; +} + +void RPCUnsetTimerInterface(RPCTimerInterface *iface) +{ + if (timerInterface == iface) + timerInterface = NULL; } void RPCRunLater(const std::string& name, boost::function func, int64_t nSeconds) { - if (timerInterfaces.empty()) + if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); - RPCTimerInterface* timerInterface = timerInterfaces.back(); LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } -- cgit v1.2.3