]> git.sesse.net Git - casparcg/blobdiff - common/polling_filesystem_monitor.cpp
Fix a few Clang warnings.
[casparcg] / common / polling_filesystem_monitor.cpp
index c5013fcd7d8d931024ece682f536658a2cd7050a..305e0b0c3b24faec62f38dde357ca4e1d8b61d46 100644 (file)
@@ -29,7 +29,6 @@
 #include <cstdint>
 
 #include <boost/asio.hpp>
-#include <boost/thread.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/convenience.hpp>
 
@@ -88,13 +87,18 @@ public:
        {
        }
 
-       void reemmit_all()
+       void reemmit_all(const tbb::atomic<bool>& running)
        {
                if (static_cast<int>(events_mask_ & filesystem_event::MODIFIED) == 0)
                        return;
 
                for (auto& file : files_)
+               {
+                       if (!running)
+                               return;
+
                        handler_(filesystem_event::MODIFIED, file.first);
+               }
        }
 
        void reemmit(const boost::filesystem::path& file)
@@ -198,17 +202,19 @@ private:
        }
 };
 
-class polling_filesystem_monitor : public filesystem_monitor
+class polling_filesystem_monitor
+               : public filesystem_monitor
+               , public spl::enable_shared_from_this<polling_filesystem_monitor>
 {
-       std::shared_ptr<boost::asio::io_service> scheduler_;
-       directory_monitor root_monitor_;
-       executor executor_;
-       boost::asio::deadline_timer timer_;
-       tbb::atomic<bool> running_;
-       int scan_interval_millis_;
-       std::promise<void> initial_scan_completion_;
-       tbb::concurrent_queue<boost::filesystem::path> to_reemmit_;
-       tbb::atomic<bool> reemmit_all_;
+       tbb::atomic<bool>                                                               running_;
+       std::shared_ptr<boost::asio::io_service>                scheduler_;
+       directory_monitor                                                               root_monitor_;
+       boost::asio::deadline_timer                                             timer_;
+       int                                                                                             scan_interval_millis_;
+       std::promise<void>                                                              initial_scan_completion_;
+       tbb::concurrent_queue<boost::filesystem::path>  to_reemmit_;
+       tbb::atomic<bool>                                                               reemmit_all_;
+       executor                                                                                executor_;
 public:
        polling_filesystem_monitor(
                        const boost::filesystem::path& folder_to_watch,
@@ -220,12 +226,16 @@ public:
                        const initial_files_handler& initial_files_handler)
                : scheduler_(std::move(scheduler))
                , root_monitor_(report_already_existing, folder_to_watch, events_of_interest_mask, handler, initial_files_handler)
-               , executor_(L"polling_filesystem_monitor")
                , timer_(*scheduler_)
                , scan_interval_millis_(scan_interval_millis)
+               , executor_(L"polling_filesystem_monitor")
        {
                running_ = true;
                reemmit_all_ = false;
+       }
+
+       void start()
+       {
                executor_.begin_invoke([this]
                {
                        scan();
@@ -238,7 +248,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<void> initial_files_processed() override
@@ -261,11 +271,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<polling_filesystem_monitor> 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();
                });
        }
 
@@ -289,10 +303,10 @@ private:
                try
                {
                        if (reemmit_all_.fetch_and_store(false))
-                               root_monitor_.reemmit_all();
+                               root_monitor_.reemmit_all(running_);
                        else
                        {
-                               boost::filesystem::wpath file;
+                               boost::filesystem::path file;
 
                                while (to_reemmit_.try_pop(file))
                                        root_monitor_.reemmit(file);
@@ -339,7 +353,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<polling_filesystem_monitor>(
+       auto monitor = spl::make_shared<polling_filesystem_monitor>(
                        folder_to_watch,
                        events_of_interest_mask,
                        report_already_existing,
@@ -347,6 +361,10 @@ filesystem_monitor::ptr polling_filesystem_monitor_factory::create(
                        impl_->scheduler_,
                        handler,
                        initial_files_handler);
+
+       monitor->start();
+
+       return monitor;
 }
 
 }