diff --git a/applications/gui/src/src_window.hpp b/applications/gui/src/src_window.hpp index de14d0d05504895d0b5137a1d9e267def32cde92..dfc00a83b85143fa7b86adae25e86859ff2bbcbc 100644 --- a/applications/gui/src/src_window.hpp +++ b/applications/gui/src/src_window.hpp @@ -36,7 +36,7 @@ class SourceWindow : public nanogui::Window { std::vector<GLTexture> thumbs_; bool refresh_thumbs_; nanogui::Widget *ipanel_; - std::mutex mutex_; + MUTEX mutex_; void _updateCameras(); diff --git a/applications/reconstruct/src/virtual_source.cpp b/applications/reconstruct/src/virtual_source.cpp index cf6d268c1acc9d4d8e9452f8887be7f8e17eb4a2..c8dc380743373c591ffcfcea6aae0f713c1068c1 100644 --- a/applications/reconstruct/src/virtual_source.cpp +++ b/applications/reconstruct/src/virtual_source.cpp @@ -7,8 +7,6 @@ #include <loguru.hpp> using ftl::rgbd::VirtualSource; -using std::mutex; -using std::unique_lock; VirtualSource::VirtualSource(ftl::rgbd::Source *host) : ftl::rgbd::detail::Source(host) { diff --git a/applications/vision/src/main.cpp b/applications/vision/src/main.cpp index 141ae56131ec13e1e1cd48608c6f32f62e3b9f06..4c38125ce3270d770a70387ddba96def445ed3a2 100644 --- a/applications/vision/src/main.cpp +++ b/applications/vision/src/main.cpp @@ -15,8 +15,6 @@ #include <vector> #include <fstream> #include <thread> -#include <mutex> -#include <condition_variable> #include <opencv2/opencv.hpp> #include <ftl/rgbd.hpp> @@ -47,8 +45,6 @@ using std::map; using std::condition_variable; using std::this_thread::sleep_for; using std::chrono::milliseconds; -using std::mutex; -using std::unique_lock; using cv::Mat; using json = nlohmann::json; diff --git a/components/common/cpp/include/ftl/threads.hpp b/components/common/cpp/include/ftl/threads.hpp index 3091ac64f894b2e8a3ec059c615cfba563e43bee..5d86ce6077be327b24db981412435ba5b29687e1 100644 --- a/components/common/cpp/include/ftl/threads.hpp +++ b/components/common/cpp/include/ftl/threads.hpp @@ -7,24 +7,28 @@ #define POOL_SIZE 10 -#if defined _DEBUG && DEBUG_MUTEX +// #define DEBUG_MUTEX + +#if defined DEBUG_MUTEX #include <loguru.hpp> #include <chrono> #include <type_traits> -#define UNIQUE_LOCK(M,L) \ - auto start_##L = std::chrono::high_resolution_clock::now(); \ - std::unique_lock<std::remove_reference<decltype(M)>::type> L(M); \ - LOG(INFO) << "LOCK(" << #M "," #L << ") in " << std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start_##L).count(); +#define MUTEX std::timed_mutex +#define RECURSIVE_MUTEX std::recursive_timed_mutex +#define SHARED_MUTEX std::shared_timed_mutex + +#define UNIQUE_LOCK(M,L) std::unique_lock<std::remove_reference<decltype(M)>::type> L(M, std::chrono::seconds(5)); if (!L) LOG(FATAL) << "Mutex deadlock"; +#define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M, std::chrono::seconds(5)); if (!L) LOG(FATAL) << "Mutex deadlock"; -#define SHARED_LOCK(M,L) \ - auto start_##L = std::chrono::high_resolution_clock::now(); \ - std::shared_lock<std::remove_reference<decltype(M)>::type> L(M); \ - LOG(INFO) << "LOCK(" << #M "," #L << ") in " << std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start_##L).count(); #else +#define MUTEX std::mutex +#define RECURSIVE_MUTEX std::recursive_mutex +#define SHARED_MUTEX std::shared_mutex + #define UNIQUE_LOCK(M,L) std::unique_lock<std::remove_reference<decltype(M)>::type> L(M); #define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M); -#endif // _DEBUG && DEBUG_MUTEX +#endif // DEBUG_MUTEX namespace ftl { extern ctpl::thread_pool pool; diff --git a/components/control/cpp/include/ftl/slave.hpp b/components/control/cpp/include/ftl/slave.hpp index a7ae0075a27b206e1fb6a2d980928075957dcfd8..e3ebd69e46fa5177eebbcc2d8d6b2f2cce70f204 100644 --- a/components/control/cpp/include/ftl/slave.hpp +++ b/components/control/cpp/include/ftl/slave.hpp @@ -4,7 +4,7 @@ #include <ftl/net/universe.hpp> #include <ftl/configurable.hpp> #include <loguru.hpp> -#include <mutex> +#include <ftl/threads.hpp> namespace ftl { namespace ctrl { @@ -38,7 +38,7 @@ class Slave { private: std::vector<ftl::UUID> log_peers_; ftl::net::Universe *net_; - std::recursive_mutex mutex_; + RECURSIVE_MUTEX mutex_; bool in_log_; bool active_; SystemState state_; diff --git a/components/net/cpp/include/ftl/net/peer.hpp b/components/net/cpp/include/ftl/net/peer.hpp index 16393a55c9cd055971531903cf62f58a84b87a85..f58ab004e59c834e3968b78867a58d00475267f3 100644 --- a/components/net/cpp/include/ftl/net/peer.hpp +++ b/components/net/cpp/include/ftl/net/peer.hpp @@ -242,14 +242,14 @@ class Peer { // Receive buffers bool is_waiting_; msgpack::unpacker recv_buf_; - std::recursive_mutex recv_mtx_; + RECURSIVE_MUTEX recv_mtx_; bool ws_read_header_; // Send buffers msgpack::vrefbuffer send_buf_; - std::recursive_mutex send_mtx_; + RECURSIVE_MUTEX send_mtx_; - std::recursive_mutex cb_mtx_; + RECURSIVE_MUTEX cb_mtx_; std::string uri_; // Original connection URI, or assumed URI ftl::UUID peerid_; // Received in handshake or allocated @@ -292,7 +292,8 @@ R Peer::call(const std::string &name, ARGS... args) { R result; int id = asyncCall<R>(name, [&](const R &r) { - UNIQUE_LOCK(m,lk); + //UNIQUE_LOCK(m,lk); + std::unique_lock<std::mutex> lk(m); hasreturned = true; result = r; lk.unlock(); @@ -300,7 +301,8 @@ R Peer::call(const std::string &name, ARGS... args) { }, std::forward<ARGS>(args)...); { // Block thread until async callback notifies us - UNIQUE_LOCK(m,lk); + //UNIQUE_LOCK(m,lk); + std::unique_lock<std::mutex> lk(m); cv.wait_for(lk, std::chrono::seconds(1), [&hasreturned]{return hasreturned;}); } diff --git a/components/net/cpp/include/ftl/net/universe.hpp b/components/net/cpp/include/ftl/net/universe.hpp index 6afdd610795850af6f1baec58ec0957aa168f74c..720dc8a59759943bab565d42ef98c564e91c8fdf 100644 --- a/components/net/cpp/include/ftl/net/universe.hpp +++ b/components/net/cpp/include/ftl/net/universe.hpp @@ -203,8 +203,8 @@ class Universe : public ftl::Configurable { private: bool active_; ftl::UUID this_peer; - std::shared_mutex net_mutex_; - std::recursive_mutex handler_mutex_; + SHARED_MUTEX net_mutex_; + RECURSIVE_MUTEX handler_mutex_; fd_set sfderror_; fd_set sfdread_; std::vector<ftl::net::Listener*> listeners_; @@ -275,7 +275,8 @@ std::optional<R> Universe::findOne(const std::string &name, ARGS... args) { std::optional<R> result; auto handler = [&](const std::optional<R> &r) { - UNIQUE_LOCK(m,lk); + //UNIQUE_LOCK(m,lk); + std::unique_lock<std::mutex> lk(m); if (hasreturned || !r) return; hasreturned = true; result = r; @@ -292,7 +293,8 @@ std::optional<R> Universe::findOne(const std::string &name, ARGS... args) { lk.unlock(); { // Block thread until async callback notifies us - UNIQUE_LOCK(m,llk); + //UNIQUE_LOCK(m,llk); + std::unique_lock<std::mutex> llk(m); cv.wait_for(llk, std::chrono::seconds(1), [&hasreturned]{return hasreturned;}); // Cancel any further results @@ -318,7 +320,8 @@ std::vector<R> Universe::findAll(const std::string &name, ARGS... args) { std::vector<R> results; auto handler = [&](const std::vector<R> &r) { - UNIQUE_LOCK(m,lk); + //UNIQUE_LOCK(m,lk); + std::unique_lock<std::mutex> lk(m); returncount++; results.insert(results.end(), r.begin(), r.end()); lk.unlock(); @@ -337,7 +340,8 @@ std::vector<R> Universe::findAll(const std::string &name, ARGS... args) { lk.unlock(); { // Block thread until async callback notifies us - UNIQUE_LOCK(m,llk); + //UNIQUE_LOCK(m,llk); + std::unique_lock<std::mutex> llk(m); cv.wait_for(llk, std::chrono::seconds(1), [&returncount,&sentcount]{return returncount == sentcount;}); // Cancel any further results diff --git a/components/net/cpp/src/peer.cpp b/components/net/cpp/src/peer.cpp index ba32248ba0ac3da8a9ee1d2affed7ccd30c87eee..c874510963afca5b8f9a7e182bcf4b7719c2b09a 100644 --- a/components/net/cpp/src/peer.cpp +++ b/components/net/cpp/src/peer.cpp @@ -41,10 +41,7 @@ using ftl::net::Dispatcher; using std::chrono::seconds; using ftl::net::Universe; using ftl::net::callback_t; -using std::mutex; using std::vector; -using std::recursive_mutex; -using std::unique_lock; /*static std::string hexStr(const std::string &s) { @@ -535,7 +532,8 @@ bool Peer::waitConnection() { if (status_ == kConnected) return true; std::mutex m; - UNIQUE_LOCK(m,lk); + //UNIQUE_LOCK(m,lk); + std::unique_lock<std::mutex> lk(m); std::condition_variable cv; callback_t h = universe_->onConnect([this,&cv](Peer *p) { diff --git a/components/net/cpp/src/universe.cpp b/components/net/cpp/src/universe.cpp index 488a2acded0c99957817dad4e5c53c00536af42a..2282af25208d48214ff5c1b4d4d40cf912c6c237 100644 --- a/components/net/cpp/src/universe.cpp +++ b/components/net/cpp/src/universe.cpp @@ -19,10 +19,6 @@ using ftl::net::Universe; using nlohmann::json; using ftl::UUID; using std::optional; -using std::unique_lock; -using std::shared_lock; -using std::mutex; -using std::shared_mutex; using ftl::config::json_t; using ftl::net::callback_t; diff --git a/components/rgbd-sources/include/ftl/rgbd/source.hpp b/components/rgbd-sources/include/ftl/rgbd/source.hpp index 3cf1a2b520efd3e390713f34e69991c43b959a04..4fd875bc8cdc7166e4c5bb5a82bb7ba881701462 100644 --- a/components/rgbd-sources/include/ftl/rgbd/source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/source.hpp @@ -3,12 +3,12 @@ #include <ftl/configuration.hpp> #include <ftl/rgbd/camera.hpp> +#include <ftl/threads.hpp> //#include <ftl/net/universe.hpp> #include <ftl/uri.hpp> #include <ftl/rgbd/detail/source.hpp> #include <opencv2/opencv.hpp> #include <Eigen/Eigen> -#include <shared_mutex> #include <string> namespace ftl { @@ -167,7 +167,7 @@ class Source : public ftl::Configurable { void customImplementation(detail::Source *); - std::shared_mutex &mutex() { return mutex_; } + SHARED_MUTEX &mutex() { return mutex_; } private: detail::Source *impl_; @@ -177,7 +177,7 @@ class Source : public ftl::Configurable { Camera params_; // TODO Find better solution Eigen::Matrix4d pose_; ftl::net::Universe *net_; - std::shared_mutex mutex_; + SHARED_MUTEX mutex_; bool paused_; bool bullet_; diff --git a/components/rgbd-sources/include/ftl/rgbd/streamer.hpp b/components/rgbd-sources/include/ftl/rgbd/streamer.hpp index 5dac8fd13252578fa0575c55da7542ebf9451da3..2ab3bbda4281d19837fd3924959ee193c8c5ed0f 100644 --- a/components/rgbd-sources/include/ftl/rgbd/streamer.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/streamer.hpp @@ -10,7 +10,6 @@ #include <string> #include <vector> #include <map> -#include <shared_mutex> #include <atomic> namespace ftl { @@ -41,7 +40,7 @@ struct StreamSource { cv::Mat prev_rgb; cv::Mat prev_depth; std::list<detail::StreamClient> clients[10]; // One list per bitrate - std::shared_mutex mutex; + SHARED_MUTEX mutex; unsigned long long frame; }; @@ -107,7 +106,7 @@ class Streamer : public ftl::Configurable { private: std::map<std::string, detail::StreamSource*> sources_; //ctpl::thread_pool pool_; - std::shared_mutex mutex_; + SHARED_MUTEX mutex_; bool active_; ftl::net::Universe *net_; bool late_; diff --git a/components/rgbd-sources/include/ftl/rgbd_source.hpp b/components/rgbd-sources/include/ftl/rgbd_source.hpp index 1c147e9614849369b35c12af07c267751a593b76..c065e6e19dcce61f94cbfe6b085c421239bd9297 100644 --- a/components/rgbd-sources/include/ftl/rgbd_source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd_source.hpp @@ -4,11 +4,11 @@ #include <ftl/config.h> #include <ftl/configurable.hpp> +#include <ftl/threads.hpp> #include <ftl/camera_params.hpp> #include <ftl/net/universe.hpp> #include <opencv2/opencv.hpp> #include <Eigen/Eigen> -#include <mutex> namespace ftl { namespace rgbd { @@ -77,7 +77,7 @@ class RGBDSource : public ftl::Configurable { protected: CameraParameters params_; ftl::net::Universe *net_; - std::mutex mutex_; + MUTEX mutex_; cv::Mat rgb_; cv::Mat depth_; diff --git a/components/rgbd-sources/src/net.cpp b/components/rgbd-sources/src/net.cpp index 7752f8d1f68531a88f963bba4e44a28d7ef80593..bedac5b67b526118e89b96cbe21a9808b60befc8 100644 --- a/components/rgbd-sources/src/net.cpp +++ b/components/rgbd-sources/src/net.cpp @@ -2,7 +2,6 @@ #include <vector> #include <thread> #include <chrono> -#include <shared_mutex> #include <tuple> #include "colour.hpp" @@ -14,8 +13,6 @@ using ftl::net::Universe; using ftl::UUID; using std::string; using ftl::rgbd::Camera; -using std::shared_mutex; -using std::unique_lock; using std::vector; using std::this_thread::sleep_for; using std::chrono::milliseconds; diff --git a/components/rgbd-sources/src/net.hpp b/components/rgbd-sources/src/net.hpp index 61bbbe7d71cb65b7ba7cb6a20b53bac238e26649..a962d880a973c1696728de808c30ffd9dae11b55 100644 --- a/components/rgbd-sources/src/net.hpp +++ b/components/rgbd-sources/src/net.hpp @@ -4,8 +4,8 @@ #include <ftl/net/universe.hpp> #include <ftl/rgbd/source.hpp> +#include <ftl/threads.hpp> #include <string> -#include <mutex> namespace ftl { namespace rgbd { @@ -36,7 +36,7 @@ class NetSource : public detail::Source { bool active_; std::string uri_; ftl::net::callback_t h_; - std::mutex mutex_; + MUTEX mutex_; int chunks_dim_; int chunk_width_; int chunk_height_; diff --git a/components/rgbd-sources/src/source.cpp b/components/rgbd-sources/src/source.cpp index 1f6c521cc688c9ff34123376379659ee9c7985ce..f810f38daf7e94ef889f51bb4fbc88d4b7102814 100644 --- a/components/rgbd-sources/src/source.cpp +++ b/components/rgbd-sources/src/source.cpp @@ -20,9 +20,6 @@ using ftl::rgbd::detail::RealsenseSource; using ftl::rgbd::Source; using ftl::Configurable; using std::string; -using std::shared_mutex; -using std::unique_lock; -using std::shared_lock; using ftl::rgbd::detail::StereoVideoSource; using ftl::rgbd::detail::NetSource; using ftl::rgbd::detail::ImageSource; diff --git a/components/rgbd-sources/src/stereovideo.cpp b/components/rgbd-sources/src/stereovideo.cpp index 9442eefde5686bbab620c32c7c21d79946e664b8..edcd5078a7381f8065ce076c0bb00d10e85668bc 100644 --- a/components/rgbd-sources/src/stereovideo.cpp +++ b/components/rgbd-sources/src/stereovideo.cpp @@ -1,17 +1,15 @@ #include <loguru.hpp> #include "stereovideo.hpp" #include <ftl/configuration.hpp> +#include <ftl/threads.hpp> #include "calibrate.hpp" #include "local.hpp" #include "disparity.hpp" -#include <mutex> using ftl::rgbd::detail::Calibrate; using ftl::rgbd::detail::LocalSource; using ftl::rgbd::detail::StereoVideoSource; using std::string; -using std::mutex; -using std::unique_lock; StereoVideoSource::StereoVideoSource(ftl::rgbd::Source *host) : ftl::rgbd::detail::Source(host), ready_(false) { @@ -83,14 +81,14 @@ void StereoVideoSource::init(const string &file) { // Add event handlers to allow calibration changes... host_->on("baseline", [this](const ftl::config::Event &e) { params_.baseline = host_->value("baseline", params_.baseline); - std::unique_lock<std::shared_mutex> lk(host_->mutex()); + UNIQUE_LOCK(host_->mutex(), lk); calib_->updateCalibration(params_); }); host_->on("focal", [this](const ftl::config::Event &e) { params_.fx = host_->value("focal", params_.fx); params_.fy = params_.fx; - std::unique_lock<std::shared_mutex> lk(host_->mutex()); + UNIQUE_LOCK(host_->mutex(), lk); calib_->updateCalibration(params_); }); diff --git a/components/rgbd-sources/src/streamer.cpp b/components/rgbd-sources/src/streamer.cpp index 3dc57428b7ce06ed2e744f40995d805ba0657692..6c656ec79d297567b30491b02aaec8948e390330 100644 --- a/components/rgbd-sources/src/streamer.cpp +++ b/components/rgbd-sources/src/streamer.cpp @@ -18,10 +18,6 @@ using std::list; using std::map; using std::optional; using std::vector; -using std::mutex; -using std::shared_mutex; -using std::unique_lock; -using std::shared_lock; using std::this_thread::sleep_for; using std::chrono::milliseconds; using std::tuple; @@ -259,8 +255,12 @@ void Streamer::wait() { } // Wait for all jobs to complete before finishing frame - UNIQUE_LOCK(job_mtx_, lk); - job_cv_.wait(lk, [this]{ return jobs_ == 0; }); + //UNIQUE_LOCK(job_mtx_, lk); + std::unique_lock<std::mutex> lk(job_mtx_); + job_cv_.wait_for(lk, std::chrono::seconds(20), [this]{ return jobs_ == 0; }); + if (jobs_ != 0) { + LOG(FATAL) << "Deadlock detected"; + } } void Streamer::_schedule() { @@ -282,12 +282,12 @@ void Streamer::_schedule() { // There will be two jobs for this source... //UNIQUE_LOCK(job_mtx_,lk); - jobs_ += 1 + kChunkDim*kChunkDim; + jobs_ += 1 + kChunkCount; //lk.unlock(); StreamSource *src = sources_[uri]; if (src == nullptr || src->jobs != 0) continue; - src->jobs = 1 + kChunkDim*kChunkDim; + src->jobs = 1 + kChunkCount; // Grab job ftl::pool.push([this,src](int id) { @@ -310,6 +310,7 @@ void Streamer::_schedule() { _swap(src); // Mark job as finished + std::unique_lock<std::mutex> lk(job_mtx_); --jobs_; job_cv_.notify_one(); }); @@ -388,6 +389,7 @@ void Streamer::_schedule() { src->jobs--; _swap(src); + std::unique_lock<std::mutex> lk(job_mtx_); --jobs_; job_cv_.notify_one(); }, i);