This commit is contained in:
Daniel Larimer 2015-01-29 17:01:19 -05:00
commit 633c889ce3
12 changed files with 406 additions and 86 deletions

View file

@ -86,15 +86,6 @@ ENDIF()
find_package(OpenSSL)
IF(APPLE)
# As of 10.10 yosemite, the OpenSSL static libraries shipped with os x have a dependency
# on zlib, so any time you link in openssl you also need to link zlib. . We really want to detect whether openssl was configured with the --no-zlib
# option or not when it was built, but that's difficult to do in practice, so we
# just always try to link it in on mac.
find_package( ZLIB REQUIRED )
ENDIF(APPLE)
set( CMAKE_FIND_LIBRARY_SUFFIXES ${ORIGINAL_LIB_SUFFIXES} )
option( UNITY_BUILD OFF )
@ -137,6 +128,7 @@ set( fc_sources
src/log/appender.cpp
src/log/console_appender.cpp
src/log/file_appender.cpp
src/log/gelf_appender.cpp
src/log/logger_config.cpp
src/crypto/openssl.cpp
src/crypto/aes.cpp
@ -353,6 +345,14 @@ if(WIN32)
endif(WIN32)
IF(APPLE)
# As of 10.10 yosemite, the OpenSSL static libraries shipped with os x have a dependency
# on zlib, so any time you link in openssl you also need to link zlib. . We really want to detect whether openssl was configured with the --no-zlib
# option or not when it was built, but that's difficult to do in practice, so we
# just always try to link it in on mac.
find_package( ZLIB REQUIRED )
ENDIF(APPLE)
SET(OPENSSL_CONF_TARGET )
IF(DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
SET (OPENSSL_CONF_TARGET ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

View file

@ -298,21 +298,26 @@ namespace fc
* @brief Checks a condition and throws an assert_exception if the test is FALSE
*/
#define FC_ASSERT( TEST, ... ) \
FC_EXPAND_MACRO( \
do { if( !(TEST) ) { FC_THROW_EXCEPTION( fc::assert_exception, #TEST ": " __VA_ARGS__ ); } } while(0) \
)
FC_EXPAND_MACRO( \
FC_MULTILINE_MACRO_BEGIN \
if( !(TEST) ) \
FC_THROW_EXCEPTION( fc::assert_exception, #TEST ": " __VA_ARGS__ ); \
FC_MULTILINE_MACRO_END \
)
#define FC_CAPTURE_AND_THROW( EXCEPTION_TYPE, ... ) \
do { throw EXCEPTION_TYPE( FC_LOG_MESSAGE( error, "", FC_FORMAT_ARG_PARAMS(__VA_ARGS__) ) ); } while(0)
FC_MULTILINE_MACRO_BEGIN \
throw EXCEPTION_TYPE( FC_LOG_MESSAGE( error, "", FC_FORMAT_ARG_PARAMS(__VA_ARGS__) ) ); \
FC_MULTILINE_MACRO_END
//#define FC_THROW( FORMAT, ... )
// FC_INDIRECT_EXPAND workas around a bug in Visual C++ variadic macro processing that prevents it
// from separating __VA_ARGS__ into separate tokens
#define FC_INDIRECT_EXPAND(MACRO, ARGS) MACRO ARGS
#define FC_THROW( ... ) \
do { \
throw fc::exception( FC_INDIRECT_EXPAND(FC_LOG_MESSAGE, ( error, __VA_ARGS__ )) ); \
} while(0)
FC_MULTILINE_MACRO_BEGIN \
throw fc::exception( FC_INDIRECT_EXPAND(FC_LOG_MESSAGE, ( error, __VA_ARGS__ )) ); \
FC_MULTILINE_MACRO_END
#define FC_EXCEPTION( EXCEPTION_TYPE, FORMAT, ... ) \
EXCEPTION_TYPE( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) )
@ -322,9 +327,9 @@ namespace fc
* @param format - a const char* string with "${keys}"
*/
#define FC_THROW_EXCEPTION( EXCEPTION, FORMAT, ... ) \
do { \
throw EXCEPTION( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
} while(0)
FC_MULTILINE_MACRO_BEGIN \
throw EXCEPTION( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
FC_MULTILINE_MACRO_END
/**
@ -332,10 +337,10 @@ namespace fc
* @brief Appends a log_message to the exception ER and rethrows it.
*/
#define FC_RETHROW_EXCEPTION( ER, LOG_LEVEL, FORMAT, ... ) \
do { \
ER.append_log( FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, __VA_ARGS__ ) ); \
throw;\
} while(0)
FC_MULTILINE_MACRO_BEGIN \
ER.append_log( FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, __VA_ARGS__ ) ); \
throw; \
FC_MULTILINE_MACRO_END
#define FC_LOG_AND_RETHROW( ) \
catch( fc::exception& er ) { \

View file

@ -1,5 +1,7 @@
#pragma once
#include <utility>
#include <memory>
#include <fc/string.hpp>
#include <fc/reflect/typename.hpp>
#include <fc/optional.hpp>
@ -226,5 +228,37 @@ namespace fc {
temp_directory(const fc::path& tempFolder = fc::temp_directory_path());
};
#if !defined(__APPLE__)
// this code is known to work on linux and windows. It may work correctly on mac,
// or it may need slight tweaks or extra includes. It's disabled now to avoid giving
// a false sense of security.
# define FC_HAS_SIMPLE_FILE_LOCK
#endif
#ifdef FC_HAS_SIMPLE_FILE_LOCK
/** simple class which only allows one process to open any given file.
* approximate usage:
* int main() {
* fc::simple_file_lock instance_lock("~/.my_app/.lock");
* if (!instance_lock.try_lock()) {
* elog("my_app is already running");
* return 1;
* }
* // do stuff here, file will be unlocked when instance_lock goes out of scope
* }
*/
class simple_lock_file
{
public:
simple_lock_file(const path& lock_file_path);
~simple_lock_file();
bool try_lock();
void unlock();
private:
class impl;
std::unique_ptr<impl> my;
};
#endif // FC_HAS_SIMPLE_FILE_LOCK
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <fc/log/appender.hpp>
#include <fc/log/logger.hpp>
#include <fc/time.hpp>
namespace fc
{
// Log appender that sends log messages in JSON format over UDP
// https://www.graylog2.org/resources/gelf/specification
class gelf_appender : public appender
{
public:
struct config
{
string endpoint = "127.0.0.1:12201";
string host = "fc"; // the name of the host, source or application that sent this message (just passed through to GELF server)
};
gelf_appender(const variant& args);
~gelf_appender();
virtual void log(const log_message& m) override;
private:
class impl;
fc::shared_ptr<impl> my;
};
} // namespace fc
#include <fc/reflect/reflect.hpp>
FC_REFLECT(fc::gelf_appender::config,
(endpoint)(host))

View file

@ -61,74 +61,77 @@ namespace fc
#define DEFAULT_LOGGER
#endif
// suppress warning "conditional expression is constant" in the while(0) for visual c++
// http://cnicholson.net/2009/03/stupid-c-tricks-dowhile0-and-c4127/
#define FC_MULTILINE_MACRO_BEGIN do {
#ifdef _MSC_VER
# define FC_MULTILINE_MACRO_END \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
} while (0) \
__pragma(warning(pop))
#else
# define FC_MULTILINE_MACRO_END } while (0)
#endif
#define fc_dlog( LOGGER, FORMAT, ... ) \
do { \
if( (LOGGER).is_enabled( fc::log_level::debug ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (LOGGER).is_enabled( fc::log_level::debug ) ) \
(LOGGER).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define fc_ilog( LOGGER, FORMAT, ... ) \
do { \
if( (LOGGER).is_enabled( fc::log_level::info ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (LOGGER).is_enabled( fc::log_level::info ) ) \
(LOGGER).log( FC_LOG_MESSAGE( info, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define fc_wlog( LOGGER, FORMAT, ... ) \
do { \
if( (LOGGER).is_enabled( fc::log_level::warn ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (LOGGER).is_enabled( fc::log_level::warn ) ) \
(LOGGER).log( FC_LOG_MESSAGE( warn, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define fc_elog( LOGGER, FORMAT, ... ) \
do { \
if( (LOGGER).is_enabled( fc::log_level::error ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (LOGGER).is_enabled( fc::log_level::error ) ) \
(LOGGER).log( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define dlog( FORMAT, ... ) \
do { \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::debug ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::debug ) ) \
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
/**
* Sends the log message to a special 'user' log stream designed for messages that
* the end user may like to see.
*/
#define ulog( FORMAT, ... ) \
do { \
if( (fc::logger::get("user")).is_enabled( fc::log_level::debug ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (fc::logger::get("user")).is_enabled( fc::log_level::debug ) ) \
(fc::logger::get("user")).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define ilog( FORMAT, ... ) \
do { \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::info ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::info ) ) \
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( info, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define wlog( FORMAT, ... ) \
do { \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::warn ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::warn ) ) \
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( warn, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#define elog( FORMAT, ... ) \
do { \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::error ) ) { \
FC_MULTILINE_MACRO_BEGIN \
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::error ) ) \
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
} \
} while (0)
FC_MULTILINE_MACRO_END
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/enum.hpp>
@ -164,13 +167,13 @@ namespace fc
// a slowdown.
#ifdef FC_DISABLE_LOGGING
# undef ulog
# define ulog(...) do {} while(0)
# define ulog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
# undef elog
# define elog(...) do {} while(0)
# define elog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
# undef wlog
# define wlog(...) do {} while(0)
# define wlog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
# undef ilog
# define ilog(...) do {} while(0)
# define ilog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
# undef dlog
# define dlog(...) do {} while(0)
# define dlog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
#endif

View file

@ -618,7 +618,7 @@ std::string to_base58( const std::vector<char>& d )
std::vector<char> from_base58( const std::string& base58_str ) {
std::vector<unsigned char> out;
if( !DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
}
return std::vector<char>((const char*)out.data(), ((const char*)out.data())+out.size() );
}
@ -629,7 +629,7 @@ size_t from_base58( const std::string& base58_str, char* out_data, size_t out_da
//slog( "%s", base58_str.c_str() );
std::vector<unsigned char> out;
if( !DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
}
memcpy( out_data, out.data(), out.size() );

View file

@ -19,6 +19,10 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
# ifdef FC_HAS_SIMPLE_FILE_LOCK
#include <sys/file.h>
#include <fcntl.h>
# endif
#endif
namespace fc {
@ -495,4 +499,101 @@ namespace fc {
return appCurrentPath;
}
#ifdef FC_HAS_SIMPLE_FILE_LOCK
class simple_lock_file::impl
{
public:
#ifdef _WIN32
HANDLE file_handle;
#else
int file_handle;
#endif
bool is_locked;
path lock_file_path;
impl(const path& lock_file_path);
~impl();
bool try_lock();
void unlock();
};
simple_lock_file::impl::impl(const path& lock_file_path) :
is_locked(false),
lock_file_path(lock_file_path),
#ifdef _WIN32
file_handle(INVALID_HANDLE_VALUE)
#else
file_handle(-1)
#endif
{}
simple_lock_file::impl::~impl()
{
unlock();
}
bool simple_lock_file::impl::try_lock()
{
#ifdef _WIN32
HANDLE fh = CreateFileA(lock_file_path.to_native_ansi_path().c_str(),
GENERIC_READ | GENERIC_WRITE,
0, 0,
OPEN_ALWAYS, 0, NULL);
if (fh == INVALID_HANDLE_VALUE)
return false;
is_locked = true;
file_handle = fh;
return true;
#else
int fd = open(lock_file_path.string().c_str(), O_RDWR|O_CREAT, 0644);
if (fd < 0)
return false;
if (flock(fd, LOCK_EX|LOCK_NB) == -1)
{
close(fd);
return false;
}
is_locked = true;
file_handle = fd;
return true;
#endif
}
void simple_lock_file::impl::unlock()
{
#ifdef WIN32
CloseHandle(file_handle);
file_handle = INVALID_HANDLE_VALUE;
is_locked = false;
#else
flock(file_handle, LOCK_UN);
close(file_handle);
file_handle = -1;
is_locked = false;
#endif
}
simple_lock_file::simple_lock_file(const path& lock_file_path) :
my(new impl(lock_file_path))
{
}
simple_lock_file::~simple_lock_file()
{
}
bool simple_lock_file::try_lock()
{
return my->try_lock();
}
void simple_lock_file::unlock()
{
my->unlock();
}
#endif // FC_HAS_SIMPLE_FILE_LOCK
}

View file

@ -7,6 +7,7 @@
#include <fc/thread/scoped_lock.hpp>
#include <fc/log/console_appender.hpp>
#include <fc/log/file_appender.hpp>
#include <fc/log/gelf_appender.hpp>
#include <fc/variant.hpp>
#include "console_defines.h"
@ -45,4 +46,6 @@ namespace fc {
static bool reg_console_appender = appender::register_appender<console_appender>( "console" );
static bool reg_file_appender = appender::register_appender<file_appender>( "file" );
static bool reg_gelf_appender = appender::register_appender<gelf_appender>( "gelf" );
} // namespace fc

139
src/log/gelf_appender.cpp Normal file
View file

@ -0,0 +1,139 @@
#include <fc/network/udp_socket.hpp>
#include <fc/network/ip.hpp>
#include <fc/network/resolve.hpp>
#include <fc/exception/exception.hpp>
#include <fc/log/gelf_appender.hpp>
#include <fc/reflect/variant.hpp>
#include <fc/thread/scoped_lock.hpp>
#include <fc/thread/thread.hpp>
#include <fc/variant.hpp>
#include <fc/io/json.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/lexical_cast.hpp>
#include <iomanip>
#include <queue>
#include <sstream>
namespace fc
{
class gelf_appender::impl : public retainable
{
public:
config cfg;
optional<ip::endpoint> gelf_endpoint;
udp_socket gelf_socket;
boost::mutex socket_mutex;
impl(const config& c) :
cfg(c)
{
}
~impl()
{
}
};
gelf_appender::gelf_appender(const variant& args) :
my(new impl(args.as<config>()))
{
try
{
try
{
// if it's a numeric address:port, this will parse it
my->gelf_endpoint = ip::endpoint::from_string(my->cfg.endpoint);
}
catch (...)
{
}
if (!my->gelf_endpoint)
{
// couldn't parse as a numeric ip address, try resolving as a DNS name.
// This can yield, so don't do it in the catch block above
string::size_type colon_pos = my->cfg.endpoint.find(':');
try
{
uint16_t port = boost::lexical_cast<uint16_t>(my->cfg.endpoint.substr(colon_pos + 1, my->cfg.endpoint.size()));
string hostname = my->cfg.endpoint.substr( 0, colon_pos );
std::vector<ip::endpoint> endpoints = resolve(hostname, port);
if (endpoints.empty())
FC_THROW_EXCEPTION(unknown_host_exception, "The host name can not be resolved: ${hostname}",
("hostname", hostname));
my->gelf_endpoint = endpoints.back();
}
catch (const boost::bad_lexical_cast&)
{
FC_THROW("Bad port: ${port}", ("port", my->cfg.endpoint.substr(colon_pos + 1, my->cfg.endpoint.size())));
}
}
if (my->gelf_endpoint)
my->gelf_socket.open();
}
catch (...)
{
std::cerr << "error opening GELF socket to endpoint ${endpoint}" << my->cfg.endpoint << "\n";
}
}
gelf_appender::~gelf_appender()
{}
void gelf_appender::log(const log_message& message)
{
if (!my->gelf_endpoint)
return;
log_context context = message.get_context();
mutable_variant_object gelf_message;
gelf_message["version"] = "1.1";
gelf_message["host"] = my->cfg.host;
gelf_message["short_message"] = format_string(message.get_format(), message.get_data());
gelf_message["timestamp"] = context.get_timestamp().time_since_epoch().count() / 1000000.;
switch (context.get_log_level())
{
case log_level::debug:
gelf_message["level"] = 7; // debug
break;
case log_level::info:
gelf_message["level"] = 6; // info
break;
case log_level::warn:
gelf_message["level"] = 4; // warning
break;
case log_level::error:
gelf_message["level"] = 3; // error
break;
case log_level::all:
case log_level::off:
// these shouldn't be used in log messages, but do something deterministic just in case
gelf_message["level"] = 6; // info
break;
}
if (!context.get_context().empty())
gelf_message["context"] = context.get_context();
gelf_message["_line"] = context.get_line_number();
gelf_message["_file"] = context.get_file();
gelf_message["_method_name"] = context.get_method();
gelf_message["_thread_name"] = context.get_thread_name();
if (!context.get_task_name().empty())
gelf_message["_task_name"] = context.get_task_name();
string gelf_message_as_string = json::to_string(gelf_message);
std::shared_ptr<char> send_buffer(new char[gelf_message_as_string.size()], [](char* p){ delete[] p; });
memcpy(send_buffer.get(), gelf_message_as_string.c_str(), gelf_message_as_string.size());
{
scoped_lock<boost::mutex> lock(my->socket_mutex);
my->gelf_socket.send_to(send_buffer, gelf_message_as_string.size(), *my->gelf_endpoint);
}
}
} // fc

View file

@ -83,7 +83,9 @@ namespace fc
void log_context::append_context( const fc::string& s )
{
my->context += "->" + s;
if (!my->context.empty())
my->context += " -> ";
my->context += s;
}
log_context::~log_context(){}
@ -158,6 +160,7 @@ namespace fc
string log_context::get_host_name()const { return my->hostname; }
time_point log_context::get_timestamp()const { return my->timestamp; }
log_level log_context::get_log_level()const{ return my->level; }
string log_context::get_context()const { return my->context; }
variant log_context::to_variant()const

View file

@ -25,7 +25,7 @@ namespace fc { namespace http {
case fc::http::reply::RecordCreated: ss << "Record Created\r\n"; break;
case fc::http::reply::NotFound: ss << "Not Found\r\n"; break;
case fc::http::reply::Found: ss << "Found\r\n"; break;
case fc::http::reply::InternalServerError: ss << "Internal Server Error\r\n"; break;
default: ss << "Internal Server Error\r\n"; break;
}
for( uint32_t i = 0; i < rep.headers.size(); ++i ) {
ss << rep.headers[i].key <<": "<<rep.headers[i].val <<"\r\n";

View file

@ -43,8 +43,8 @@ namespace fc { namespace rpc {
*_out << ",\"result\":";
json::to_stream( *_out, result);
*_out << "}\n";
_out->flush();
}
_out->flush();
}
void send_error( variant id, fc::exception& e )
{
@ -59,9 +59,9 @@ namespace fc { namespace rpc {
*_out <<",\"code\":0,\"data\":";
json::to_stream( *_out, variant(e));
*_out << "}}\n";
_out->flush();
}
//wlog( "exception: ${except}", ("except", variant(e)) );
_out->flush();
}
void handle_message( const variant_object& obj )
@ -306,8 +306,8 @@ namespace fc { namespace rpc {
*my->_out << ",\"params\":";
fc::json::to_stream( *my->_out, named_args );
*my->_out << "}\n";
my->_out->flush();
}
my->_out->flush();
}
void json_connection::notice( const fc::string& method )
{
@ -316,8 +316,8 @@ namespace fc { namespace rpc {
*my->_out << "{\"method\":";
json::to_stream( *my->_out, method );
*my->_out << "}\n";
my->_out->flush();
}
my->_out->flush();
}
@ -342,8 +342,8 @@ namespace fc { namespace rpc {
{
*my->_out << ",\"params\":[]}\n";
}
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
@ -361,8 +361,8 @@ namespace fc { namespace rpc {
*my->_out << ",\"params\":[";
fc::json::to_stream( *my->_out, a1 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2 )
@ -381,8 +381,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a2 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3 )
@ -403,8 +403,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a3 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
@ -428,8 +428,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a4 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
@ -455,8 +455,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a5 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
@ -484,8 +484,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a6 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5, const variant& a6, const variant& a7 )
@ -514,8 +514,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a7 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method,
@ -554,8 +554,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a8 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method,
@ -597,8 +597,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a9 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method,
@ -643,8 +643,8 @@ namespace fc { namespace rpc {
*my->_out << ",";
fc::json::to_stream( *my->_out, a10 );
*my->_out << "]}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
@ -665,8 +665,8 @@ namespace fc { namespace rpc {
*my->_out << ",\"params\":";
fc::json::to_stream( *my->_out, named_args );
*my->_out << "}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}
future<variant> json_connection::async_call( const fc::string& method )
@ -680,8 +680,8 @@ namespace fc { namespace rpc {
*my->_out << ",\"method\":";
json::to_stream( *my->_out, method );
*my->_out << "}\n";
my->_out->flush();
}
my->_out->flush();
return my->_awaiting[id];
}