From d8f53ad9888a04fb5c50551c566b85ffd25afb90 Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Tue, 8 Nov 2016 19:22:08 +0100 Subject: [PATCH] [polling_filesystem_monitor] Fixed bug where unallocated memory could be read by polling_filesystem_monitor at server shutdown --- common/polling_filesystem_monitor.cpp | 46 +++++++++++++++++---------- shell/server.cpp | 3 ++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/common/polling_filesystem_monitor.cpp b/common/polling_filesystem_monitor.cpp index c189218ea..74962590b 100644 --- a/common/polling_filesystem_monitor.cpp +++ b/common/polling_filesystem_monitor.cpp @@ -203,17 +203,19 @@ private: } }; -class polling_filesystem_monitor : public filesystem_monitor +class polling_filesystem_monitor + : public filesystem_monitor + , public spl::enable_shared_from_this { - tbb::atomic running_; - std::shared_ptr scheduler_; - directory_monitor root_monitor_; - boost::asio::deadline_timer timer_; - int scan_interval_millis_; - std::promise initial_scan_completion_; - tbb::concurrent_queue to_reemmit_; - tbb::atomic reemmit_all_; - executor executor_; + tbb::atomic running_; + std::shared_ptr scheduler_; + directory_monitor root_monitor_; + boost::asio::deadline_timer timer_; + int scan_interval_millis_; + std::promise initial_scan_completion_; + tbb::concurrent_queue to_reemmit_; + tbb::atomic reemmit_all_; + executor executor_; public: polling_filesystem_monitor( const boost::filesystem::path& folder_to_watch, @@ -231,6 +233,10 @@ public: { running_ = true; reemmit_all_ = false; + } + + void start() + { executor_.begin_invoke([this] { scan(); @@ -243,7 +249,7 @@ public: { running_ = false; boost::system::error_code e; - timer_.cancel(e); + timer_.cancel(e); // Can still have be queued for execution by asio, therefore the task has a weak_ptr to this } std::future initial_files_processed() override @@ -266,11 +272,15 @@ private: if (!running_) return; - timer_.expires_from_now( - boost::posix_time::milliseconds(scan_interval_millis_)); - timer_.async_wait([this](const boost::system::error_code& e) + std::weak_ptr weak_self = shared_from_this(); + + timer_.expires_from_now(boost::posix_time::milliseconds(scan_interval_millis_)); + timer_.async_wait([weak_self](const boost::system::error_code& e) { - begin_scan(); + auto strong_self = weak_self.lock(); + + if (strong_self) + strong_self->begin_scan(); }); } @@ -344,7 +354,7 @@ filesystem_monitor::ptr polling_filesystem_monitor_factory::create( const filesystem_monitor_handler& handler, const initial_files_handler& initial_files_handler) { - return spl::make_shared( + auto monitor = spl::make_shared( folder_to_watch, events_of_interest_mask, report_already_existing, @@ -352,6 +362,10 @@ filesystem_monitor::ptr polling_filesystem_monitor_factory::create( impl_->scheduler_, handler, initial_files_handler); + + monitor->start(); + + return monitor; } } diff --git a/shell/server.cpp b/shell/server.cpp index 3d78ed36b..69fa7c083 100644 --- a/shell/server.cpp +++ b/shell/server.cpp @@ -109,12 +109,15 @@ std::shared_ptr create_running_io_service() CASPAR_LOG_CURRENT_EXCEPTION(); } } + + CASPAR_LOG(info) << "[asio] Global io_service uninitialized."; }); return std::shared_ptr( service.get(), [service, work, thread](void*) mutable { + CASPAR_LOG(info) << "[asio] Shutting down global io_service."; work.reset(); service->stop(); if (thread->get_id() != boost::this_thread::get_id()) -- 2.39.2