Alexandria  2.19
Please provide a description of the project.
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 
19 #include "FilePool/FileManager.h"
20 #include "FilePool/FileHandler.h"
22 #include <boost/filesystem/operations.hpp>
23 
24 #if BOOST_VERSION < 106000
25 
29 boost::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 
56 namespace Euclid {
57 namespace FilePool {
58 
60  static auto default_manager = std::make_shared<LRUFileManager>();
61  return default_manager;
62 }
63 
65 
67 }
68 
70  // In principle a FileId should only be hold by a single thread, so no need to lock here
71  id->m_last_used = Clock::now();
72  ++id->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  fd->m_request_close();
88  }
89 }
90 
92  auto canonical = weakly_canonical(path);
93 
95  auto i = m_handlers.find(canonical);
96  std::shared_ptr<FileHandler> handler_ptr;
97 
98  if (i != m_handlers.end()) {
99  handler_ptr = i->second.lock();
100  }
101  // Either didn't exist or it is gone
102  if (!handler_ptr) {
104  handler_ptr = std::shared_ptr<FileHandler>(new FileHandler(canonical, this_weak), [this_weak, canonical](FileHandler* obj) {
105  {
106  auto this_shared = this_weak.lock();
107  if (this_shared) {
108  std::lock_guard<std::mutex> manager_lock(this_shared->m_mutex);
109  this_shared->m_handlers.erase(canonical);
110  }
111  }
112  delete obj;
113  });
114  m_handlers[canonical] = handler_ptr;
115  }
116  return handler_ptr;
117 }
118 
119 bool FileManager::hasHandler(const boost::filesystem::path& path) const {
121  auto canonical = weakly_canonical(path);
122  auto iter = m_handlers.find(canonical);
123  return iter != m_handlers.end();
124 }
125 
126 } // namespace FilePool
127 } // namespace Euclid
Euclid::FilePool::FileManager::FileManager
FileManager()
Constructor.
Definition: FileManager.cpp:64
Euclid::FilePool::FileManager::FileId
FileMetadata * FileId
Opaque FileId, its concrete type should only be assumed to be copyable and hashable.
Definition: FileManager.h:62
FileHandler.h
std::weak_ptr::lock
T lock(T... args)
std::shared_ptr
STL class.
Euclid::FilePool::FileHandler
Definition: FileHandler.h:39
std::pair
LRUFileManager.h
std::vector
STL class.
Euclid::FilePool::FileManager::~FileManager
virtual ~FileManager()
Destructor.
Definition: FileManager.cpp:66
Euclid::FilePool::FileManager::hasHandler
bool hasHandler(const boost::filesystem::path &path) const
Definition: FileManager.cpp:119
std::back_inserter
T back_inserter(T... args)
std::lock_guard
STL class.
std::enable_shared_from_this< FileManager >::shared_from_this
T shared_from_this(T... args)
std::unique_lock
STL class.
Euclid::FilePool::FileManager::closeAll
void closeAll()
Definition: FileManager.cpp:75
std::transform
T transform(T... args)
std::weak_ptr
STL class.
Euclid::FilePool::FileManager::m_mutex
std::mutex m_mutex
Definition: FileManager.h:158
Euclid::FilePool::FileManager::getFileHandler
std::shared_ptr< FileHandler > getFileHandler(const boost::filesystem::path &path)
Definition: FileManager.cpp:91
std::map::begin
T begin(T... args)
Euclid::FilePool::FileManager::getDefault
static std::shared_ptr< FileManager > getDefault()
Definition: FileManager.cpp:59
std::map::end
T end(T... args)
path
Elements::Path::Item path
weakly_canonical
boost::filesystem::path weakly_canonical(const boost::filesystem::path &path)
Definition: FileManager.cpp:29
Euclid::FilePool::FileManager::m_files
std::map< FileId, std::unique_ptr< FileMetadata > > m_files
Definition: FileManager.h:172
Euclid::FilePool::FileManager::m_handlers
std::map< boost::filesystem::path, std::weak_ptr< FileHandler > > m_handlers
Definition: FileManager.h:167
FileManager.h
std::unique_ptr< FileMetadata >
Euclid
Definition: InstOrRefHolder.h:29
Euclid::FilePool::FileManager::notifyUsed
virtual void notifyUsed(FileId id)
Definition: FileManager.cpp:69
std::chrono::steady_clock::now
T now(T... args)