Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First draft of the directory monitoring rewrite.
- Loading branch information
Showing
4 changed files
with
572 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "directory_monitor_v2.hpp" | ||
|
||
namespace boost{ | ||
namespace afio{ | ||
|
||
|
||
std::pair< future< bool >, async_io_op > dir_monitor::remove(const async_io_op & req, const path& path, const Handler& handler) | ||
{ | ||
auto func = std::bind(remove_path(path, handler)); | ||
return dispatcher->call(req, func); | ||
} | ||
|
||
std::pair< future< bool >, async_io_op > dir_monitor::add(const async_io_op & req, const path& path, const Handler& handler) | ||
{ | ||
auto func = std::bind(add_path(path, handler)); | ||
return dispatcher->call(req, func); | ||
} | ||
|
||
|
||
bool dir_monitor::remove_path(const path& path, const Handler& handler) | ||
{ | ||
//lock this durring removal | ||
mtx.lock(); | ||
try | ||
{ | ||
Path* p; | ||
p = hash.at(path); | ||
|
||
} | ||
catch(std::outofrange& e) | ||
{ | ||
// if it wasn't in the hash we're not monitoring it | ||
// consider an exception here with a useful message | ||
return false; | ||
} | ||
|
||
// if we can't find the handler return false | ||
// again an exception might be more informative | ||
if(!p->remove_handler(handler)) | ||
return false; | ||
|
||
// if this path doesn't have any more handlers, | ||
// then the monitoring is complete | ||
if(p->handlers.empty()) | ||
hash_remove(path); | ||
|
||
// we have successfully found the path and handler, | ||
// removed them, and done any clean up necessary | ||
return true; | ||
} | ||
|
||
|
||
bool dir_monitor::add_path(const path& path, const Handler& handler) | ||
{ | ||
try | ||
{ | ||
Path* p; | ||
p = hash.at(path); | ||
|
||
} | ||
catch(std::outofrange& e) | ||
{ | ||
p = new Path(path); | ||
if(!hash_insert(path, *p)) | ||
return false; | ||
} | ||
p->add_handler(handler); | ||
p->schedule(); | ||
return true; | ||
} | ||
|
||
bool dir_monitor::hash_insert(const path& path, const Path& dir) | ||
{ | ||
sp_lock.lock(); | ||
try{ | ||
|
||
if(hash.emplace(ent, ent).second) | ||
return true; | ||
else | ||
return false; | ||
} | ||
catch(std::exception& e) | ||
{ | ||
//std::cout << "error inserting " << path.string() | ||
// << " into the hash_table: "<< e.what()<<std::endl; | ||
return false; | ||
} | ||
} | ||
bool dir_monitor::hash_remove(const path& path) | ||
{ | ||
sp_lock.lock(); | ||
try | ||
{ | ||
if(hash.erase(path) > 0) | ||
return true; | ||
else | ||
return false; | ||
} | ||
catch(...)//this should probably be more specific | ||
{ | ||
//throw;//should this throw??? | ||
return false; | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
|
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,56 @@ | ||
#ifndef BOOST_AFIO_DIR_MONITOR_HPP | ||
#define BOOST_AFIO_DIR_MONITOR_HPP | ||
|
||
#include "afio.hpp" | ||
#include <unordered_map>//may need to move this after some Hash() declarations | ||
#include <vector> | ||
#include <memory> | ||
#include "boost/smart_ptr/detail/spinlock.hpp" | ||
#include "path.hpp" | ||
|
||
namespace boost{ | ||
namespace afio{ | ||
|
||
class dir_monitor | ||
{ | ||
typedef std::filesystem::path path; | ||
typedef std::function<void(dir_event)> Handler; | ||
public: | ||
//constructors | ||
dir_monitor(){} | ||
dir_monitor(std::shared_ptr<boost::afio::async_file_io_dispatcher_base> _dispatcher):dispatcher(_dispatcher){} | ||
|
||
//public functions | ||
/*! \brief Schedules the removal of a handler on an associated directory after the preceding operation | ||
\note This will also stop the monitoring of the directory if there are no associated handlers after removal. | ||
monitoring can begin again after adding a new handler. | ||
\return A future vector of directory entries with a boolean returning false if done. | ||
\param req A precondition op handle. If default constructed, the precondition is null. | ||
\exceptionmodelstd | ||
\qexample{enumerate_example} | ||
*/ | ||
std::pair< future< bool >, async_io_op > remove(const async_io_op & req, const path& path, const Handler& handler); | ||
std::pair< future< bool >, async_io_op > add(const async_io_op & req, const path& path, const Handler& handler); | ||
//change time interval??? | ||
|
||
private: | ||
|
||
//private data | ||
std::shared_ptr<boost::afio::async_io_dispatcher_base> dispatcher; | ||
recursive_mutex mtx;//consider a non-recursive mutex | ||
std::unordered_map<path, Path> hash; | ||
boost::detail::spinlock sp_lock; | ||
|
||
// private member functions | ||
bool remove_path(const path& path, const Handler& handler); | ||
bool add_path(const path& path, const Handler& handler); | ||
bool hash_insert(const path& path, const Path& dir); | ||
bool hash_remove(const path& path); | ||
}; | ||
}//namespace afio | ||
}//namespace boost | ||
#endif |
Oops, something went wrong.