-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update dir_monitor and adjust to API change
- Loading branch information
Showing
11 changed files
with
1,788 additions
and
886 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,103 @@ | ||
// | ||
// Copyright (c) 2008, 2009 Boris Schaeling <boris@highscore.de> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
|
||
#ifndef BOOST_ASIO_BASIC_DIR_MONITOR_HPP | ||
#define BOOST_ASIO_BASIC_DIR_MONITOR_HPP | ||
|
||
#include <boost/asio.hpp> | ||
#include <string> | ||
|
||
namespace boost { | ||
namespace asio { | ||
|
||
struct dir_monitor_event | ||
{ | ||
enum event_type | ||
{ | ||
null = 0, | ||
added = 1, | ||
removed = 2, | ||
modified = 3, | ||
renamed_old_name = 4, | ||
renamed_new_name = 5 | ||
}; | ||
|
||
dir_monitor_event() | ||
: type(null) { } | ||
|
||
dir_monitor_event(const std::string &d, const std::string &f, event_type t) | ||
: dirname(d), filename(f), type(t) { } | ||
|
||
std::string dirname; | ||
std::string filename; | ||
event_type type; | ||
}; | ||
|
||
template <typename Service> | ||
class basic_dir_monitor | ||
: public boost::asio::basic_io_object<Service> | ||
{ | ||
public: | ||
explicit basic_dir_monitor(boost::asio::io_service &io_service) | ||
: boost::asio::basic_io_object<Service>(io_service) | ||
{ | ||
} | ||
|
||
void add_directory(const std::string &dirname) | ||
{ | ||
this->service.add_directory(this->implementation, dirname); | ||
} | ||
|
||
void remove_directory(const std::string &dirname) | ||
{ | ||
this->service.remove_directory(this->implementation, dirname); | ||
} | ||
|
||
dir_monitor_event monitor() | ||
{ | ||
boost::system::error_code ec; | ||
dir_monitor_event ev = this->service.monitor(this->implementation, ec); | ||
boost::asio::detail::throw_error(ec); | ||
return ev; | ||
} | ||
|
||
dir_monitor_event monitor(boost::system::error_code &ec) | ||
{ | ||
return this->service.monitor(this->implementation, ec); | ||
} | ||
|
||
template <typename Handler> | ||
void async_monitor(Handler handler) | ||
{ | ||
this->service.async_monitor(this->implementation, handler); | ||
} | ||
}; | ||
|
||
} | ||
} | ||
|
||
#endif | ||
// | ||
// Copyright (c) 2008, 2009 Boris Schaeling <boris@highscore.de> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
#pragma once | ||
|
||
#include <boost/asio.hpp> | ||
#include <boost/filesystem.hpp> | ||
#include <string> | ||
|
||
namespace boost { | ||
namespace asio { | ||
|
||
struct dir_monitor_event | ||
{ | ||
enum event_type | ||
{ | ||
null = 0, | ||
added = 1, | ||
removed = 2, | ||
modified = 3, | ||
renamed_old_name = 4, | ||
renamed_new_name = 5, | ||
/** | ||
* In some cases a recursive scan of directory under dirname is required. | ||
*/ | ||
recursive_rescan = 6 | ||
}; | ||
|
||
dir_monitor_event() | ||
: type(null) { } | ||
|
||
dir_monitor_event(const boost::filesystem::path &p, event_type t) | ||
: path(p), type(t) { } | ||
|
||
const char* type_cstr() const | ||
{ | ||
switch(type) { | ||
case boost::asio::dir_monitor_event::added: return "ADDED"; | ||
case boost::asio::dir_monitor_event::removed: return "REMOVED"; | ||
case boost::asio::dir_monitor_event::modified: return "MODIFIED"; | ||
case boost::asio::dir_monitor_event::renamed_old_name: return "RENAMED (OLD NAME)"; | ||
case boost::asio::dir_monitor_event::renamed_new_name: return "RENAMED (NEW NAME)"; | ||
case boost::asio::dir_monitor_event::recursive_rescan: return "RESCAN DIR"; | ||
default: return "UNKNOWN"; | ||
} | ||
} | ||
|
||
boost::filesystem::path path; | ||
event_type type; | ||
}; | ||
|
||
inline std::ostream& operator << (std::ostream& os, dir_monitor_event const& ev) | ||
{ | ||
os << "dir_monitor_event " << ev.type_cstr() << " " << ev.path; | ||
return os; | ||
} | ||
|
||
template <typename Service> | ||
class basic_dir_monitor | ||
: public boost::asio::basic_io_object<Service> | ||
{ | ||
public: | ||
explicit basic_dir_monitor(boost::asio::io_service &io_service) | ||
: boost::asio::basic_io_object<Service>(io_service) | ||
{ | ||
} | ||
|
||
void add_directory(const std::string &dirname) | ||
{ | ||
this->get_service().add_directory(this->get_implementation(), dirname); | ||
} | ||
|
||
void remove_directory(const std::string &dirname) | ||
{ | ||
this->get_service().remove_directory(this->get_implementation(), dirname); | ||
} | ||
|
||
dir_monitor_event monitor() | ||
{ | ||
boost::system::error_code ec; | ||
dir_monitor_event ev = this->get_service().monitor(this->get_implementation(), ec); | ||
boost::asio::detail::throw_error(ec); | ||
return ev; | ||
} | ||
|
||
dir_monitor_event monitor(boost::system::error_code &ec) | ||
{ | ||
return this->get_service().monitor(this->get_implementation(), ec); | ||
} | ||
|
||
template <typename Handler> | ||
void async_monitor(Handler handler) | ||
{ | ||
this->get_service().async_monitor(this->get_implementation(), handler); | ||
} | ||
}; | ||
|
||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,31 @@ | ||
// | ||
// Copyright (c) 2008, 2009 Boris Schaeling <boris@highscore.de> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// | ||
// Copyright (c) 2008, 2009 Boris Schaeling <boris@highscore.de> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
#pragma once | ||
|
||
#ifndef BOOST_ASIO_DIR_MONITOR_HPP | ||
#define BOOST_ASIO_DIR_MONITOR_HPP | ||
#include "basic_dir_monitor.hpp" | ||
#include <boost/predef/os.h> | ||
|
||
#include "basic_dir_monitor.hpp" | ||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) | ||
# include "windows/basic_dir_monitor_service.hpp" | ||
#elif defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) || defined(__FreeBSD__) | ||
# include "inotify/basic_dir_monitor_service.hpp" | ||
#else | ||
# error "Platform not supported." | ||
#endif | ||
#if BOOST_OS_WINDOWS | ||
# include "windows/basic_dir_monitor_service.hpp" | ||
#elif (BOOST_OS_LINUX || BOOST_OS_ANDROID) | ||
# include "inotify/basic_dir_monitor_service.hpp" | ||
#elif BOOST_OS_MACOS | ||
# include "fsevents/basic_dir_monitor_service.hpp" | ||
#elif BOOST_OS_BSD | ||
# include "kqueue/basic_dir_monitor_service.hpp" | ||
#else | ||
# error "Platform not supported." | ||
#endif | ||
|
||
namespace boost { | ||
namespace asio { | ||
namespace boost { | ||
namespace asio { | ||
|
||
typedef basic_dir_monitor<basic_dir_monitor_service<> > dir_monitor; | ||
typedef basic_dir_monitor<basic_dir_monitor_service<> > dir_monitor; | ||
|
||
} | ||
} | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// | ||
// Apple FSEvents monitor implementation based on windows monitor_service | ||
// Copyright (c) 2014 Stanislav Karchebnyy <berkus@atta-metta.net> | ||
// Copyright (c) 2008, 2009 Boris Schaeling <boris@highscore.de> | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
#pragma once | ||
|
||
#include "dir_monitor_impl.hpp" | ||
#include <boost/asio.hpp> | ||
#include <boost/thread.hpp> | ||
#include <boost/bind.hpp> | ||
#include <boost/shared_ptr.hpp> | ||
#include <boost/weak_ptr.hpp> | ||
#include <boost/scoped_ptr.hpp> | ||
#include <boost/scoped_array.hpp> | ||
#include <boost/filesystem.hpp> | ||
#include <boost/system/error_code.hpp> | ||
#include <boost/system/system_error.hpp> | ||
#include <string> | ||
#include <stdexcept> | ||
|
||
namespace boost { | ||
namespace asio { | ||
|
||
template <typename DirMonitorImplementation = dir_monitor_impl> | ||
class basic_dir_monitor_service | ||
: public boost::asio::io_service::service | ||
{ | ||
public: | ||
static boost::asio::io_service::id id; | ||
|
||
explicit basic_dir_monitor_service(boost::asio::io_service &io_service) | ||
: boost::asio::io_service::service(io_service), | ||
async_monitor_work_(new boost::asio::io_service::work(async_monitor_io_service_)), | ||
async_monitor_thread_(boost::bind(&boost::asio::io_service::run, &async_monitor_io_service_)) | ||
{ | ||
} | ||
|
||
~basic_dir_monitor_service() | ||
{ | ||
// The async_monitor thread will finish when async_monitor_work_ is reset as all asynchronous | ||
// operations have been aborted and were discarded before (in destroy). | ||
async_monitor_work_.reset(); | ||
|
||
// Event processing is stopped to discard queued operations. | ||
async_monitor_io_service_.stop(); | ||
|
||
// The async_monitor thread is joined to make sure the directory monitor service is | ||
// destroyed _after_ the thread is finished (not that the thread tries to access | ||
// instance properties which don't exist anymore). | ||
async_monitor_thread_.join(); | ||
} | ||
|
||
typedef boost::shared_ptr<DirMonitorImplementation> implementation_type; | ||
|
||
void construct(implementation_type &impl) | ||
{ | ||
impl.reset(new DirMonitorImplementation()); | ||
} | ||
|
||
void destroy(implementation_type &impl) | ||
{ | ||
// If an asynchronous call is currently waiting for an event | ||
// we must interrupt the blocked call to make sure it returns. | ||
impl->destroy(); | ||
|
||
impl.reset(); | ||
} | ||
|
||
void add_directory(implementation_type &impl, const std::string &dirname) | ||
{ | ||
boost::filesystem::path dir(boost::filesystem::canonical(dirname)); | ||
if (!boost::filesystem::is_directory(dir)) | ||
throw std::invalid_argument("boost::asio::basic_dir_monitor_service::add_directory: " + dir.native() + " is not a valid directory entry"); | ||
|
||
impl->add_directory(dir); | ||
} | ||
|
||
void remove_directory(implementation_type &impl, const std::string &dirname) | ||
{ | ||
boost::filesystem::path dir(boost::filesystem::canonical(dirname)); | ||
impl->remove_directory(dir); | ||
} | ||
|
||
/** | ||
* Blocking event monitor. | ||
*/ | ||
dir_monitor_event monitor(implementation_type &impl, boost::system::error_code &ec) | ||
{ | ||
return impl->popfront_event(ec); | ||
} | ||
|
||
template <typename Handler> | ||
class monitor_operation | ||
{ | ||
public: | ||
monitor_operation(implementation_type &impl, boost::asio::io_service &io_service, Handler handler) | ||
: impl_(impl), | ||
io_service_(io_service), | ||
work_(io_service), | ||
handler_(handler) | ||
{ | ||
} | ||
|
||
void operator()() const | ||
{ | ||
implementation_type impl = impl_.lock(); | ||
if (impl) | ||
{ | ||
boost::system::error_code ec; | ||
dir_monitor_event ev = impl->popfront_event(ec); | ||
this->io_service_.post(boost::asio::detail::bind_handler(handler_, ec, ev)); | ||
} | ||
else | ||
{ | ||
this->io_service_.post(boost::asio::detail::bind_handler(handler_, boost::asio::error::operation_aborted, dir_monitor_event())); | ||
} | ||
} | ||
|
||
private: | ||
boost::weak_ptr<DirMonitorImplementation> impl_; | ||
boost::asio::io_service &io_service_; | ||
boost::asio::io_service::work work_; | ||
Handler handler_; | ||
}; | ||
|
||
/** | ||
* Non-blocking event monitor. | ||
*/ | ||
template <typename Handler> | ||
void async_monitor(implementation_type &impl, Handler handler) | ||
{ | ||
this->async_monitor_io_service_.post(monitor_operation<Handler>(impl, this->get_io_service(), handler)); | ||
} | ||
|
||
private: | ||
void shutdown_service() override | ||
{} | ||
|
||
boost::asio::io_service async_monitor_io_service_; | ||
boost::scoped_ptr<boost::asio::io_service::work> async_monitor_work_; | ||
boost::thread async_monitor_thread_; | ||
}; | ||
|
||
template <typename DirMonitorImplementation> | ||
boost::asio::io_service::id basic_dir_monitor_service<DirMonitorImplementation>::id; | ||
|
||
} // asio namespace | ||
} // boost namespace | ||
|
Oops, something went wrong.