Alexandria  2.27.0
SDC-CH common library for the Euclid project
FileManager.icpp
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 #ifndef FILEMANAGER_IMPL
20 #error "This file should not be included directly! Use FileManager.h instead"
21 #else
22 #include "AlexandriaKernel/memory_tools.h"
23 #include "FilePool/FileHandler.h"
24 #include <atomic>
25 #include <boost/filesystem/operations.hpp>
26 
27 namespace Euclid {
28 namespace FilePool {
29 
30 struct FileManager::FileMetadata {
31  boost::filesystem::path m_path;
32  bool m_write;
33  Timestamp m_last_used;
34  uint64_t m_used_count;
35  std::function<bool(void)> m_request_close;
36 
37  FileMetadata(const boost::filesystem::path& path, bool write)
38  : m_path(path), m_write(write), m_last_used(Clock::now()), m_used_count(0) {}
39 };
40 
41 template <typename TFD>
42 auto FileManager::open(const boost::filesystem::path& path, bool write, std::function<bool(FileId)> request_close)
43  -> std::pair<FileId, TFD> {
44  notifyIntentToOpen(write);
45 
46  auto meta = Euclid::make_unique<FileMetadata>(path, write);
47  FileId id = reinterpret_cast<FileId>(meta.get());
48  meta->m_request_close = [id, request_close]() -> bool { return request_close(id); };
49 
50  TFD fd = OpenCloseTrait<TFD>::open(path, write);
51 
52  {
53  std::lock_guard<std::mutex> lock(m_mutex);
54  m_files[id] = std::move(meta);
55  }
56 
57  notifyOpenedFile(id);
58  return std::make_pair(id, std::move(fd));
59 }
60 
61 template <typename TFD>
62 void FileManager::close(FileId id, TFD& fd) {
63  OpenCloseTrait<TFD>::close(fd);
64 
65  notifyClosedFile(id);
66 
67  std::lock_guard<std::mutex> lock(m_mutex);
68  auto iter = m_files.find(id);
69  assert(iter != m_files.end());
70  m_files.erase(iter);
71 }
72 
73 } // namespace FilePool
74 } // namespace Euclid
75 
76 #endif