diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/password.cpp | 2 | ||||
-rw-r--r-- | src/common/threadpool.cpp | 43 | ||||
-rw-r--r-- | src/common/threadpool.h | 21 | ||||
-rw-r--r-- | src/common/util.cpp | 25 | ||||
-rw-r--r-- | src/common/util.h | 3 |
5 files changed, 71 insertions, 23 deletions
diff --git a/src/common/password.cpp b/src/common/password.cpp index 9336a14fc..3ce2ba42a 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -164,7 +164,7 @@ namespace while (true) { if (message) - std::cout << message <<": "; + std::cout << message <<": " << std::flush; if (!read_from_tty(pass1)) return false; if (verify) diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp index 51e071577..6b69e2a12 100644 --- a/src/common/threadpool.cpp +++ b/src/common/threadpool.cpp @@ -36,16 +36,17 @@ #include "common/util.h" static __thread int depth = 0; +static __thread bool is_leaf = false; namespace tools { -threadpool::threadpool() : running(true), active(0) { +threadpool::threadpool(unsigned int max_threads) : running(true), active(0) { boost::thread::attributes attrs; attrs.set_stack_size(THREAD_STACK_SIZE); - max = tools::get_max_concurrency(); - size_t i = max; + max = max_threads ? max_threads : tools::get_max_concurrency(); + size_t i = max ? max - 1 : 0; while(i--) { - threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this))); + threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false))); } } @@ -60,25 +61,30 @@ threadpool::~threadpool() { } } -void threadpool::submit(waiter *obj, std::function<void()> f) { - entry e = {obj, f}; +void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) { + CHECK_AND_ASSERT_THROW_MES(!is_leaf, "A leaf routine is using a thread pool"); boost::unique_lock<boost::mutex> lock(mutex); - if ((active == max && !queue.empty()) || depth > 0) { + if (!leaf && ((active == max && !queue.empty()) || depth > 0)) { // if all available threads are already running // and there's work waiting, just run in current thread lock.unlock(); ++depth; + is_leaf = leaf; f(); --depth; + is_leaf = false; } else { if (obj) obj->inc(); - queue.push_back(e); + if (leaf) + queue.push_front({obj, f, leaf}); + else + queue.push_back({obj, f, leaf}); has_work.notify_one(); } } -int threadpool::get_max_concurrency() { +unsigned int threadpool::get_max_concurrency() const { return max; } @@ -91,7 +97,7 @@ threadpool::waiter::~waiter() } try { - wait(); + wait(NULL); } catch (const std::exception &e) { @@ -99,9 +105,12 @@ threadpool::waiter::~waiter() } } -void threadpool::waiter::wait() { +void threadpool::waiter::wait(threadpool *tpool) { + if (tpool) + tpool->run(true); boost::unique_lock<boost::mutex> lock(mt); - while(num) cv.wait(lock); + while(num) + cv.wait(lock); } void threadpool::waiter::inc() { @@ -113,15 +122,19 @@ void threadpool::waiter::dec() { const boost::unique_lock<boost::mutex> lock(mt); num--; if (!num) - cv.notify_one(); + cv.notify_all(); } -void threadpool::run() { +void threadpool::run(bool flush) { boost::unique_lock<boost::mutex> lock(mutex); while (running) { entry e; while(queue.empty() && running) + { + if (flush) + return; has_work.wait(lock); + } if (!running) break; active++; @@ -129,8 +142,10 @@ void threadpool::run() { queue.pop_front(); lock.unlock(); ++depth; + is_leaf = e.leaf; e.f(); --depth; + is_leaf = false; if (e.wo) e.wo->dec(); diff --git a/src/common/threadpool.h b/src/common/threadpool.h index 34152541c..a43e38a76 100644 --- a/src/common/threadpool.h +++ b/src/common/threadpool.h @@ -46,6 +46,9 @@ public: static threadpool instance; return instance; } + static threadpool *getNewForUnitTests(unsigned max_threads = 0) { + return new threadpool(max_threads); + } // The waiter lets the caller know when all of its // tasks are completed. @@ -56,7 +59,7 @@ public: public: void inc(); void dec(); - void wait(); //! Wait for a set of tasks to finish. + void wait(threadpool *tpool); //! Wait for a set of tasks to finish. waiter() : num(0){} ~waiter(); }; @@ -64,25 +67,27 @@ public: // Submit a task to the pool. The waiter pointer may be // NULL if the caller doesn't care to wait for the // task to finish. - void submit(waiter *waiter, std::function<void()> f); + void submit(waiter *waiter, std::function<void()> f, bool leaf = false); + + unsigned int get_max_concurrency() const; - int get_max_concurrency(); + ~threadpool(); private: - threadpool(); - ~threadpool(); + threadpool(unsigned int max_threads = 0); typedef struct entry { waiter *wo; std::function<void()> f; + bool leaf; } entry; std::deque<entry> queue; boost::condition_variable has_work; boost::mutex mutex; std::vector<boost::thread> threads; - int active; - int max; + unsigned int active; + unsigned int max; bool running; - void run(); + void run(bool flush = false); }; } diff --git a/src/common/util.cpp b/src/common/util.cpp index 008610117..329352e94 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -727,6 +727,13 @@ std::string get_nix_version_display_string() bool is_local_address(const std::string &address) { + // always assume Tor/I2P addresses to be untrusted by default + if (boost::ends_with(address, ".onion") || boost::ends_with(address, ".i2p")) + { + MDEBUG("Address '" << address << "' is Tor/I2P, non local"); + return false; + } + // extract host epee::net_utils::http::url_content u_c; if (!epee::net_utils::parse_url(address, u_c)) @@ -820,4 +827,22 @@ std::string get_nix_version_display_string() return false; return true; } + + boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str) + { + auto pos = str.find(":"); + bool r = pos != std::string::npos; + uint32_t major; + r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos)); + uint32_t minor; + r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1)); + if (r) + { + return std::make_pair(major, minor); + } + else + { + return {}; + } + } } diff --git a/src/common/util.h b/src/common/util.h index 7caf0e3c5..dc426830b 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -32,6 +32,7 @@ #include <boost/thread/locks.hpp> #include <boost/thread/mutex.hpp> +#include <boost/optional.hpp> #include <system_error> #include <csignal> #include <cstdio> @@ -214,4 +215,6 @@ namespace tools bool sha256sum(const std::string &filename, crypto::hash &hash); bool is_hdd(const char *path); + + boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str); } |