Directory: | cvmfs/ |
---|---|
File: | cvmfs/fd_refcount_mgr.cc |
Date: | 2024-04-21 02:33:16 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 13 | 75 | 17.3% |
Branches: | 5 | 76 | 6.6% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | */ | ||
4 | |||
5 | #include <fcntl.h> | ||
6 | #include <unistd.h> | ||
7 | |||
8 | #include <cassert> | ||
9 | #include <string> | ||
10 | |||
11 | #include "fd_refcount_mgr.h" | ||
12 | #include "util/mutex.h" | ||
13 | #include "util/smalloc.h" | ||
14 | |||
15 | |||
16 | ✗ | int FdRefcountMgr::Open(const shash::Any id, const std::string& path) { | |
17 | ✗ | int result = -1; | |
18 | ✗ | MutexLockGuard lock_guard(lock_cache_refcount_); | |
19 | ✗ | if (!map_fd_.Lookup(id, &result)) { | |
20 | ✗ | result = open(path.c_str(), O_RDONLY); | |
21 | ✗ | if (result >= 0) { | |
22 | ✗ | map_fd_.Insert(id, result); | |
23 | } | ||
24 | } | ||
25 | ✗ | if (result >= 0) { | |
26 | ✗ | FdRefcountInfo refc_info; | |
27 | ✗ | if (map_refcount_.Lookup(result, &refc_info)) { | |
28 | ✗ | refc_info.refcount++; | |
29 | } else { | ||
30 | ✗ | refc_info.refcount = 1; | |
31 | ✗ | refc_info.id = id; | |
32 | } | ||
33 | ✗ | map_refcount_.Insert(result, refc_info); | |
34 | } | ||
35 | ✗ | return result; | |
36 | } | ||
37 | |||
38 | ✗ | int FdRefcountMgr::Close(int fd) { | |
39 | ✗ | int retval = -1; | |
40 | ✗ | MutexLockGuard lock_guard(lock_cache_refcount_); | |
41 | ✗ | FdRefcountInfo refc_info; | |
42 | ✗ | if (map_refcount_.Lookup(fd, &refc_info)) { | |
43 | ✗ | if (refc_info.refcount > 1) { | |
44 | ✗ | refc_info.refcount -= 1; | |
45 | ✗ | map_refcount_.Insert(fd, refc_info); | |
46 | ✗ | retval = 0; | |
47 | } else { | ||
48 | ✗ | retval = close(fd); | |
49 | ✗ | map_fd_.Erase(refc_info.id); | |
50 | ✗ | map_refcount_.Erase(fd); | |
51 | } | ||
52 | } else { | ||
53 | // fd not present in our table - this should only happen | ||
54 | // when reloading from the normal posix cache manager! | ||
55 | ✗ | LogCvmfs(kLogCache, kLogDebug, | |
56 | "WARNING: trying to close fd that " | ||
57 | " is not in refcount tables"); | ||
58 | ✗ | retval = close(fd); | |
59 | } | ||
60 | ✗ | return retval; | |
61 | } | ||
62 | |||
63 | ✗ | int FdRefcountMgr::Dup(int fd) { | |
64 | ✗ | int retval = -1; | |
65 | ✗ | MutexLockGuard lock_guard(lock_cache_refcount_); | |
66 | ✗ | FdRefcountInfo refc_info; | |
67 | ✗ | if (map_refcount_.Lookup(fd, &refc_info)) { | |
68 | ✗ | refc_info.refcount += 1; | |
69 | ✗ | map_refcount_.Insert(fd, refc_info); | |
70 | ✗ | retval = fd; | |
71 | } else { | ||
72 | // fd not present in our table - this should | ||
73 | // not happen in the current usage of Dup | ||
74 | ✗ | LogCvmfs(kLogCache, kLogDebug, | |
75 | "WARNING: trying to dup fd that " | ||
76 | " is not in refcount tables"); | ||
77 | ✗ | retval = dup(fd); | |
78 | } | ||
79 | ✗ | return retval; | |
80 | } | ||
81 | |||
82 | ✗ | FdRefcountMgr* FdRefcountMgr::Clone() { | |
83 | ✗ | FdRefcountMgr* clone = new FdRefcountMgr(map_refcount_, map_fd_); | |
84 | ✗ | return clone; | |
85 | } | ||
86 | |||
87 | ✗ | SmallHashDynamic<shash::Any, int> * FdRefcountMgr::GetFdMapPtr() { | |
88 | ✗ | return &map_fd_; | |
89 | } | ||
90 | |||
91 | SmallHashDynamic<int, FdRefcountMgr::FdRefcountInfo>* | ||
92 | ✗ | FdRefcountMgr::GetRefcountMapPtr() { | |
93 | ✗ | return &map_refcount_; | |
94 | } | ||
95 | |||
96 | ✗ | void FdRefcountMgr::AssignFrom(FdRefcountMgr* other) { | |
97 | ✗ | map_fd_ = *other->GetFdMapPtr(); | |
98 | ✗ | map_refcount_ = *other->GetRefcountMapPtr(); | |
99 | } | ||
100 | |||
101 | 167 | FdRefcountMgr::~FdRefcountMgr() { | |
102 | 167 | pthread_mutex_destroy(lock_cache_refcount_); | |
103 | 167 | free(lock_cache_refcount_); | |
104 | 167 | } | |
105 | |||
106 |
1/2✓ Branch 2 taken 169 times.
✗ Branch 3 not taken.
|
169 | FdRefcountMgr::FdRefcountMgr() { |
107 |
1/2✓ Branch 1 taken 169 times.
✗ Branch 2 not taken.
|
169 | const shash::Any hash_null; |
108 |
1/2✓ Branch 1 taken 169 times.
✗ Branch 2 not taken.
|
169 | map_fd_.Init(16, hash_null, hasher_any); |
109 |
1/2✓ Branch 1 taken 169 times.
✗ Branch 2 not taken.
|
169 | map_refcount_.Init(16, -1, hasher_int); |
110 | 169 | lock_cache_refcount_ = | |
111 | 169 | reinterpret_cast<pthread_mutex_t*>(smalloc(sizeof(pthread_mutex_t))); | |
112 | 169 | int retval = pthread_mutex_init(lock_cache_refcount_, NULL); | |
113 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 169 times.
|
169 | assert(retval == 0); |
114 | 169 | } | |
115 | |||
116 | ✗ | FdRefcountMgr::FdRefcountMgr( | |
117 | const SmallHashDynamic<int, FdRefcountMgr::FdRefcountInfo> &map_refcount, | ||
118 | ✗ | const SmallHashDynamic<shash::Any, int> &map_fd) | |
119 | { | ||
120 | ✗ | const shash::Any hash_null; | |
121 | ✗ | map_fd_.Init(16, hash_null, hasher_any); | |
122 | ✗ | map_refcount_.Init(16, -1, hasher_int); | |
123 | ✗ | map_refcount_ = map_refcount; | |
124 | ✗ | map_fd_ = map_fd; | |
125 | ✗ | lock_cache_refcount_ = | |
126 | ✗ | reinterpret_cast<pthread_mutex_t*>(smalloc(sizeof(pthread_mutex_t))); | |
127 | ✗ | int retval = pthread_mutex_init(lock_cache_refcount_, NULL); | |
128 | ✗ | assert(retval == 0); | |
129 | } | ||
130 |