Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
FileManager.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-2021 Euclid Science Ground Segment
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the Free
6 * Software Foundation; either version 3.0 of the License, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
22#include <boost/filesystem/operations.hpp>
23
24#if BOOST_VERSION < 106000
29boost::filesystem::path weakly_canonical(const boost::filesystem::path& path) {
30 auto iter = path.end();
31 boost::filesystem::path head = path;
32
33 for (; !head.empty(); --iter) {
34 if (boost::filesystem::exists(head)) {
35 break;
36 }
37 head.remove_filename();
38 }
39
40 if (head.empty())
41 return boost::filesystem::absolute(path);
42 head = boost::filesystem::canonical(head);
43
44 boost::filesystem::path tail;
45 for (; iter != path.end(); ++iter) {
46 tail /= *iter;
47 }
48
49 if (tail.empty())
50 return head;
51
52 return boost::filesystem::absolute(head / tail);
53}
54#endif
55
56namespace Euclid {
57namespace FilePool {
58
60 static auto default_manager = std::make_shared<LRUFileManager>();
61 return default_manager;
62}
63
65
67
69 // In principle a FileId should only be hold by a single thread, so no need to lock here
70 FileMetadata* f_ptr = reinterpret_cast<FileMetadata*>(id);
71 f_ptr->m_last_used = Clock::now();
72 ++f_ptr->m_used_count;
73}
74
76 std::vector<FileMetadata*> to_be_closed;
77
78 // To avoid deadlocks on the callback, we get the pointers first
79 {
82 [](std::pair<FileId const, std::unique_ptr<FileMetadata>>& entry) { return entry.second.get(); });
83 }
84
85 // And request the closing after
86 for (auto& fd : to_be_closed) {
87 auto req_close_copy = fd->m_request_close;
88 // In case m_request_close is a lambda, which would get freed during the call
89 req_close_copy();
90 }
91}
92
93std::shared_ptr<FileHandler> FileManager::getFileHandler(const boost::filesystem::path& path) {
94 auto canonical = weakly_canonical(path);
95
97 auto i = m_handlers.find(canonical);
99
100 if (i != m_handlers.end()) {
101 handler_ptr = i->second.lock();
102 }
103 // Either didn't exist or it is gone
104 if (!handler_ptr) {
106 auto handler_destroy = [this_weak, canonical](FileHandler* obj) {
107 auto this_shared = this_weak.lock();
108 if (this_shared) {
109 std::lock_guard<std::mutex> manager_lock(this_shared->m_mutex);
110 this_shared->m_handlers.erase(canonical);
111 }
112 delete obj;
113 };
114 handler_ptr = std::shared_ptr<FileHandler>(new FileHandler(canonical, this_weak), handler_destroy);
115 m_handlers[canonical] = handler_ptr;
116 }
117 return handler_ptr;
118}
119
120bool FileManager::hasHandler(const boost::filesystem::path& path) const {
122 auto canonical = weakly_canonical(path);
123 auto iter = m_handlers.find(canonical);
124 return iter != m_handlers.end();
125}
126
127} // namespace FilePool
128} // namespace Euclid
boost::filesystem::path weakly_canonical(const boost::filesystem::path &path)
T back_inserter(T... args)
T begin(T... args)
virtual ~FileManager()
Destructor.
intptr_t FileId
Opaque FileId, its concrete type should only be assumed to be copyable and hashable.
Definition FileManager.h:65
std::map< boost::filesystem::path, std::weak_ptr< FileHandler > > m_handlers
static std::shared_ptr< FileManager > getDefault()
virtual void notifyUsed(FileId id)
std::map< FileId, std::unique_ptr< FileMetadata > > m_files
std::shared_ptr< FileHandler > getFileHandler(const boost::filesystem::path &path)
bool hasHandler(const boost::filesystem::path &path) const
T end(T... args)
T lock(T... args)
T transform(T... args)