Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/server.cpp
// Copyright (c) 2010 Satoshi Nakamoto | // Copyright (c) 2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Copyright (c) 2018-2019 The Bitcoin developers | |||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "rpc/server.h" | #include "rpc/server.h" | ||||
#include "base58.h" | #include "base58.h" | ||||
#include "config.h" | #include "config.h" | ||||
#include "fs.h" | #include "fs.h" | ||||
Show All 15 Lines | |||||
#include <memory> // for unique_ptr | #include <memory> // for unique_ptr | ||||
#include <set> | #include <set> | ||||
#include <unordered_map> | #include <unordered_map> | ||||
static bool fRPCRunning = false; | static bool fRPCRunning = false; | ||||
static bool fRPCInWarmup = true; | static bool fRPCInWarmup = true; | ||||
static std::string rpcWarmupStatus("RPC server started"); | static std::string rpcWarmupStatus("RPC server started"); | ||||
static CCriticalSection cs_rpcWarmup; | static CCriticalSection cs_rpcWarmup; | ||||
static CCriticalSection cs_rpcRegister; | |||||
jasonbcox: should not be global | |||||
/* Timer-creating functions */ | /* Timer-creating functions */ | ||||
static RPCTimerInterface *timerInterface = nullptr; | static RPCTimerInterface *timerInterface = nullptr; | ||||
/* Map of name to timer. */ | /* Map of name to timer. */ | ||||
static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers; | static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers; | ||||
UniValue RPCServer::ExecuteCommand(Config &config, | UniValue RPCServer::ExecuteCommand(Config &config, | ||||
const JSONRPCRequest &request) const { | const JSONRPCRequest &request) const { | ||||
// Return immediately if in warmup | // Return immediately if in warmup | ||||
{ | { | ||||
jasonbcoxAuthorUnsubmitted Done Inline ActionsVerify and comment regarding warmup and node state jasonbcox: Verify and comment regarding warmup and node state | |||||
LOCK(cs_rpcWarmup); | LOCK(cs_rpcWarmup); | ||||
deadalnixUnsubmitted Done Inline ActionsClearly, it assumed this function may be called from multiple threads or even before warmup has finished, and that this function would be thread safe in such instance. deadalnix: Clearly, it assumed this function may be called from multiple threads or even before warmup has… | |||||
if (fRPCInWarmup) { | if (fRPCInWarmup) { | ||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | ||||
} | } | ||||
} | } | ||||
// TODO Only call tableRPC.execute() if no context-sensitive RPC command | std::string commandName = request.strMethod; | ||||
// exists | RPCCommand *command = MatchCommand(commandName); | ||||
deadalnixUnsubmitted Done Inline ActionsSo certainly there is some mechanism making sure this stay alive whatever other threads do while it is being used. deadalnix: So certainly there is some mechanism making sure this stay alive whatever other threads do… | |||||
jasonbcoxAuthorUnsubmitted Done Inline ActionsI need to use RWCollection jasonbcox: I need to use RWCollection | |||||
if (command != nullptr) { | |||||
try { | |||||
return command->Execute(request.params); | |||||
} catch (const std::exception &e) { | |||||
throw JSONRPCError(RPC_MISC_ERROR, e.what()); | |||||
deadalnixUnsubmitted Done Inline ActionsDoes tableRPC does this ? If not, what is the reason behind this behavior change ? deadalnix: Does tableRPC does this ? If not, what is the reason behind this behavior change ? | |||||
jasonbcoxAuthorUnsubmitted Done Inline ActionsIt does. See CRPCTable::execute(...) below. jasonbcox: It does. See `CRPCTable::execute(...)` below. | |||||
} | |||||
} | |||||
// TODO Remove the below call to tableRPC.execute() and only call it for | |||||
// context-free RPC commands via an implementation of RPCCommand. | |||||
// Check if context-free RPC method is valid and execute it | // Check if context-free RPC method is valid and execute it | ||||
return tableRPC.execute(config, request); | return tableRPC.execute(config, request); | ||||
} | } | ||||
void RPCServer::RegisterCommand(std::unique_ptr<RPCCommand> command) { | |||||
if (command != nullptr) { | |||||
LOCK(cs_rpcRegister); | |||||
commands[command->GetName()] = std::move(command); | |||||
} | |||||
} | |||||
RPCCommand *RPCServer::MatchCommand(std::string name) const { | |||||
auto iter = commands.find(name); | |||||
if (iter == commands.end()) { | |||||
return nullptr; | |||||
} | |||||
return iter->second.get(); | |||||
} | |||||
static struct CRPCSignals { | static struct CRPCSignals { | ||||
boost::signals2::signal<void()> Started; | boost::signals2::signal<void()> Started; | ||||
boost::signals2::signal<void()> Stopped; | boost::signals2::signal<void()> Stopped; | ||||
boost::signals2::signal<void(const ContextFreeRPCCommand &)> PreCommand; | boost::signals2::signal<void(const ContextFreeRPCCommand &)> PreCommand; | ||||
} g_rpcSignals; | } g_rpcSignals; | ||||
void RPCServerSignals::OnStarted(std::function<void()> slot) { | void RPCServerSignals::OnStarted(std::function<void()> slot) { | ||||
g_rpcSignals.Started.connect(slot); | g_rpcSignals.Started.connect(slot); | ||||
▲ Show 20 Lines • Show All 527 Lines • Show Last 20 Lines |
should not be global