Alexandria  2.27.0
SDC-CH common library for the Euclid 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
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 
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 
94  auto canonical = weakly_canonical(path);
95 
97  auto i = m_handlers.find(canonical);
98  std::shared_ptr<FileHandler> handler_ptr;
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 
120 bool 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)
Definition: FileManager.cpp:29
T back_inserter(T... args)
T begin(T... args)
virtual ~FileManager()
Destructor.
Definition: FileManager.cpp:66
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
Definition: FileManager.h:171
static std::shared_ptr< FileManager > getDefault()
Definition: FileManager.cpp:59
virtual void notifyUsed(FileId id)
Definition: FileManager.cpp:68
std::map< FileId, std::unique_ptr< FileMetadata > > m_files
Definition: FileManager.h:176
std::shared_ptr< FileHandler > getFileHandler(const boost::filesystem::path &path)
Definition: FileManager.cpp:93
bool hasHandler(const boost::filesystem::path &path) const
T end(T... args)
T lock(T... args)
Path::Item path
T transform(T... args)