mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 21:22:31 +00:00
* Cleaned up obsolete scheduler framework.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1071 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -434,11 +434,11 @@ initialize_command_download() {
|
||||
ADD_CD_LIST("delete_link", rak::bind_ptr_fn(&apply_d_change_link, 1));
|
||||
ADD_CD_V_VOID("delete_tied", &apply_d_delete_tied);
|
||||
|
||||
CMD_FUNC_SINGLE("d.start", "d.set_hashing_failed=0 ;d.set_state=1 ;view.set_not_visible=stopped ;view.set_visible=started");
|
||||
CMD_FUNC_SINGLE("d.stop", "d.set_state=0 ;view.set_visible=stopped ;view.set_not_visible=started");
|
||||
CMD_FUNC_SINGLE("d.try_start", "branch=\"or={d.get_hashing_failed=,d.get_ignore_commands=}\",{},{d.set_state=1,view.set_not_visible=stopped,view.set_visible=started}");
|
||||
CMD_FUNC_SINGLE("d.try_stop", "branch=d.get_ignore_commands=, {}, {d.set_state=0, view.set_visible=stopped, view.set_not_visible=started}");
|
||||
CMD_FUNC_SINGLE("d.try_close", "branch=d.get_ignore_commands=, {}, {d.set_state=0, view.set_visible=stopped, view.set_not_visible=started, d.close=}");
|
||||
CMD_FUNC_SINGLE("d.start", "d.set_hashing_failed=0 ;view.set_visible=started");
|
||||
CMD_FUNC_SINGLE("d.stop", "view.set_visible=stopped");
|
||||
CMD_FUNC_SINGLE("d.try_start", "branch=\"or={d.get_hashing_failed=,d.get_ignore_commands=}\",{},{view.set_visible=started}");
|
||||
CMD_FUNC_SINGLE("d.try_stop", "branch=d.get_ignore_commands=, {}, {view.set_visible=stopped}");
|
||||
CMD_FUNC_SINGLE("d.try_close", "branch=d.get_ignore_commands=, {}, {view.set_visible=stopped, d.close=}");
|
||||
|
||||
ADD_CD_F_VOID("resume", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::resume_default));
|
||||
ADD_CD_F_VOID("pause", rak::make_mem_fun(control->core()->download_list(), &core::DownloadList::pause_default));
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "core/manager.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/view_manager.h"
|
||||
#include "core/scheduler.h"
|
||||
#include "core/dht_manager.h"
|
||||
|
||||
#include "display/canvas.h"
|
||||
@@ -75,7 +74,6 @@ Control::Control() :
|
||||
|
||||
m_core = new core::Manager();
|
||||
m_viewManager = new core::ViewManager();
|
||||
m_scheduler = new core::Scheduler(m_core->download_list());
|
||||
m_dhtManager = new core::DhtManager();
|
||||
|
||||
m_inputStdin->slot_pressed(sigc::mem_fun(m_input, &input::Manager::pressed));
|
||||
@@ -96,7 +94,6 @@ Control::~Control() {
|
||||
delete m_ui;
|
||||
delete m_display;
|
||||
delete m_core;
|
||||
delete m_scheduler;
|
||||
delete m_dhtManager;
|
||||
}
|
||||
|
||||
@@ -114,7 +111,6 @@ Control::initialize() {
|
||||
m_core->download_store()->enable(rpc::call_command_value("get_session_lock"));
|
||||
|
||||
m_core->set_hashing_view(*m_viewManager->find_throw("hashing"));
|
||||
m_scheduler->set_view(*m_viewManager->find_throw("scheduler"));
|
||||
|
||||
m_ui->init(this);
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace ui {
|
||||
namespace core {
|
||||
class Manager;
|
||||
class ViewManager;
|
||||
class Scheduler;
|
||||
class DhtManager;
|
||||
}
|
||||
|
||||
@@ -90,7 +89,6 @@ public:
|
||||
|
||||
core::Manager* core() { return m_core; }
|
||||
core::ViewManager* view_manager() { return m_viewManager; }
|
||||
core::Scheduler* scheduler() { return m_scheduler; }
|
||||
core::DhtManager* dht_manager() { return m_dhtManager; }
|
||||
|
||||
torrent::Poll* poll();
|
||||
@@ -120,7 +118,6 @@ private:
|
||||
|
||||
core::Manager* m_core;
|
||||
core::ViewManager* m_viewManager;
|
||||
core::Scheduler* m_scheduler;
|
||||
core::DhtManager* m_dhtManager;
|
||||
|
||||
ui::Root* m_ui;
|
||||
|
||||
@@ -32,8 +32,6 @@ libsub_core_a_SOURCES = \
|
||||
poll_manager_kqueue.h \
|
||||
poll_manager_select.cc \
|
||||
poll_manager_select.h \
|
||||
scheduler.cc \
|
||||
scheduler.h \
|
||||
view.cc \
|
||||
view.h \
|
||||
view_manager.cc \
|
||||
|
||||
@@ -262,14 +262,19 @@ DownloadFactory::receive_success() {
|
||||
if (m_session) {
|
||||
// This torrent was queued for hashing or hashing when the
|
||||
// session file was saved. Or it was in a started state.
|
||||
if (rpc::call_command_value("d.get_hashing", rpc::make_target(download)) != Download::variable_hashing_stopped ||
|
||||
if (//rpc::call_command_value("d.get_hashing", rpc::make_target(download)) != Download::variable_hashing_stopped ||
|
||||
rpc::call_command_value("d.get_state", rpc::make_target(download)) != 0)
|
||||
m_manager->download_list()->resume(download);
|
||||
// m_manager->download_list()->resume(download);
|
||||
rpc::parse_command_single(rpc::make_target(download), "view.set_visible=started");
|
||||
else
|
||||
rpc::parse_command_single(rpc::make_target(download), "view.set_visible=stopped");
|
||||
|
||||
} else {
|
||||
// Use the state thingie here, move below.
|
||||
if (m_start)
|
||||
rpc::parse_command_single(rpc::make_target(download), "d.start=");
|
||||
else
|
||||
rpc::parse_command_single(rpc::make_target(download), "view.set_visible=stopped");
|
||||
|
||||
m_manager->download_store()->save(download);
|
||||
}
|
||||
|
||||
@@ -72,20 +72,6 @@ DownloadList::check_contains(Download* d) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// struct download_list_call {
|
||||
// download_list_call(Download* d) : m_download(d) {}
|
||||
|
||||
// void operator () (const DownloadList::slot_map::value_type& s) {
|
||||
// try {
|
||||
// rpc::parse_command_d_multiple_std(m_download, s.second);
|
||||
// } catch (torrent::input_error& e) {
|
||||
// control->core()->push_log((std::string("Download event action failed: ") + e.what()).c_str());
|
||||
// }
|
||||
// }
|
||||
|
||||
// Download* m_download;
|
||||
// };
|
||||
|
||||
void
|
||||
DownloadList::clear() {
|
||||
std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadList::close), this));
|
||||
|
||||
@@ -39,9 +39,7 @@
|
||||
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sigc++/functors/slot.h>
|
||||
|
||||
namespace torrent {
|
||||
class HashString;
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
// 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 <algorithm>
|
||||
#include <rak/functional.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
#include "scheduler.h"
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
// Change to unlimited.
|
||||
Scheduler::Scheduler(DownloadList* dl) :
|
||||
m_view(NULL),
|
||||
m_downloadList(dl),
|
||||
|
||||
m_maxActive(2),
|
||||
m_cycle(1) {
|
||||
}
|
||||
|
||||
Scheduler::~Scheduler() {
|
||||
}
|
||||
|
||||
void
|
||||
Scheduler::set_view(View* view) {
|
||||
m_view = view;
|
||||
}
|
||||
|
||||
Scheduler::size_type
|
||||
Scheduler::active() const {
|
||||
return std::count_if(m_view->begin_visible(), m_view->end_visible(), std::mem_fun(&Download::is_active));
|
||||
}
|
||||
|
||||
void
|
||||
Scheduler::update() {
|
||||
// size_type curActive = active();
|
||||
// size_type curInactive = m_view->size() - curActive;
|
||||
|
||||
// Hmm... Perhaps we should use a more complex sorting thingie.
|
||||
// m_view->sort();
|
||||
|
||||
// Just a hack for now, need to take into consideration how many
|
||||
// inactive we can switch with.
|
||||
// size_type target = m_maxActive - std::min(m_cycle, m_maxActive);
|
||||
|
||||
// for (View::iterator itr = m_view->begin_visible(), last = m_view->end_visible(); curActive > target; ++itr) {
|
||||
// if (itr == last)
|
||||
// throw torrent::internal_error("Scheduler::update() loop bork.");
|
||||
|
||||
// if ((*itr)->is_active()) {
|
||||
// m_downloadList->pause(*itr);
|
||||
// --curActive;
|
||||
// }
|
||||
// }
|
||||
|
||||
// m_view->sort();
|
||||
|
||||
// for (View::iterator itr = m_view->begin_visible(), last = m_view->end_visible(); curActive < m_maxActive; ++itr) {
|
||||
// if (itr == last)
|
||||
// throw torrent::internal_error("Scheduler::update() loop bork.");
|
||||
|
||||
// if (!(*itr)->is_active()) {
|
||||
// m_downloadList->start_try(*itr);
|
||||
// ++curActive;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
// 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
|
||||
|
||||
#ifndef RTORRENT_CORE_SCHEDULER_H
|
||||
#define RTORRENT_CORE_SCHEDULER_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "view.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
class DownloadList;
|
||||
class View;
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
typedef uint32_t size_type;
|
||||
|
||||
static const size_type unlimited = ~size_type();
|
||||
|
||||
Scheduler(DownloadList* dl);
|
||||
~Scheduler();
|
||||
|
||||
void set_view(View* view);
|
||||
|
||||
size_type max_active() const { return m_maxActive; }
|
||||
void set_max_active(size_type v) { m_maxActive = v; }
|
||||
|
||||
size_type cycle() const { return m_cycle; }
|
||||
void set_cycle(size_type v) { m_cycle = v; }
|
||||
|
||||
size_type active() const;
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
View* m_view;
|
||||
DownloadList* m_downloadList;
|
||||
|
||||
size_type m_maxActive;
|
||||
size_type m_cycle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+8
-17
@@ -116,10 +116,7 @@ View::~View() {
|
||||
if (m_name.empty())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < DownloadList::SLOTS_MAX_SIZE; i++)
|
||||
rpc::commands.call("system.method.set_key", rpc::make_target(),
|
||||
rpc::create_object_list(control->core()->download_list()->slot_name(i), "0_view_" + m_name));
|
||||
|
||||
clear_filter_on();
|
||||
priority_queue_erase(&taskScheduler, &m_delayChanged);
|
||||
}
|
||||
|
||||
@@ -131,13 +128,8 @@ View::initialize(const std::string& name) {
|
||||
if (name.empty())
|
||||
throw torrent::internal_error("View::initialize(...) called with an empty name.");
|
||||
|
||||
std::string key = "0_view_" + name;
|
||||
core::DownloadList* dlist = control->core()->download_list();
|
||||
|
||||
if (rpc::commands.call("system.method.has_key", rpc::make_target(), rpc::create_object_list("event.download.inserted", key)).as_value() ||
|
||||
rpc::commands.call("system.method.has_key", rpc::make_target(), rpc::create_object_list("event.download.erased", key)).as_value())
|
||||
throw torrent::internal_error("View::initialize(...) duplicate key name found in DownloadList.");
|
||||
|
||||
m_name = name;
|
||||
|
||||
// Urgh, wrong. No filtering being done.
|
||||
@@ -297,21 +289,20 @@ View::filter_download(core::Download* download) {
|
||||
}
|
||||
|
||||
void
|
||||
View::set_filter_on(int event) {
|
||||
if (event == DownloadList::D_SLOTS_INSERT || event == DownloadList::D_SLOTS_ERASE || event >= DownloadList::SLOTS_MAX_SIZE)
|
||||
throw torrent::internal_error("View::filter_on(...) invalid event.");
|
||||
View::set_filter_on_event(const std::string& event) {
|
||||
if (std::find(m_events.begin(), m_events.end(), event) != m_events.end())
|
||||
return;
|
||||
|
||||
rpc::commands.call("system.method.set_key", rpc::make_target(),
|
||||
rpc::create_object_list(control->core()->download_list()->slot_name(event), "0_view_" + m_name, "view.filter_download=" + m_name));
|
||||
rpc::commands.call_catch("system.method.set_key", rpc::make_target(), rpc::create_object_list(event, "!view_" + m_name, "view.filter_download=" + m_name));
|
||||
m_events.push_back(event);
|
||||
}
|
||||
|
||||
void
|
||||
View::clear_filter_on() {
|
||||
// Don't clear insert and erase as these are required to keep the
|
||||
// View up-to-date with the available downloads.
|
||||
for (int i = DownloadList::D_SLOTS_OPEN; i < DownloadList::SLOTS_MAX_SIZE; i++)
|
||||
rpc::commands.call("system.method.set_key", rpc::make_target(),
|
||||
rpc::create_object_list(control->core()->download_list()->slot_name(i), "0_view_" + m_name));
|
||||
for (event_list_type::const_iterator itr = m_events.begin(); itr != m_events.end(); itr++)
|
||||
rpc::commands.call_catch("system.method.set_key", rpc::make_target(), rpc::create_object_list(*itr, "!view_" + m_name));
|
||||
}
|
||||
|
||||
inline void
|
||||
|
||||
+3
-1
@@ -64,6 +64,7 @@ class Download;
|
||||
class View : private std::vector<Download*> {
|
||||
public:
|
||||
typedef std::vector<Download*> base_type;
|
||||
typedef std::vector<std::string> event_list_type;
|
||||
typedef sigc::signal0<void> signal_type;
|
||||
|
||||
using base_type::iterator;
|
||||
@@ -122,7 +123,7 @@ public:
|
||||
void filter_download(core::Download* download);
|
||||
|
||||
void set_filter(const std::string& s) { m_filter = s; }
|
||||
void set_filter_on(int event);
|
||||
void set_filter_on_event(const std::string& event);
|
||||
|
||||
void clear_filter_on();
|
||||
|
||||
@@ -167,6 +168,7 @@ private:
|
||||
std::string m_sortCurrent;
|
||||
|
||||
std::string m_filter;
|
||||
event_list_type m_events;
|
||||
|
||||
std::string m_eventAdded;
|
||||
std::string m_eventRemoved;
|
||||
|
||||
@@ -112,30 +112,8 @@ ViewManager::set_filter_on(const std::string& name, const filter_args& args) {
|
||||
|
||||
(*viewItr)->clear_filter_on();
|
||||
|
||||
for (filter_args::const_iterator itr = args.begin(); itr != args.end(); ++itr) {
|
||||
|
||||
if (*itr == "start")
|
||||
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_START);
|
||||
|
||||
else if (*itr == "stop")
|
||||
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_STOP);
|
||||
|
||||
else if (*itr == "hash_queued")
|
||||
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_HASH_QUEUED);
|
||||
|
||||
else if (*itr == "hash_removed")
|
||||
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_HASH_REMOVED);
|
||||
|
||||
else if (*itr == "hash_done")
|
||||
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_HASH_DONE);
|
||||
|
||||
else if (*itr == "finished")
|
||||
(*viewItr)->set_filter_on(DownloadList::D_SLOTS_FINISHED);
|
||||
|
||||
else
|
||||
throw torrent::input_error("Invalid filter on identifier.");
|
||||
|
||||
}
|
||||
for (filter_args::const_iterator itr = args.begin(); itr != args.end(); ++itr)
|
||||
(*viewItr)->set_filter_on_event(*itr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-18
@@ -199,51 +199,43 @@ main(int argc, char** argv) {
|
||||
"view_filter = active,false=\n"
|
||||
|
||||
"view_add = started\n"
|
||||
"view_filter = started,d.get_state=\n"
|
||||
"view.event_added = started,scheduler.simple.added=\n"
|
||||
"view.event_removed = started,scheduler.simple.removed=\n"
|
||||
"view_filter = started,false=\n"
|
||||
"view.event_added = started,\"view.set_not_visible=stopped ;d.set_state=1 ;scheduler.simple.added=\"\n"
|
||||
"view.event_removed = started,\"view.set_visible=stopped ;scheduler.simple.removed=\"\n"
|
||||
|
||||
"view_add = stopped\n"
|
||||
"view_filter = stopped,not=$d.get_state=\n"
|
||||
"view_filter = stopped,false=\n"
|
||||
"view.event_added = stopped,\"view.set_not_visible=started ;d.set_state=0\"\n"
|
||||
"view.event_removed = stopped,view.set_visible=started\n"
|
||||
|
||||
"view_add = complete\n"
|
||||
"view_filter = complete,d.get_complete=\n"
|
||||
"view_filter_on = complete,hash_done,finished\n"
|
||||
"view_filter_on = complete,event.download.hash_done,event.download.finished\n"
|
||||
"view_sort_new = complete,less=d.get_state_changed=\n"
|
||||
"view_sort_current = complete,less=d.get_state_changed=\n"
|
||||
|
||||
"view_add = incomplete\n"
|
||||
"view_filter = incomplete,not=$d.get_complete=\n"
|
||||
"view_filter_on = incomplete,hash_done,finished\n"
|
||||
"view_filter_on = incomplete,event.download.hash_done,event.download.finished\n"
|
||||
"view_sort_new = incomplete,less=d.get_state_changed=\n"
|
||||
"view_sort_current = incomplete,less=d.get_state_changed=\n"
|
||||
|
||||
// The hashing view does not include stopped torrents.
|
||||
"view_add = hashing\n"
|
||||
"view_filter = hashing,d.get_hashing=\n"
|
||||
"view_filter_on = hashing,hash_queued,hash_removed,hash_done\n"
|
||||
"view_filter_on = hashing,event.download.hash_queued,event.download.hash_removed,event.download.hash_done\n"
|
||||
// "view_sort_new = hashing,less=d.get_state_changed=\n"
|
||||
// "view_sort_current = hashing,less=d.get_state_changed=\n"
|
||||
|
||||
"view_add = seeding\n"
|
||||
"view_filter = seeding,\"and=d.get_state=,d.get_complete=\"\n"
|
||||
"view_filter_on = seeding,start,stop\n"
|
||||
"view_filter_on = seeding,event.download.resumed,event.download.paused\n"
|
||||
"view_sort_new = seeding,less=d.get_state_changed=\n"
|
||||
"view_sort_current = seeding,less=d.get_state_changed=\n"
|
||||
|
||||
// Changing these will bork the (non-existant) scheduler.
|
||||
"view_add = scheduler\n"
|
||||
// "view_sort_new = scheduler,less=d.get_state_changed=\n"
|
||||
// "view_sort_current = scheduler,less=d.get_state_changed=\n"
|
||||
|
||||
// "schedule = scheduler,10,10,download_scheduler=\n"
|
||||
|
||||
"schedule = view_main,10,10,\"view_sort=main,20\"\n"
|
||||
"schedule = view_name,10,10,\"view_sort=name,20\"\n"
|
||||
// "schedule = view_started,10,10,view_sort=started,5\n"
|
||||
// "schedule = view_stopped,10,10,view_sort=stopped,5\n"
|
||||
// "schedule = view_complete,10,10,view_sort=complete,5\n"
|
||||
// "schedule = view_incomplete,10,10,view_sort=incomplete,5\n"
|
||||
|
||||
"schedule = session_save,1800,1800,session_save=\n"
|
||||
"schedule = low_diskspace,5,60,close_low_diskspace=500M\n"
|
||||
|
||||
Reference in New Issue
Block a user