mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-07 22:59:21 +00:00
* Fixed more redirected commands.
* Cleaned up the Command stack implementation. * Added framework for object_storage class that will hold variables and user-defined command lists. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1162 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+30
-17
@@ -109,10 +109,22 @@ system_method_insert(const torrent::Object::list_type& args) {
|
||||
rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, slot, flags, NULL, NULL);
|
||||
|
||||
} else if (options.find("simple") != std::string::npos) {
|
||||
rpc::Command::any_slot slot = &rpc::CommandFunction::call;
|
||||
rpc::Command* command = new rpc::CommandFunction(system_method_generate_command(++itrArgs, args.end()));
|
||||
rpc::command_base* command = new rpc::command_base();
|
||||
|
||||
rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, slot, flags, NULL, NULL);
|
||||
command->set_function<rpc::command_base_is_type
|
||||
<rpc::command_base_call
|
||||
<rpc::target_type> >::type>(std::tr1::bind(&rpc::command_function_call_str,
|
||||
system_method_generate_command(++itrArgs, args.end()),
|
||||
std::tr1::placeholders::_1,
|
||||
std::tr1::placeholders::_2));
|
||||
|
||||
rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, &rpc::command_base_call<rpc::target_type>,
|
||||
flags, NULL, NULL);
|
||||
|
||||
// rpc::Command::any_slot slot = &rpc::CommandFunction::call;
|
||||
// rpc::Command* command = new rpc::CommandFunction(system_method_generate_command(++itrArgs, args.end()));
|
||||
|
||||
// rpc::commands.insert_type(create_new_key<0>(rawKey, ""), command, slot, flags, NULL, NULL);
|
||||
|
||||
} else if (options.find("value") != std::string::npos ||
|
||||
options.find("bool") != std::string::npos ||
|
||||
@@ -197,29 +209,30 @@ system_method_redirect(const torrent::Object::list_type& args) {
|
||||
|
||||
torrent::Object
|
||||
system_method_get(const torrent::Object::string_type& args) {
|
||||
rpc::CommandFunction* function;
|
||||
rpc::CommandMap::iterator itr = rpc::commands.find(args.c_str());
|
||||
// rpc::CommandFunction* function;
|
||||
// rpc::CommandMap::iterator itr = rpc::commands.find(args.c_str());
|
||||
|
||||
if (itr == rpc::commands.end() ||
|
||||
(function = dynamic_cast<rpc::CommandFunction*>(itr->second.m_variable)) == NULL)
|
||||
throw torrent::input_error("Command not modifiable or wrong type.");
|
||||
// if (itr == rpc::commands.end() ||
|
||||
// (function = dynamic_cast<rpc::CommandFunction*>(itr->second.m_variable)) == NULL)
|
||||
// throw torrent::input_error("Command not modifiable or wrong type.");
|
||||
|
||||
return torrent::Object(function->command());
|
||||
// return torrent::Object(function->command());
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
system_method_set(const torrent::Object::list_type& args) {
|
||||
if (args.empty())
|
||||
throw torrent::input_error("Invalid argument count.");
|
||||
// if (args.empty())
|
||||
// throw torrent::input_error("Invalid argument count.");
|
||||
|
||||
rpc::CommandFunction* function;
|
||||
rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str());
|
||||
// rpc::CommandFunction* function;
|
||||
// rpc::CommandMap::iterator itr = rpc::commands.find(args.front().as_string().c_str());
|
||||
|
||||
if (itr == rpc::commands.end() || !rpc::commands.is_modifiable(itr) ||
|
||||
(function = dynamic_cast<rpc::CommandFunction*>(itr->second.m_variable)) == NULL)
|
||||
throw torrent::input_error("Command not modifiable or wrong type.");
|
||||
// if (itr == rpc::commands.end() || !rpc::commands.is_modifiable(itr) ||
|
||||
// (function = dynamic_cast<rpc::CommandFunction*>(itr->second.m_variable)) == NULL)
|
||||
// throw torrent::input_error("Command not modifiable or wrong type.");
|
||||
|
||||
function->set_command(system_method_generate_command(++args.begin(), args.end()));
|
||||
// function->set_command(system_method_generate_command(++args.begin(), args.end()));
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
|
||||
@@ -341,5 +341,5 @@ initialize_command_events() {
|
||||
CMD2_ANY_VALUE ("close_low_diskspace", std::tr1::bind(&apply_close_low_diskspace, std::tr1::placeholders::_2));
|
||||
|
||||
CMD2_ANY_LIST ("download_list", std::tr1::bind(&apply_download_list, std::tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST ("d.multicall", std::tr1::bind(&d_multicall, std::tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST ("d.multicall2", std::tr1::bind(&d_multicall, std::tr1::placeholders::_2));
|
||||
}
|
||||
|
||||
@@ -71,12 +71,11 @@ void initialize_commands();
|
||||
rpc::commands.insert_type(key, commandNewSlotItr++, &rpc::function, \
|
||||
rpc::CommandMap::flag_dont_delete, NULL, NULL);
|
||||
|
||||
// #define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call_any, slot, "i:", "")
|
||||
#define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
#define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
|
||||
#define CMD2_ANY_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
#define CMD2_ANY_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_ANY_L(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, slot, "A:", "")
|
||||
#define CMD2_ANY_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
#define CMD2_ANY_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_ANY_L(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, slot, "A:", "")
|
||||
|
||||
#define CMD2_ANY_VALUE(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<rpc::target_type>, slot, "i:i", "")
|
||||
#define CMD2_ANY_VALUE_V(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<rpc::target_type>, object_convert_void(slot), "i:i", "")
|
||||
|
||||
@@ -240,8 +240,8 @@ initialize_command_local() {
|
||||
CMD2_ANY("execute_capture", std::tr1::bind(&rpc::ExecFile::execute_object, &rpc::execFile, std::tr1::placeholders::_2, rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture));
|
||||
CMD2_ANY("execute_capture_nothrow", std::tr1::bind(&rpc::ExecFile::execute_object, &rpc::execFile, std::tr1::placeholders::_2, rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture));
|
||||
|
||||
CMD2_ANY_STRING("log.execute", std::tr1::bind(&apply_log, std::tr1::placeholders::_2, 0));
|
||||
CMD2_ANY_STRING("log.xmlrpc", std::tr1::bind(&apply_log, std::tr1::placeholders::_2, 1));
|
||||
CMD2_ANY_STRING ("log.execute", std::tr1::bind(&apply_log, std::tr1::placeholders::_2, 0));
|
||||
CMD2_ANY_STRING_V("log.xmlrpc", std::tr1::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::tr1::placeholders::_2));
|
||||
|
||||
// TODO: Convert to new command types:
|
||||
*rpc::Command::argument(0) = "placeholder.0";
|
||||
|
||||
@@ -611,6 +611,9 @@ main(int argc, char** argv) {
|
||||
CMD2_REDIRECT ("view_sort_current", "view.sort_current");
|
||||
CMD2_REDIRECT ("view_sort_new", "view.sort_new");
|
||||
|
||||
// Rename these to avoid conflicts with old style.
|
||||
CMD2_REDIRECT_GENERIC("d.multicall", "d.multicall2");
|
||||
|
||||
// Functions that might not get depracted as they are nice for
|
||||
// configuration files, and thus might do with just some
|
||||
// cleanup.
|
||||
|
||||
@@ -19,6 +19,8 @@ libsub_rpc_a_SOURCES = \
|
||||
command_new_slot.h \
|
||||
exec_file.cc \
|
||||
exec_file.h \
|
||||
object_storage.cc \
|
||||
object_storage.h \
|
||||
parse.cc \
|
||||
parse.h \
|
||||
parse_commands.cc \
|
||||
|
||||
@@ -157,6 +157,7 @@ public:
|
||||
static torrent::Object* stack_end() { return current_stack.end(); }
|
||||
|
||||
static torrent::Object* push_stack(const torrent::Object::list_type& args, stack_type* stack);
|
||||
static torrent::Object* push_stack(const torrent::Object* first_arg, const torrent::Object* last_arg, stack_type* stack);
|
||||
static void pop_stack(stack_type* stack, torrent::Object* last_stack);
|
||||
|
||||
protected:
|
||||
|
||||
+20
-94
@@ -49,105 +49,39 @@ namespace rpc {
|
||||
// Temp until it can be moved somewhere better...
|
||||
const torrent::Object
|
||||
command_function_call(const torrent::raw_string& cmd, target_type target, const torrent::Object& args) {
|
||||
char* buffer[sizeof(torrent::Object) * Command::max_arguments];
|
||||
torrent::Object* stack = (torrent::Object*)buffer;
|
||||
torrent::Object* first = (torrent::Object*)buffer;
|
||||
rpc::Command::stack_type stack;
|
||||
torrent::Object* last_stack;
|
||||
|
||||
if (args.is_list()) {
|
||||
// Do nothing for now.
|
||||
for (torrent::Object::list_const_iterator itr = args.as_list().begin(), last = args.as_list().end();
|
||||
itr != last && first != stack + Command::max_arguments;
|
||||
itr++, first++) {
|
||||
new (first) torrent::Object(*itr);
|
||||
first->swap(*Command::argument(std::distance(stack, first)));
|
||||
}
|
||||
|
||||
} else if (args.type() != torrent::Object::TYPE_NONE) {
|
||||
new (first) torrent::Object(args);
|
||||
(first++)->swap(*Command::argument(0));
|
||||
}
|
||||
if (args.is_list())
|
||||
last_stack = rpc::Command::push_stack(args.as_list(), &stack);
|
||||
else if (args.type() != torrent::Object::TYPE_NONE)
|
||||
last_stack = rpc::Command::push_stack(&args, &args + 1, &stack);
|
||||
else
|
||||
last_stack = rpc::Command::push_stack(NULL, NULL, &stack);
|
||||
|
||||
try {
|
||||
torrent::Object result = parse_command_multiple(target, cmd.begin(), cmd.end());
|
||||
|
||||
while (first-- != stack) {
|
||||
first->swap(*Command::argument(std::distance(stack, first)));
|
||||
first->~Object();
|
||||
}
|
||||
|
||||
rpc::Command::pop_stack(&stack, last_stack);
|
||||
return result;
|
||||
|
||||
} catch (torrent::bencode_error& e) {
|
||||
while (first-- != stack) {
|
||||
first->swap(*Command::argument(std::distance(stack, first)));
|
||||
first->~Object();
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const torrent::Object
|
||||
CommandFunction::call(Command* rawCommand, target_type target, const torrent::Object& args) {
|
||||
char* buffer[sizeof(torrent::Object) * Command::max_arguments];
|
||||
torrent::Object* stack = (torrent::Object*)buffer;
|
||||
torrent::Object* first = (torrent::Object*)buffer;
|
||||
|
||||
if (args.is_list()) {
|
||||
// Do nothing for now.
|
||||
for (torrent::Object::list_const_iterator itr = args.as_list().begin(), last = args.as_list().end();
|
||||
itr != last && first != stack + Command::max_arguments;
|
||||
itr++, first++) {
|
||||
new (first) torrent::Object(*itr);
|
||||
first->swap(*argument(std::distance(stack, first)));
|
||||
}
|
||||
|
||||
} else if (args.type() != torrent::Object::TYPE_NONE) {
|
||||
new (first) torrent::Object(args);
|
||||
(first++)->swap(*argument(0));
|
||||
}
|
||||
|
||||
CommandFunction* command = reinterpret_cast<CommandFunction*>(rawCommand);
|
||||
|
||||
try {
|
||||
torrent::Object result = parse_command_multiple(target, command->m_command.c_str(), command->m_command.c_str() + command->m_command.size());
|
||||
|
||||
while (first-- != stack) {
|
||||
first->swap(*argument(std::distance(stack, first)));
|
||||
first->~Object();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} catch (torrent::bencode_error& e) {
|
||||
while (first-- != stack) {
|
||||
first->swap(*Command::argument(std::distance(stack, first)));
|
||||
first->~Object();
|
||||
}
|
||||
|
||||
rpc::Command::pop_stack(&stack, last_stack);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const torrent::Object
|
||||
CommandFunctionList::call(Command* rawCommand, target_type target, const torrent::Object& args) {
|
||||
char* buffer[sizeof(torrent::Object) * Command::max_arguments];
|
||||
torrent::Object* stack = (torrent::Object*)buffer;
|
||||
torrent::Object* first = (torrent::Object*)buffer;
|
||||
rpc::Command::stack_type stack;
|
||||
torrent::Object* last_stack;
|
||||
|
||||
if (args.is_list()) {
|
||||
// Do nothing for now.
|
||||
for (torrent::Object::list_const_iterator itr = args.as_list().begin(), last = args.as_list().end();
|
||||
itr != last && first != stack + Command::max_arguments;
|
||||
itr++, first++) {
|
||||
new (first) torrent::Object(*itr);
|
||||
first->swap(*argument(std::distance(stack, first)));
|
||||
}
|
||||
|
||||
} else if (args.type() != torrent::Object::TYPE_NONE) {
|
||||
new (first) torrent::Object(args);
|
||||
(first++)->swap(*argument(0));
|
||||
}
|
||||
if (args.is_list())
|
||||
last_stack = rpc::Command::push_stack(args.as_list(), &stack);
|
||||
else if (args.type() != torrent::Object::TYPE_NONE)
|
||||
last_stack = rpc::Command::push_stack(&args, &args + 1, &stack);
|
||||
else
|
||||
last_stack = rpc::Command::push_stack(NULL, NULL, &stack);
|
||||
|
||||
CommandFunctionList* command = reinterpret_cast<CommandFunctionList*>(rawCommand);
|
||||
|
||||
@@ -156,19 +90,11 @@ CommandFunctionList::call(Command* rawCommand, target_type target, const torrent
|
||||
parse_command_multiple(target, itr->second.c_str(), itr->second.c_str() + itr->second.size());
|
||||
|
||||
} catch (torrent::bencode_error& e) {
|
||||
while (first-- != stack) {
|
||||
first->swap(*Command::argument(std::distance(stack, first)));
|
||||
first->~Object();
|
||||
}
|
||||
|
||||
rpc::Command::pop_stack(&stack, last_stack);
|
||||
throw e;
|
||||
}
|
||||
|
||||
while (first-- != stack) {
|
||||
first->swap(*argument(std::distance(stack, first)));
|
||||
first->~Object();
|
||||
}
|
||||
|
||||
rpc::Command::pop_stack(&stack, last_stack);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,20 +47,6 @@
|
||||
|
||||
namespace rpc {
|
||||
|
||||
class CommandFunction : public Command {
|
||||
public:
|
||||
CommandFunction(const std::string& cmd = std::string()) : m_command(cmd) {}
|
||||
|
||||
const std::string& command() const { return m_command; }
|
||||
void set_command(const std::string& cmd) { m_command = cmd; }
|
||||
|
||||
static const torrent::Object call(Command* rawCommand, target_type target, const torrent::Object& args);
|
||||
|
||||
private:
|
||||
// TODO: Replace with a delete-me flag and const char*.
|
||||
std::string m_command;
|
||||
};
|
||||
|
||||
class CommandFunctionList : public Command,
|
||||
private std::vector<std::pair<std::string, std::string> > {
|
||||
public:
|
||||
@@ -86,6 +72,11 @@ public:
|
||||
const torrent::Object
|
||||
command_function_call(const torrent::raw_string& cmd, target_type target, const torrent::Object& args);
|
||||
|
||||
inline const torrent::Object
|
||||
command_function_call_str(const std::string& cmd, target_type target, const torrent::Object& args) {
|
||||
return command_function_call(torrent::raw_string::from_string(cmd), target, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+10
-4
@@ -77,18 +77,24 @@ get_target_cast<torrent::File*>(target_type target, int type) {
|
||||
}
|
||||
|
||||
inline torrent::Object*
|
||||
Command::push_stack(const torrent::Object::list_type& args, stack_type* stack) {
|
||||
Command::push_stack(const torrent::Object* first_arg, const torrent::Object* last_arg, stack_type* stack) {
|
||||
unsigned int idx = 0;
|
||||
|
||||
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end();
|
||||
itr != last && idx < Command::max_arguments; itr++, idx++) {
|
||||
new (&(*stack)[idx]) torrent::Object(*itr);
|
||||
while (first_arg != last_arg && idx < Command::max_arguments) {
|
||||
new (&(*stack)[idx]) torrent::Object(*first_arg++);
|
||||
(*stack)[idx].swap(*Command::argument(idx));
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
return stack->begin() + idx;
|
||||
}
|
||||
|
||||
inline torrent::Object*
|
||||
Command::push_stack(const torrent::Object::list_type& args, stack_type* stack) {
|
||||
return push_stack(args.data(), args.data() + args.size(), stack);
|
||||
}
|
||||
|
||||
inline void
|
||||
Command::pop_stack(stack_type* stack, torrent::Object* last_stack) {
|
||||
while (last_stack-- != stack->begin()) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2007, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "object_storage.h"
|
||||
|
||||
namespace rpc {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2007, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
// The object_storage type is responsible for storing variables,
|
||||
// commands, command lists and other types encoded in torrent::Object
|
||||
// format.
|
||||
|
||||
#ifndef RTORRENT_RPC_OBJECT_STORAGE_H
|
||||
#define RTORRENT_RPC_OBJECT_STORAGE_H
|
||||
|
||||
#include <cstring>
|
||||
#include <tr1/unordered_set>
|
||||
#include <torrent/object.h>
|
||||
|
||||
namespace rpc {
|
||||
|
||||
// The key size should be such that the value type size which includes
|
||||
// the next-pointer.
|
||||
|
||||
struct object_storage_node_internal {
|
||||
torrent::Object object;
|
||||
char key[0];
|
||||
};
|
||||
|
||||
struct object_storage_node : public object_storage_node_internal {
|
||||
// TODO: Use the size of the unordered_map::value_type with a struct {}.
|
||||
static const size_t key_size = 128 - sizeof(object_storage_node_internal) - sizeof(void*);
|
||||
};
|
||||
|
||||
struct hash_object_storage_node {
|
||||
inline std::size_t operator () (const object_storage_node& p);
|
||||
};
|
||||
|
||||
bool operator == (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) == 0; }
|
||||
bool operator != (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) != 0; }
|
||||
bool operator < (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) < 0; }
|
||||
bool operator <= (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) <= 0; }
|
||||
bool operator > (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) > 0; }
|
||||
bool operator >= (const object_storage_node& left, const object_storage_node& right) { return std::strcmp(left.key, right.key) >= 0; }
|
||||
|
||||
class object_storage : private std::tr1::unordered_set<object_storage_node, hash_object_storage_node> {
|
||||
typedef std::tr1::unordered_set<object_storage_node, hash_object_storage_node> base_type;
|
||||
|
||||
using base_type::iterator;
|
||||
};
|
||||
|
||||
inline std::size_t
|
||||
hash_object_storage_node::operator () (const object_storage_node& p) {
|
||||
std::size_t result = 0;
|
||||
const char* first = p.key;
|
||||
|
||||
while (*first != '\0')
|
||||
result = (result * 131) + *first++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -229,8 +229,15 @@ SCgiTask::receive_write(const char* buffer, uint32_t length) {
|
||||
m_bufferSize = length + headerSize;
|
||||
|
||||
std::memcpy(m_buffer + headerSize, buffer, length);
|
||||
event_write();
|
||||
|
||||
if (m_parent->log_fd() >= 0) {
|
||||
// Clean up logging, this is just plain ugly...
|
||||
// write(m_logFd, "\n---\n", sizeof("\n---\n"));
|
||||
write(m_parent->log_fd(), m_buffer, m_bufferSize);
|
||||
write(m_parent->log_fd(), "\n---\n", sizeof("\n---\n"));
|
||||
}
|
||||
|
||||
event_write();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cassert>
|
||||
#include <rak/path.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "core/manager.h"
|
||||
@@ -67,6 +70,8 @@ ThreadWorker::set_scgi(rpc::SCgi* scgi) {
|
||||
if (!__sync_bool_compare_and_swap(&m_safe.scgi, NULL, scgi))
|
||||
return false;
|
||||
|
||||
change_xmlrpc_log();
|
||||
|
||||
// The xmlrpc process call requires a global lock.
|
||||
// m_safe.scgi->set_slot_process(rak::mem_fn(&rpc::xmlrpc, &rpc::XmlRpc::process));
|
||||
|
||||
@@ -77,6 +82,13 @@ ThreadWorker::set_scgi(rpc::SCgi* scgi) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ThreadWorker::set_xmlrpc_log(const std::string& filename) {
|
||||
m_xmlrpcLog = filename;
|
||||
|
||||
queue_item((thread_base_func)&msg_change_xmlrpc_log);
|
||||
}
|
||||
|
||||
void
|
||||
ThreadWorker::start_scgi(ThreadBase* baseThread) {
|
||||
ThreadWorker* thread = (ThreadWorker*)baseThread;
|
||||
@@ -95,6 +107,38 @@ ThreadWorker::start_log_counter(ThreadBase* baseThread) {
|
||||
priority_queue_insert(&thread->m_taskScheduler, &thread->m_taskTouchLog, cachedTime);
|
||||
}
|
||||
|
||||
void
|
||||
ThreadWorker::msg_change_xmlrpc_log(ThreadBase* baseThread) {
|
||||
ThreadWorker* thread = (ThreadWorker*)baseThread;
|
||||
|
||||
acquire_global_lock();
|
||||
thread->change_xmlrpc_log();
|
||||
release_global_lock();
|
||||
}
|
||||
|
||||
void
|
||||
ThreadWorker::change_xmlrpc_log() {
|
||||
if (scgi() == NULL)
|
||||
return;
|
||||
|
||||
if (scgi()->log_fd() != -1)
|
||||
::close(scgi()->log_fd());
|
||||
|
||||
if (m_xmlrpcLog.empty()) {
|
||||
control->core()->push_log("Closed XMLRPC log.");
|
||||
return;
|
||||
}
|
||||
|
||||
scgi()->set_log_fd(open(rak::path_expand(m_xmlrpcLog).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644));
|
||||
|
||||
if (scgi()->log_fd() == -1) {
|
||||
control->core()->push_log_std("Could not open XMLRPC log file '" + m_xmlrpcLog + "'.");
|
||||
return;
|
||||
}
|
||||
|
||||
control->core()->push_log_std("Logging XMLRPC events to '" + m_xmlrpcLog + "'.");
|
||||
}
|
||||
|
||||
void
|
||||
ThreadWorker::task_touch_log() {
|
||||
priority_queue_insert(&m_taskScheduler, &m_taskTouchLog, cachedTime + rak::timer::from_seconds(1));
|
||||
|
||||
+10
-2
@@ -58,13 +58,16 @@ public:
|
||||
rpc::SCgi* scgi() { return m_safe.scgi; }
|
||||
bool set_scgi(rpc::SCgi* scgi);
|
||||
|
||||
void set_xmlrpc_log(const std::string& filename);
|
||||
|
||||
static void start_scgi(ThreadBase* thread);
|
||||
static void start_log_counter(ThreadBase* thread);
|
||||
static void msg_change_xmlrpc_log(ThreadBase* thread);
|
||||
|
||||
private:
|
||||
void task_touch_log();
|
||||
|
||||
rak::priority_item m_taskTouchLog;
|
||||
void change_xmlrpc_log();
|
||||
|
||||
struct lt_cacheline_aligned safe_type {
|
||||
safe_type() : scgi(NULL) {}
|
||||
@@ -72,7 +75,12 @@ private:
|
||||
rpc::SCgi* scgi;
|
||||
};
|
||||
|
||||
safe_type m_safe;
|
||||
rak::priority_item m_taskTouchLog;
|
||||
safe_type m_safe;
|
||||
|
||||
// The following types shall only be modified while holding the
|
||||
// global lock.
|
||||
std::string m_xmlrpcLog;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user